From 50526d8a6a586cbc547a880f0489cd30f551faef Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 18 Aug 2020 00:51:38 +0200 Subject: [PATCH 001/176] initial commit Signed-off-by: Bernd (cherry picked from commit ccc2b2ca32b7981b0a4a056dd80dbb7beeb23ac2) Signed-off-by: Bernd --- CODEOWNERS | 1 + .../.classpath | 32 ++++ .../.project | 23 +++ .../NOTICE | 13 ++ .../README.md | 56 +++++++ .../pom.xml | 17 ++ .../src/main/feature/feature.xml | 9 + .../BMWConnectedDriveBindingConstants.java | 34 ++++ .../BMWConnectedDriveHandlerFactory.java | 66 ++++++++ .../internal/ConnectedCarConfiguration.java | 49 ++++++ .../internal/dto/CarData.java | 26 +++ .../internal/handler/BimmerConstants.java | 47 ++++++ .../internal/handler/ConnectedCarHandler.java | 105 ++++++++++++ .../handler/ConnectedDrivePortalHandler.java | 155 ++++++++++++++++++ .../internal/handler/HTTPConstants.java | 39 +++++ .../internal/handler/Token.java | 47 ++++++ .../resources/ESH-INF/binding/binding.xml | 10 ++ .../i18n/bmwconnecteddrive_be.properties | 17 ++ .../ESH-INF/thing/thing-connected-car.xml | 54 ++++++ .../internal/handler/AuthTest.java | 135 +++++++++++++++ .../test.json | 107 ++++++++++++ bundles/pom.xml | 1 + 22 files changed, 1043 insertions(+) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/.classpath create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/.project create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/NOTICE create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/README.md create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/pom.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/feature/feature.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/BMWConnectedDriveBindingConstants.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/BMWConnectedDriveHandlerFactory.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CarData.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BimmerConstants.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDrivePortalHandler.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/HTTPConstants.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/binding/binding.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_be.properties create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-connected-car.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/test.json diff --git a/CODEOWNERS b/CODEOWNERS index 122c664046cb4..0f7b8512b56b4 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -35,6 +35,7 @@ /bundles/org.openhab.binding.bluetooth.govee/ @cpmeister /bundles/org.openhab.binding.bluetooth.roaming/ @cpmeister /bundles/org.openhab.binding.bluetooth.ruuvitag/ @ssalonen +/bundles/org.openhab.binding.bmwconnecteddrive/ @weymann /bundles/org.openhab.binding.boschindego/ @jofleck /bundles/org.openhab.binding.boschshc/ @stefan-kaestle @coeing @GerdZanker /bundles/org.openhab.binding.bosesoundtouch/ @marvkis @tratho diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/.classpath b/bundles/org.openhab.binding.bmwconnecteddrive/.classpath new file mode 100644 index 0000000000000..a5d95095ccaaf --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/.classpath @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/.project b/bundles/org.openhab.binding.bmwconnecteddrive/.project new file mode 100644 index 0000000000000..fe8d304ee802e --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/.project @@ -0,0 +1,23 @@ + + + org.openhab.binding.bmwconnecteddrive + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/NOTICE b/bundles/org.openhab.binding.bmwconnecteddrive/NOTICE new file mode 100644 index 0000000000000..38d625e349232 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/NOTICE @@ -0,0 +1,13 @@ +This content is produced and maintained by the openHAB project. + +* Project home: https://www.openhab.org + +== Declared Project Licenses + +This program and the accompanying materials are made available under the terms +of the Eclipse Public License 2.0 which is available at +https://www.eclipse.org/legal/epl-2.0/. + +== Source Code + +https://github.com/openhab/openhab-addons diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md new file mode 100644 index 0000000000000..af3c37315896b --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -0,0 +1,56 @@ +# BMWConnectedDrive Binding + +_Give some details about what this binding is meant for - a protocol, system, specific device._ + +_If possible, provide some resources like pictures, a YouTube video, etc. to give an impression of what can be done with this binding. You can place such resources into a `doc` folder next to this README.md._ + +## Supported Things + +_Please describe the different supported things / devices within this section._ +_Which different types are supported, which models were tested etc.?_ +_Note that it is planned to generate some part of this based on the XML files within ```src/main/resources/ESH-INF/thing``` of your binding._ + +## Discovery + +_Describe the available auto-discovery features here. Mention for what it works and what needs to be kept in mind when using it._ + +## Binding Configuration + +_If your binding requires or supports general configuration settings, please create a folder ```cfg``` and place the configuration file ```.cfg``` inside it. In this section, you should link to this file and provide some information about the options. The file could e.g. look like:_ + +``` +# Configuration for the Philips Hue Binding +# +# Default secret key for the pairing of the Philips Hue Bridge. +# It has to be between 10-40 (alphanumeric) characters +# This may be changed by the user for security reasons. +secret=openHABSecret +``` + +_Note that it is planned to generate some part of this based on the information that is available within ```src/main/resources/ESH-INF/binding``` of your binding._ + +_If your binding does not offer any generic configurations, you can remove this section completely._ + +## Thing Configuration + +_Describe what is needed to manually configure a thing, either through the (Paper) UI or via a thing-file. This should be mainly about its mandatory and optional configuration parameters. A short example entry for a thing file can help!_ + +_Note that it is planned to generate some part of this based on the XML files within ```src/main/resources/ESH-INF/thing``` of your binding._ + +## Channels + +_Here you should provide information about available channel types, what their meaning is and how they can be used._ + +_Note that it is planned to generate some part of this based on the XML files within ```src/main/resources/ESH-INF/thing``` of your binding._ + +| channel | type | description | +|----------|--------|------------------------------| +| control | Switch | This is the control channel | + +## Full Example + +_Provide a full usage example based on textual configuration files (*.things, *.items, *.sitemap)._ + +## Any custom content here! + +_Feel free to add additional sections for whatever you think should also be mentioned about your binding!_ diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/pom.xml b/bundles/org.openhab.binding.bmwconnecteddrive/pom.xml new file mode 100644 index 0000000000000..d56f328559044 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/pom.xml @@ -0,0 +1,17 @@ + + + + 4.0.0 + + + org.openhab.addons.bundles + org.openhab.addons.reactor.bundles + 2.5.8-SNAPSHOT + + + org.openhab.binding.bmwconnecteddrive + + openHAB Add-ons :: Bundles :: BMWConnectedDrive Binding + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/feature/feature.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/feature/feature.xml new file mode 100644 index 0000000000000..eecb5293a69b2 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/feature/feature.xml @@ -0,0 +1,9 @@ + + + mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features + + + openhab-runtime-base + mvn:org.openhab.addons.bundles/org.openhab.binding.bmwconnecteddrive/${project.version} + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/BMWConnectedDriveBindingConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/BMWConnectedDriveBindingConstants.java new file mode 100644 index 0000000000000..8dda706b41002 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/BMWConnectedDriveBindingConstants.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.smarthome.core.thing.ThingTypeUID; + +/** + * The {@link BMWConnectedDriveBindingConstants} class defines common constants, which are + * used across the whole binding. + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class BMWConnectedDriveBindingConstants { + + private static final String BINDING_ID = "bmwconnecteddrive"; + + // List of all Thing Type UIDs + public static final ThingTypeUID THING_TYPE_CONNECTED_CAR = new ThingTypeUID(BINDING_ID, "connected-car"); + + // List of all Channel ids + public static final String CHANNEL_1 = "channel1"; +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/BMWConnectedDriveHandlerFactory.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/BMWConnectedDriveHandlerFactory.java new file mode 100644 index 0000000000000..19c5bf79aff9f --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/BMWConnectedDriveHandlerFactory.java @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal; + +import static org.openhab.binding.bmwconnecteddrive.internal.BMWConnectedDriveBindingConstants.THING_TYPE_CONNECTED_CAR; + +import java.util.Collections; +import java.util.Set; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.thing.Thing; +import org.eclipse.smarthome.core.thing.ThingTypeUID; +import org.eclipse.smarthome.core.thing.binding.BaseThingHandlerFactory; +import org.eclipse.smarthome.core.thing.binding.ThingHandler; +import org.eclipse.smarthome.core.thing.binding.ThingHandlerFactory; +import org.eclipse.smarthome.io.net.http.HttpClientFactory; +import org.openhab.binding.bmwconnecteddrive.internal.handler.ConnectedCarHandler; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +/** + * The {@link BMWConnectedDriveHandlerFactory} is responsible for creating things and thing + * handlers. + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +@Component(configurationPid = "binding.bmwconnecteddrive", service = ThingHandlerFactory.class) +public class BMWConnectedDriveHandlerFactory extends BaseThingHandlerFactory { + + private static final Set SUPPORTED_THING_TYPES_UIDS = Collections.singleton(THING_TYPE_CONNECTED_CAR); + private final HttpClientFactory httpClientFactory; + + @Activate + public BMWConnectedDriveHandlerFactory(final @Reference HttpClientFactory hcf) { + httpClientFactory = hcf; + } + + @Override + public boolean supportsThingType(ThingTypeUID thingTypeUID) { + return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID); + } + + @Override + protected @Nullable ThingHandler createHandler(Thing thing) { + ThingTypeUID thingTypeUID = thing.getThingTypeUID(); + + if (THING_TYPE_CONNECTED_CAR.equals(thingTypeUID)) { + return new ConnectedCarHandler(thing, httpClientFactory.getCommonHttpClient()); + } + + return null; + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java new file mode 100644 index 0000000000000..a9237d67064ed --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link ConnectedCarConfiguration} class contains fields mapping thing configuration parameters. + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class ConnectedCarConfiguration { + + /** + * Depending on the location the correct server needs to be called + */ + public String region = ""; + + /** + * BMW Connected Drive Username + */ + public String userName = ""; + + /** + * BMW Connected Drive Password + */ + public String password = ""; + + /** + * Vehilce Identification Number (VIN) + */ + public String vin = ""; + + /** + * Data refresh rate in minutes + */ + public int refreshInterval = 15; +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CarData.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CarData.java new file mode 100644 index 0000000000000..e0ff1e8fde68e --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CarData.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedCarConfiguration; + +/** + * The {@link ConnectedCarConfiguration} class contains fields mapping thing configuration parameters. + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class CarData { + +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BimmerConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BimmerConstants.java new file mode 100644 index 0000000000000..c923c1b7cd2ba --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BimmerConstants.java @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link BimmerConstants} This class holds the important constants for the BMW Connected Drive Authorization. They + * are taken from the Bimmercode from github {@link https://github.com/bimmerconnected/bimmer_connected} + * File defining these constants + * {@link https://github.com/bimmerconnected/bimmer_connected/blob/master/bimmer_connected/account.py} + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class BimmerConstants { + + public final static String SERVER_NORTH_AMERICA = "b2vapi.bmwgroup.us"; + public final static String SERVER_CHINA = "b2vapi.bmwgroup.cn:859"; + public final static String SERVER_ROW = "b2vapi.bmwgroup.com"; + public final static Map SERVER_MAP = new HashMap() { + { + put("NORTH_AMERICA", SERVER_NORTH_AMERICA); + put("CHINA", SERVER_CHINA); + put("ROW", SERVER_ROW); + } + }; + + public final static String AUTHORIZATION_VALUE = "Basic blF2NkNxdHhKdVhXUDc0eGYzQ0p3VUVQOjF6REh4NnVuNGNEanliTEVOTjNreWZ1bVgya0VZaWdXUGNRcGR2RFJwSUJrN3JPSg=="; + public final static String CREDENTIAL_VALUES = "nQv6CqtxJuXWP74xf3CJwUEP:1zDHx6un4cDjybLENN3kyfumX2kEYigWPcQpdvDRpIBk7rOJ"; + public final static String CLIENT_ID_VALUE = "dbf0a542-ebd1-4ff0-a9a7-55172fbfce35"; + public final static String REDIRECT_URI_VALUE = "https://www.bmw-connecteddrive.com/app/static/external-dispatch.html"; + public final static String SCOPE_VALUES = "authenticate_user vehicle_data remote_services"; +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java new file mode 100644 index 0000000000000..5bcb8c66ddfa8 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import static org.openhab.binding.bmwconnecteddrive.internal.BMWConnectedDriveBindingConstants.CHANNEL_1; + +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.smarthome.core.thing.ChannelUID; +import org.eclipse.smarthome.core.thing.Thing; +import org.eclipse.smarthome.core.thing.ThingStatus; +import org.eclipse.smarthome.core.thing.ThingStatusDetail; +import org.eclipse.smarthome.core.thing.binding.BaseThingHandler; +import org.eclipse.smarthome.core.types.Command; +import org.eclipse.smarthome.core.types.RefreshType; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedCarConfiguration; +import org.openhab.binding.bmwconnecteddrive.internal.dto.CarData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link ConnectedCarHandler} is responsible for handling commands, which are + * sent to one of the channels. + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class ConnectedCarHandler extends BaseThingHandler { + private final Logger logger = LoggerFactory.getLogger(ConnectedCarHandler.class); + + private final ConnectedDrivePortalHandler cdpHandler; + protected @Nullable ScheduledFuture refreshJob; + + public ConnectedCarHandler(Thing thing, HttpClient hc) { + super(thing); + cdpHandler = new ConnectedDrivePortalHandler(hc); + } + + @Override + public void handleCommand(ChannelUID channelUID, Command command) { + if (CHANNEL_1.equals(channelUID.getId())) { + if (command instanceof RefreshType) { + // TODO: handle data refresh + } + + // TODO: handle command + + // Note: if communication with thing fails for some reason, + // indicate that by setting the status with detail information: + // updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, + // "Could not control device at IP address x.x.x.x"); + } + } + + @Override + public void initialize() { + updateStatus(ThingStatus.UNKNOWN); + ConnectedCarConfiguration config = getConfigAs(ConnectedCarConfiguration.class); + if (config != null) { + scheduler.execute(() -> { + cdpHandler.initialize(config); + startSchedule(config.refreshInterval); + }); + } else { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR); + } + } + + private void startSchedule(int interval) { + ScheduledFuture localRefreshJob = refreshJob; + if (localRefreshJob != null) { + if (localRefreshJob.isCancelled()) { + refreshJob = scheduler.scheduleWithFixedDelay(this::dataUpdate, 0, interval, TimeUnit.MINUTES); + } // else - scheduler is already running! + } else { + refreshJob = scheduler.scheduleWithFixedDelay(this::dataUpdate, 0, interval, TimeUnit.MINUTES); + } + } + + protected void dataUpdate() { + CarData carData = cdpHandler.getData(); + } + + @Override + public void dispose() { + ScheduledFuture localRefreshJob = refreshJob; + if (localRefreshJob != null) { + localRefreshJob.cancel(true); + } + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDrivePortalHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDrivePortalHandler.java new file mode 100644 index 0000000000000..d2bbcf8892a08 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDrivePortalHandler.java @@ -0,0 +1,155 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import static org.openhab.binding.bmwconnecteddrive.internal.handler.HTTPConstants.*; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +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.client.util.StringContentProvider; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.util.MultiMap; +import org.eclipse.jetty.util.UrlEncoded; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedCarConfiguration; +import org.openhab.binding.bmwconnecteddrive.internal.dto.CarData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link ConnectedDrivePortalHandler} Deals with the Authorization & Communication for one specific Car and the BMW + * Connected Drive Portal + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class ConnectedDrivePortalHandler { + private final Logger logger = LoggerFactory.getLogger(ConnectedDrivePortalHandler.class); + private final HttpClient httpClient; + private final Token token = new Token(); + private @Nullable ConnectedCarConfiguration configuration; + private @Nullable String vehicleAPI; + + public ConnectedDrivePortalHandler(HttpClient hc) { + httpClient = hc; + httpClient.setFollowRedirects(false); + } + + public void initialize(ConnectedCarConfiguration config) { + configuration = config; + vehicleAPI = "https://" + BimmerConstants.SERVER_MAP.get(configuration.region) + + "/api/vehicle/dynamic/v1/" + configuration.vin + "?offset=-60"; + logger.info("Vehicle API set to {}", vehicleAPI); + + // r = requests.get(self.vehicleApi+'/dynamic/v1/'+self.bmwVin+'?offset=-60', + // headers=headers,allow_redirects=True) + } + + /** + * Authorize at BMW Connected Drive Portal and re + * + * @return + */ + void auth() { + String uri = "https://customer.bmwgroup.com/gcdm/oauth/authenticate"; + Request req = httpClient.POST(uri); + + req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); + req.header(HttpHeader.CONNECTION, KEEP_ALIVE); + req.header(HttpHeader.HOST, BimmerConstants.SERVER_MAP.get(configuration.region)); + req.header(HttpHeader.AUTHORIZATION, BimmerConstants.AUTHORIZATION_VALUE); + req.header(CREDENTIALS, BimmerConstants.CREDENTIAL_VALUES); + + MultiMap map = new MultiMap(); + map.add(CLIENT_ID, BimmerConstants.CLIENT_ID_VALUE); + map.add(RESPONSE_TYPE, TOKEN); + map.add(REDIRECT_URI, BimmerConstants.REDIRECT_URI_VALUE); + map.add(SCOPE, BimmerConstants.SCOPE_VALUES); + map.add(USERNAME, configuration.userName); + map.add(PASSWORD, configuration.password); + String urlEncodedData = UrlEncoded.encode(map, Charset.defaultCharset(), false); + + logger.info("URL encoded data {}", urlEncodedData); + logger.info("Data size {} ", urlEncodedData.length()); + req.header("Content-Length", urlEncodedData.length() + ""); + req.content(new StringContentProvider(urlEncodedData)); + try { + ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); + logger.info("Status {} ", contentResponse.getStatus()); + logger.info("Reason {} ", contentResponse.getReason()); + logger.info("Encoding {} ", contentResponse.getEncoding()); + logger.info("Content length {} ", contentResponse.getContent().length); + logger.info("Media Type {} ", contentResponse.getMediaType()); + HttpFields fields = contentResponse.getHeaders(); + HttpField field = fields.getField(HttpHeader.LOCATION); + storeToken(field.getValue(), token); + // + // for (int i = 0; i < fields.size(); i++) { + // HttpField field = fields.getField(i); + // logger.info("Field {}, Name {}, Value {}", i, field.getName(), field.getValue()); + // } + // String content = contentResponse.getContentAsString(); + // logger.info("Auth response: {}", content); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + logger.warn("Auth Exception: {}", e.getMessage()); + } + } + + public void storeToken(String urlEncoded, Token t) { + MultiMap map = new MultiMap(); + UrlEncoded.decodeTo(urlEncoded, map, StandardCharsets.US_ASCII); + map.forEach((key, value) -> { + logger.info("Key {} Value {}", key, value); + if (key.endsWith(ACCESS_TOKEN)) { + t.setToken(value.get(0).toString()); + } else if (key.equals(EXPIRES_IN)) { + logger.info("Expires {}", value.get(0).toString()); + t.setExpiration(Integer.parseInt(value.get(0).toString())); + } else if (key.equals(TOKEN_TYPE)) { + t.setType(value.get(0).toString()); + } + }); + } + + public @Nullable CarData getData() { + if (token.isExpired()) { + auth(); + if (token.isExpired()) { + return null; + } + } + Request req = httpClient.newRequest(vehicleAPI); + + req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); + req.header(HttpHeader.AUTHORIZATION, token.getToken()); + try { + ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); + logger.info("Status {}", contentResponse.getStatus()); + logger.info("Reason {}", contentResponse.getReason()); + logger.info("Reason {}", contentResponse.getContentAsString()); + } catch (InterruptedException | TimeoutException | ExecutionException e) { + logger.warn("Get Data Exception {}", e.getMessage()); + } + return null; + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/HTTPConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/HTTPConstants.java new file mode 100644 index 0000000000000..842d06c718ca7 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/HTTPConstants.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link HTTPConstants} class contains fields mapping thing configuration parameters. + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class HTTPConstants { + public final static String CONTENT_TYPE_URL_ENCODED = "application/x-www-form-urlencoded"; + public final static String CONTENT_TYPE_JSON = "application/json"; + public final static String KEEP_ALIVE = "Keep-Alive"; + public final static String CLIENT_ID = "client_id"; + public final static String RESPONSE_TYPE = "response_type"; + public final static String TOKEN = "token"; + public final static String REDIRECT_URI = "redirect_uri"; + public final static String SCOPE = "scope"; + public final static String CREDENTIALS = "Credentials"; + public final static String USERNAME = "username"; + public final static String PASSWORD = "password"; + + public final static String ACCESS_TOKEN = "access_token"; + public final static String TOKEN_TYPE = "token_type"; + public final static String EXPIRES_IN = "expires_in"; +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java new file mode 100644 index 0000000000000..1706b7cf8785e --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link Token} class contains fields mapping thing configuration parameters. + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class Token { + private String token = ""; + private String tokenType = ""; + private long expiration = 0; + + public String getToken() { + return tokenType + " " + token; + } + + public void setToken(String token) { + this.token = token; + } + + public void setExpiration(int expiration) { + this.expiration = System.currentTimeMillis() / 1000 + expiration; + } + + public boolean isExpired() { + return (expiration - System.currentTimeMillis() / 1000) < 2; + } + + public void setType(String type) { + tokenType = type; + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/binding/binding.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/binding/binding.xml new file mode 100644 index 0000000000000..a46634ca63664 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/binding/binding.xml @@ -0,0 +1,10 @@ + + + + BMW Connected Car + Provides access to your Car via BMW Connected Drive Portal + Bernd Weymann + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_be.properties b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_be.properties new file mode 100644 index 0000000000000..7bd1569f77d77 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_be.properties @@ -0,0 +1,17 @@ +# FIXME: please substitute the xx_XX with a proper locale, ie. de_DE +# FIXME: please do not add the file to the repo if you add or change no content +# binding +binding.bmwconnecteddrive.name = +binding.bmwconnecteddrive.description = + +# thing types +thing-type.bmwconnecteddrive.sample.label = +thing-type.bmwconnecteddrive.sample.description = + +# thing type config description +thing-type.config.bmwconnecteddrive.sample.config1.label = +thing-type.config.bmwconnecteddrive.sample.config1.description = + +# channel types +channel-type.bmwconnecteddrive.sample-channel.label = +channel-type.bmwconnecteddrive.sample-channel.description = diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-connected-car.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-connected-car.xml new file mode 100644 index 0000000000000..f1c99b8d0f0e0 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-connected-car.xml @@ -0,0 +1,54 @@ + + + + + + + Car associated with the BMW Connected Drive Portal + + + + + + + + + BMW Connected Drive Username + + + + BMW Connected Drive Password + + + + BMW Car VIN + + + + Based on your location the appropriate BMW Server needs to be connected + Rest of the World + + + + + + + + + Data Refresh Rate for your Car values + 15 + + + + + + + bmwconnecteddriveItem + + Sample channel for BMWConnectedDrive Binding + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java new file mode 100644 index 0000000000000..b59277d033e62 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java @@ -0,0 +1,135 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import static org.junit.Assert.assertEquals; + +import java.nio.charset.Charset; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.api.AuthenticationStore; +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.client.util.StringContentProvider; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.util.MultiMap; +import org.eclipse.jetty.util.UrlEncoded; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link AuthTest} is responsible for handling commands, which are + * sent to one of the channels. + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class AuthTest { + private final Logger logger = LoggerFactory.getLogger(ConnectedCarHandler.class); + + @Test + public void test() { + HttpClient httpClient = new HttpClient(); + try { + httpClient.start(); + } catch (Exception e1) { + // TODO Auto-generated catch block + // e1.printStackTrace(); + } + String uri = "https://customer.bmwgroup.com/gcdm/oauth/authenticate"; + Request req = httpClient.POST(uri); + AuthenticationStore authStore = httpClient.getAuthenticationStore(); + // Authentication a = new Authentication(); + + // "Content-Type": "application/x-www-form-urlencoded", + // "Content-Length": "124", + // "Connection": "Keep-Alive", + // "Host": self.serverUrl, + // "Accept-Encoding": "gzip", + // "Authorization": "Basic blF2NkNxdHhKdVhXUDc0eGYzQ0p3VUVQOjF6REh4NnVuNGNEanli" + // "TEVOTjNreWZ1bVgya0VZaWdXUGNRcGR2RFJwSUJrN3JPSg==", + // "Credentials": "nQv6CqtxJuXWP74xf3CJwUEP:1zDHx6un4cDjybLENN3kyfumX2kEYigWPcQpdvDRpIBk7rOJ", + // "User-Agent": "okhttp/2.60", + req.header("Content-Type", "application/x-www-form-urlencoded"); + req.header("Connection", "Keep-Alive"); + req.header("Host", "b2vapi.bmwgroup.com"); + req.header("Authorization", + "Basic blF2NkNxdHhKdVhXUDc0eGYzQ0p3VUVQOjF6REh4NnVuNGNEanliTEVOTjNreWZ1bVgya0VZaWdXUGNRcGR2RFJwSUJrN3JPSg=="); + req.header("Credentials", "nQv6CqtxJuXWP74xf3CJwUEP:1zDHx6un4cDjybLENN3kyfumX2kEYigWPcQpdvDRpIBk7rOJ"); + + // 'client_id': 'dbf0a542-ebd1-4ff0-a9a7-55172fbfce35', + // 'response_type': 'token', + // 'redirect_uri': 'https://www.bmw-connecteddrive.com/app/static/external-dispatch.html', + // 'scope': 'authenticate_user vehicle_data remote_services', + // 'username': self.bmwUsername, + // 'password': self.bmwPassword + + String data = " {'client_id': 'dbf0a542-ebd1-4ff0-a9a7-55172fbfce35'," + " 'response_type': 'token'," + + " 'redirect_uri': 'https://www.bmw-connecteddrive.com/app/static/external-dispatch.html'," + + " 'scope': 'authenticate_user vehicle_data remote_services'," + + " 'username': 'marika.weymann@gmail.com'," + " 'password': 'P4nd4b3r'}"; + MultiMap map = new MultiMap(); + map.add("client_id", "dbf0a542-ebd1-4ff0-a9a7-55172fbfce35"); + map.add("response_type", "token"); + map.add("redirect_uri", "https://www.bmw-connecteddrive.com/app/static/external-dispatch.html"); + map.add("scope", "authenticate_user vehicle_data remote_services"); + map.add("username", "marika.weymann@gmail.com"); + map.add("password", "P4nd4b3r"); + String urlEncodedData = UrlEncoded.encode(map, Charset.defaultCharset(), false); + logger.info("URL encoded data {}", urlEncodedData); + logger.info("Data size {} ", urlEncodedData.length()); + req.header("Content-Length", urlEncodedData.length() + ""); + req.content(new StringContentProvider(urlEncodedData)); + try { + ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); + logger.info("Status {} ", contentResponse.getStatus()); + logger.info("Reason {} ", contentResponse.getReason()); + logger.info("Encoding {} ", contentResponse.getEncoding()); + logger.info("Content length {} ", contentResponse.getContent().length); + logger.info("Media Type {} ", contentResponse.getMediaType()); + HttpFields fields = contentResponse.getHeaders(); + for (int i = 0; i < fields.size(); i++) { + HttpField field = fields.getField(i); + logger.info("Field {}, Name {}, Value {}", i, field.getName(), field.getValue()); + } + String content = contentResponse.getContentAsString(); + logger.info("Auth response: {}", content); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + logger.info("Auth Exception: {}", e.getMessage()); + // e.printStackTrace(); + } + try { + httpClient.stop(); + } catch (Exception e) { + // TODO Auto-generated catch block + // e.printStackTrace(); + } + httpClient.destroy(); + } + + @Test + public void testTokenDecoding() { + Token t = new Token(); + ConnectedDrivePortalHandler cdpHandler = new ConnectedDrivePortalHandler(new HttpClient()); + String headerValue = "https://www.bmw-connecteddrive.com/app/static/external-dispatch.html#access_token=SfXKgkEXeeFJkVqdD4XMmfUU224MRuyh&token_type=Bearer&expires_in=7199"; + MultiMap map = new MultiMap(); + cdpHandler.storeToken(headerValue, t); + assertEquals("Token", "Bearer SfXKgkEXeeFJkVqdD4XMmfUU224MRuyh", t.getToken()); + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/test.json b/bundles/org.openhab.binding.bmwconnecteddrive/test.json new file mode 100644 index 0000000000000..64fdbd3784cef --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/test.json @@ -0,0 +1,107 @@ +{ + "attributesMap": { + "unitOfLength": "km", + "sunroof_state": "CLOSED", + "chargingLogicCurrentlyActive": "NOT_CHARGING", + "vehicle_tracking": "1", + "chargeNowAllowed": "NOT_ALLOWED", + "updateTime_converted": "16.08.2020 15:34", + "door_driver_rear": "CLOSED", + "head_unit_pu_software": "07/16", + "beMaxRangeElectricKm": "203.0", + "door_passenger_rear": "CLOSED", + "beRemainingRangeFuelKm": "62.0", + "Segment_LastTrip_time_segment_end_formatted_date": "15.08.2020", + "door_driver_front": "CLOSED", + "shdStatusUnified": "CLOSED", + "hood_state": "CLOSED", + "charging_status": "CHARGINGACTIVE", + "kombi_current_remaining_range_fuel": "62.0", + "beMaxRangeElectric": "203.0", + "window_driver_rear": "CLOSED", + "beRemainingRangeElectricKm": "203.0", + "mileage": "17044", + "Segment_LastTrip_time_segment_end_formatted_time": "19:11", + "beMaxRangeElectricMile": "126.0", + "Segment_LastTrip_time_segment_end_formatted": "15.08.2020 19:11", + "lastChargingEndResult": "UNKNOWN", + "unitOfEnergy": "kWh", + "beRemainingRangeElectric": "203.0", + "sunroof_position": "0", + "soc_hv_percent": "65.4", + "single_immediate_charging": "isUnused", + "updateTime_converted_time": "15:34", + "chargingHVStatus": "FINISHED_FULLY_CHARGED", + "connectorStatus": "CONNECTED", + "chargingLevelHv": "100.0", + "chargingSystemStatus": "CHARGINGACTIVE", + "fuelPercent": "47", + "unitOfCombustionConsumption": "l/100km", + "gps_lat": "50.556034", + "window_driver_front": "CLOSED", + "Segment_LastTrip_ratio_electric_driven_distance": "100", + "gps_lng": "8.49561", + "condition_based_services": "00003,OK,2021-11,;00017,OK,2021-11,;00001,OK,2021-11,;00032,OK,2021-11,", + "window_passenger_front": "CLOSED", + "window_passenger_rear": "CLOSED", + "lastChargingEndReason": "UNKNOWN", + "updateTime_converted_date": "16.08.2020", + "beRemainingRangeFuelMile": "38.0", + "beRemainingRangeFuel": "62.0", + "door_passenger_front": "CLOSED", + "updateTime_converted_timestamp": "1597592093000", + "remaining_fuel": "4", + "charging_inductive_positioning": "not_positioned", + "heading": "221", + "lsc_trigger": "DOORSTATECHANGED", + "lights_parking": "OFF", + "door_lock_state": "UNLOCKED", + "updateTime": "16.08.2020 14:34:53 UTC", + "prognosisWhileChargingStatus": "IS_PERFORMED", + "head_unit": "EntryNav", + "trunk_state": "CLOSED", + "battery_size_max": "33200", + "charging_connection_type": "CONDUCTIVE", + "beRemainingRangeElectricMile": "126.0", + "unitOfElectricConsumption": "kWh/100km", + "Segment_LastTrip_time_segment_end": "15.08.2020 19:11:00 UTC", + "lastUpdateReason": "DOORSTATECHANGED" + }, + "vehicleMessages": { + "ccmMessages": [], + "cbsMessages": [ + { + "description": "Nächster Wechsel spätestens zum angegebenen Termin.", + "text": "Bremsflüssigkeit", + "id": 3, + "status": "OK", + "messageType": "CBS", + "date": "2021-11" + }, + { + "description": "Nächste Sichtprüfung nach der angegebenen Fahrstrecke oder zum angegebenen Termin.", + "text": "Fahrzeug-Check", + "id": 17, + "status": "OK", + "messageType": "CBS", + "date": "2021-11" + }, + { + "description": "Nächster Wechsel nach der angegebenen Fahrstrecke oder zum angegebenen Termin.", + "text": "Motoröl", + "id": 1, + "status": "OK", + "messageType": "CBS", + "date": "2021-11" + }, + { + "description": "Nächste gesetzliche Fahrzeuguntersuchung zum angegebenen Termin.", + "text": "§ Fahrzeuguntersuchung", + "id": 32, + "status": "OK", + "messageType": "CBS", + "date": "2021-11" + } + ] + } +} \ No newline at end of file diff --git a/bundles/pom.xml b/bundles/pom.xml index aef3e7d41dcd3..a0851c25927f8 100644 --- a/bundles/pom.xml +++ b/bundles/pom.xml @@ -66,6 +66,7 @@ org.openhab.binding.bluetooth.govee org.openhab.binding.bluetooth.roaming org.openhab.binding.bluetooth.ruuvitag + org.openhab.binding.bmwconnecteddrive org.openhab.binding.boschindego org.openhab.binding.boschshc org.openhab.binding.bosesoundtouch From 30f56475c67397ea59efbb415b98cc4b9bfe5c74 Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 18 Aug 2020 01:00:32 +0200 Subject: [PATCH 002/176] initial commit Signed-off-by: Bernd (cherry picked from commit a1ecf762e6d1f633f3396209b1aa80b50022cc14) Signed-off-by: Bernd --- .../internal/handler/BimmerConstants.java | 18 ++++++------ .../internal/handler/HTTPConstants.java | 28 +++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BimmerConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BimmerConstants.java index c923c1b7cd2ba..c904318a7e862 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BimmerConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BimmerConstants.java @@ -28,10 +28,10 @@ @NonNullByDefault public class BimmerConstants { - public final static String SERVER_NORTH_AMERICA = "b2vapi.bmwgroup.us"; - public final static String SERVER_CHINA = "b2vapi.bmwgroup.cn:859"; - public final static String SERVER_ROW = "b2vapi.bmwgroup.com"; - public final static Map SERVER_MAP = new HashMap() { + public static final String SERVER_NORTH_AMERICA = "b2vapi.bmwgroup.us"; + public static final String SERVER_CHINA = "b2vapi.bmwgroup.cn:859"; + public static final String SERVER_ROW = "b2vapi.bmwgroup.com"; + public static final Map SERVER_MAP = new HashMap() { { put("NORTH_AMERICA", SERVER_NORTH_AMERICA); put("CHINA", SERVER_CHINA); @@ -39,9 +39,9 @@ public class BimmerConstants { } }; - public final static String AUTHORIZATION_VALUE = "Basic blF2NkNxdHhKdVhXUDc0eGYzQ0p3VUVQOjF6REh4NnVuNGNEanliTEVOTjNreWZ1bVgya0VZaWdXUGNRcGR2RFJwSUJrN3JPSg=="; - public final static String CREDENTIAL_VALUES = "nQv6CqtxJuXWP74xf3CJwUEP:1zDHx6un4cDjybLENN3kyfumX2kEYigWPcQpdvDRpIBk7rOJ"; - public final static String CLIENT_ID_VALUE = "dbf0a542-ebd1-4ff0-a9a7-55172fbfce35"; - public final static String REDIRECT_URI_VALUE = "https://www.bmw-connecteddrive.com/app/static/external-dispatch.html"; - public final static String SCOPE_VALUES = "authenticate_user vehicle_data remote_services"; + public static final String AUTHORIZATION_VALUE = "Basic blF2NkNxdHhKdVhXUDc0eGYzQ0p3VUVQOjF6REh4NnVuNGNEanliTEVOTjNreWZ1bVgya0VZaWdXUGNRcGR2RFJwSUJrN3JPSg=="; + public static final String CREDENTIAL_VALUES = "nQv6CqtxJuXWP74xf3CJwUEP:1zDHx6un4cDjybLENN3kyfumX2kEYigWPcQpdvDRpIBk7rOJ"; + public static final String CLIENT_ID_VALUE = "dbf0a542-ebd1-4ff0-a9a7-55172fbfce35"; + public static final String REDIRECT_URI_VALUE = "https://www.bmw-connecteddrive.com/app/static/external-dispatch.html"; + public static final String SCOPE_VALUES = "authenticate_user vehicle_data remote_services"; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/HTTPConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/HTTPConstants.java index 842d06c718ca7..9354b112f04e7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/HTTPConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/HTTPConstants.java @@ -21,19 +21,19 @@ */ @NonNullByDefault public class HTTPConstants { - public final static String CONTENT_TYPE_URL_ENCODED = "application/x-www-form-urlencoded"; - public final static String CONTENT_TYPE_JSON = "application/json"; - public final static String KEEP_ALIVE = "Keep-Alive"; - public final static String CLIENT_ID = "client_id"; - public final static String RESPONSE_TYPE = "response_type"; - public final static String TOKEN = "token"; - public final static String REDIRECT_URI = "redirect_uri"; - public final static String SCOPE = "scope"; - public final static String CREDENTIALS = "Credentials"; - public final static String USERNAME = "username"; - public final static String PASSWORD = "password"; + public static final String CONTENT_TYPE_URL_ENCODED = "application/x-www-form-urlencoded"; + public static final String CONTENT_TYPE_JSON = "application/json"; + public static final String KEEP_ALIVE = "Keep-Alive"; + public static final String CLIENT_ID = "client_id"; + public static final String RESPONSE_TYPE = "response_type"; + public static final String TOKEN = "token"; + public static final String REDIRECT_URI = "redirect_uri"; + public static final String SCOPE = "scope"; + public static final String CREDENTIALS = "Credentials"; + public static final String USERNAME = "username"; + public static final String PASSWORD = "password"; - public final static String ACCESS_TOKEN = "access_token"; - public final static String TOKEN_TYPE = "token_type"; - public final static String EXPIRES_IN = "expires_in"; + public static final String ACCESS_TOKEN = "access_token"; + public static final String TOKEN_TYPE = "token_type"; + public static final String EXPIRES_IN = "expires_in"; } From 15f4aed3fd0928beb151ecc6933db352d73ab7c6 Mon Sep 17 00:00:00 2001 From: Bernd Date: Sun, 23 Aug 2020 14:51:35 +0200 Subject: [PATCH 003/176] Range feature added Signed-off-by: Bernd (cherry picked from commit 1b7e4da6b8df82771215469e029175098768f50e) Signed-off-by: Bernd --- .../Clustering.txt | 77 ++++++ .../internal/ConnectedCarConfiguration.java | 16 -- ....java => ConnectedDriveConfiguration.java} | 23 +- .../internal/ConnectedDriveConstants.java | 122 +++++++++ ...java => ConnectedDriveHandlerFactory.java} | 33 ++- .../discovery/ConnectedCarDiscovery.java | 117 ++++++++ .../internal/dto/AttributesMap.java | 30 ++ .../internal/dto/BevRexAttributes.java | 93 +++++++ .../internal/dto/BevRexAttributesMap.java | 22 ++ .../internal/dto/CBSMessage.java | 27 ++ .../dto/{CarData.java => CCMMessage.java} | 8 +- .../internal/dto/ConnectedDriveUserInfo.java | 34 +++ .../internal/dto/Dealer.java | 27 ++ .../internal/dto/DynamicVehicleRangeData.java | 30 ++ .../internal/dto/Vehicle.java | 58 ++++ .../internal/dto/VehicleMessages.java | 25 ++ .../handler/ConnectedCarChannelHandler.java | 106 ++++++++ .../internal/handler/ConnectedCarHandler.java | 218 +++++++++++++-- .../handler/ConnectedDriveBridgeHandler.java | 256 ++++++++++++++++++ .../handler/ConnectedDrivePortalHandler.java | 155 ----------- .../internal/handler/Token.java | 11 +- .../resources/ESH-INF/binding/binding.xml | 2 +- ...ted-car.xml => bridge-connected-drive.xml} | 41 ++- .../thing/hybrid-range-channel-groups.xml | 19 ++ .../ESH-INF/thing/image-channel-groups.xml | 14 + .../ESH-INF/thing/image-channel-types.xml | 27 ++ .../ESH-INF/thing/range-channel-groups.xml | 13 + .../ESH-INF/thing/range-channel-types.xml | 34 +++ .../resources/ESH-INF/thing/thing-bev_rex.xml | 32 +++ .../internal/dto/BEV_REX_VehcileValues.java | 41 +++ .../internal/dto/ConnectedDriveTest.java | 60 ++++ .../internal/handler/AuthTest.java | 106 +------- .../internal/util/FileReader.java | 48 ++++ .../connected-drive-account-info.json | 63 +++++ .../src/test/resources/efficiency.json | 85 ++++++ .../src/test/resources/navigation.json | 12 + .../{ => src/test/resources}/test.json | 4 +- .../src/test/resources/vehicle.json | 108 ++++++++ .../src/test/resources/webapi-status.json | 76 ++++++ 39 files changed, 1921 insertions(+), 352 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/Clustering.txt rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/{BMWConnectedDriveBindingConstants.java => ConnectedDriveConfiguration.java} (52%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/{BMWConnectedDriveHandlerFactory.java => ConnectedDriveHandlerFactory.java} (60%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/AttributesMap.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexAttributes.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexAttributesMap.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CBSMessage.java rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/{CarData.java => CCMMessage.java} (64%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveUserInfo.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Dealer.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DynamicVehicleRangeData.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Vehicle.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleMessages.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDrivePortalHandler.java rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/{thing-connected-car.xml => bridge-connected-drive.xml} (53%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-range-channel-groups.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-groups.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-groups.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BEV_REX_VehcileValues.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/FileReader.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/connected-drive-account-info.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/efficiency.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/navigation.json rename bundles/org.openhab.binding.bmwconnecteddrive/{ => src/test/resources}/test.json (98%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/vehicle.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi-status.json diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/Clustering.txt b/bundles/org.openhab.binding.bmwconnecteddrive/Clustering.txt new file mode 100644 index 0000000000000..43b13c8d0c870 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/Clustering.txt @@ -0,0 +1,77 @@ + "door_driver_front": "CLOSED", + "door_driver_rear": "CLOSED", + "door_passenger_rear": "CLOSED", + "door_lock_state": "SECURED", + "sunroof_state": "CLOSED", + "sunroof_position": "0", + "hood_state": "CLOSED", + "trunk_state": "CLOSED", + "window_driver_front": "CLOSED", + "window_passenger_front": "CLOSED", + "window_driver_rear": "CLOSED", + "window_passenger_rear": "CLOSED", + "shdStatusUnified": "CLOSED", + "lastUpdateReason": "VEHCSHUTDOWN_SECURED" + "head_unit_pu_software": "07/16", + "vehicle_tracking": "1", + "lsc_trigger": "VEHCSHUTDOWN_SECURED", + "lights_parking": "OFF", + "battery_size_max": "33200", + "head_unit": "EntryNav", + + "unitOfEnergy": "kWh", + "unitOfLength": "km", + "unitOfCombustionConsumption": "l/100km", + "unitOfElectricConsumption": "kWh/100km", + + "charging_status": "NOCHARGING", + "lastChargingEndResult": "SUCCESS", + "lastChargingEndReason": "END_REQUESTED_BY_DRIVER", + + "chargingSystemStatus": "NOCHARGING", + "chargingHVStatus": "INVALID", + "connectorStatus": "DISCONNECTED", + "single_immediate_charging": "isUnused", + "chargingLogicCurrentlyActive": "NOT_CHARGING", + "chargeNowAllowed": "NOT_ALLOWED", + "prognosisWhileChargingStatus": "NOT_NEEDED", + "charging_inductive_positioning": "not_positioned", + "charging_connection_type": "CONDUCTIVE", + + + "heading": "219", + "gps_lat": "50.57321", + "gps_lng": "8.66393", + + + "check_control_messages": "", + + "beMaxRangeElectric": "202.0", + "beMaxRangeElectricKm": "202.0", + "beMaxRangeElectricMile": "125.0", + "beRemainingRangeElectric": "113.0", + "beRemainingRangeElectricKm": "113.0", + "beRemainingRangeElectricMile": "70.0", + "beRemainingRangeFuel": "65.0", + "beRemainingRangeFuelKm": "65.0", + "beRemainingRangeFuelMile": "40.0", + "kombi_current_remaining_range_fuel": "65.0", + "mileage": "17107", + "soc_hv_percent": "58.1", + "chargingLevelHv": "58.0", + "fuelPercent": "47", + "remaining_fuel": "4", + "Segment_LastTrip_ratio_electric_driven_distance": "100", + + "condition_based_services": "00003,OK,2021-11,;00017,OK,2021-11,;00001,OK,2021-11,;00032,OK,2021-11,", + + "updateTime_converted": "18.08.2020 05:44", + "updateTime_converted_date": "18.08.2020", + "updateTime_converted_timestamp": "1597729475000", + "updateTime": "18.08.2020 04:44:35 UTC", + "updateTime_converted_time": "05:44", + "Segment_LastTrip_time_segment_end": "18.08.2020 06:45:00 UTC", + "Segment_LastTrip_time_segment_end_formatted_time": "06:45", + "Segment_LastTrip_time_segment_end_formatted_date": "18.08.2020", + "Segment_LastTrip_time_segment_end_formatted": "18.08.2020 06:45", + \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java index a9237d67064ed..fffcb4d27f58a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java @@ -21,22 +21,6 @@ */ @NonNullByDefault public class ConnectedCarConfiguration { - - /** - * Depending on the location the correct server needs to be called - */ - public String region = ""; - - /** - * BMW Connected Drive Username - */ - public String userName = ""; - - /** - * BMW Connected Drive Password - */ - public String password = ""; - /** * Vehilce Identification Number (VIN) */ diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/BMWConnectedDriveBindingConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConfiguration.java similarity index 52% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/BMWConnectedDriveBindingConstants.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConfiguration.java index 8dda706b41002..2488bda3802f9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/BMWConnectedDriveBindingConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConfiguration.java @@ -13,22 +13,27 @@ package org.openhab.binding.bmwconnecteddrive.internal; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.smarthome.core.thing.ThingTypeUID; /** - * The {@link BMWConnectedDriveBindingConstants} class defines common constants, which are - * used across the whole binding. + * The {@link ConnectedDriveConfiguration} class contains fields mapping thing configuration parameters. * * @author Bernd Weymann - Initial contribution */ @NonNullByDefault -public class BMWConnectedDriveBindingConstants { +public class ConnectedDriveConfiguration { - private static final String BINDING_ID = "bmwconnecteddrive"; + /** + * Depending on the location the correct server needs to be called + */ + public String region = ""; - // List of all Thing Type UIDs - public static final ThingTypeUID THING_TYPE_CONNECTED_CAR = new ThingTypeUID(BINDING_ID, "connected-car"); + /** + * BMW Connected Drive Username + */ + public String userName = ""; - // List of all Channel ids - public static final String CHANNEL_1 = "channel1"; + /** + * BMW Connected Drive Password + */ + public String password = ""; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java new file mode 100644 index 0000000000000..0d22069a83c17 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -0,0 +1,122 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.smarthome.core.thing.ThingTypeUID; + +/** + * The {@link ConnectedDriveConstants} class defines common constants, which are + * used across the whole binding. + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class ConnectedDriveConstants { + + private static final String BINDING_ID = "bmwconnecteddrive"; + + // See constants from bimmer-connected + // https://github.com/bimmerconnected/bimmer_connected/blob/master/bimmer_connected/vehicle.py + public enum CarType { + CONVENTIONAL("CONV"), + PLUGIN_HYBRID("PHEV"), + ELECTRIC_REX("BEV_REX"), + ELECTRIC("BEV"); + + private final String type; + + CarType(String s) { + type = s; + } + + @Override + public String toString() { + return type; + } + } + + public static final Set FUEL_CARS = new HashSet() { + { + add(CarType.CONVENTIONAL.toString()); + add(CarType.PLUGIN_HYBRID.toString()); + add(CarType.ELECTRIC_REX.toString()); + } + }; + public static final Set ELECTRIC_CARS = new HashSet() { + { + add(CarType.ELECTRIC.toString()); + add(CarType.PLUGIN_HYBRID.toString()); + add(CarType.ELECTRIC_REX.toString()); + } + }; + + // List of all Thing Type UIDs + public static final ThingTypeUID THING_TYPE_CONNECTED_DRIVE_ACCOUNT = new ThingTypeUID(BINDING_ID, "account"); + public static final ThingTypeUID THING_TYPE_CONV = new ThingTypeUID(BINDING_ID, CarType.CONVENTIONAL.toString()); + public static final ThingTypeUID THING_TYPE_PHEV = new ThingTypeUID(BINDING_ID, CarType.PLUGIN_HYBRID.toString()); + public static final ThingTypeUID THING_TYPE_BEV_REX = new ThingTypeUID(BINDING_ID, CarType.ELECTRIC_REX.toString()); + public static final ThingTypeUID THING_TYPE_BEV = new ThingTypeUID(BINDING_ID, CarType.ELECTRIC.toString()); + public static final Set SUPPORTED_THING_SET = new HashSet() { + { + add(THING_TYPE_CONNECTED_DRIVE_ACCOUNT); + add(THING_TYPE_CONV); + add(THING_TYPE_PHEV); + add(THING_TYPE_BEV_REX); + add(THING_TYPE_BEV); + } + }; + + // Bridge Channels + public static final String DISCOVERY_TRIGGER = "discovery-trigger"; + public static final String DISCOVERY_FINGERPRINT = "discovery-fingerprint"; + + // Group definitions + public static final String CHANNEL_GROUP_PROPERTIES = "properties"; + public static final String CHANNEL_GROUP_RANGE = "range"; + public static final String CHANNEL_GROUP_CAR_STATUS = "status"; + public static final String CHANNEL_GROUP_CAR_IMAGE = "image"; + + public static final String PROPERTIES_BRAND = "brand"; + public static final String PROPERTIES_MODEL = "model"; + public static final String PROPERTIES_DRIVETRAIN = "drivetrain"; + public static final String PROPERTIES_BODYTYPE = "body"; + public static final String PROPERTIES_COLOR = "color"; + public static final String PROPERTIES_CONSTRUCTION_YEAR = "construction-year"; + public static final String PROPERTIES_COMMUNITY = "community-statistics"; + public static final String PROPERTIES_ALARM = "alarm"; + public static final String PROPERTIES_DEALER_NAME = "dealer-name"; + public static final String PROPERTIES_DEALER_ADDRESS = "dealer-address"; + public static final String PROPERTIES_DEALER_PHONE = "dealer-phone"; + public static final String PROPERTIES_BREAKDOWN_PHONE = "breakdown-phone"; + public static final String PROPERTIES_ACTIVATED_SERVICES = "activated-services"; + public static final String PROPERTIES_DEACTIVATED_SERVICES = "deactivated-services"; + public static final String PROPERTIES_SUPPORTED_SERVICES = "supported-services"; + public static final String PROPERTIES_NOT_SUPPORTED_SERVICES = "not-supported-services"; + public static final String PROPERTIES_CHARGING_MODES = "charging-modes"; + + public static final String IMAGE = "rendered"; + public static final String IMAGE_SIZE = "size"; + public static final String IMAGE_VIEW_DIRECTION = "view-direction"; + + public static final String MILEAGE = "mileage"; + public static final String REMAINING_RANGE = "remaining-range"; + public static final String REMAINING_RANGE_ELECTRIC = "remaining-range-electric"; + public static final String REMAINING_SOC = "remaining-soc"; + public static final String REMAINING_RANGE_FUEL = "remaining-range-fuel"; + public static final String REMAINING_FUEL = "remaining-fuel"; + public static final String LAST_UPDATE = "last-update"; +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/BMWConnectedDriveHandlerFactory.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java similarity index 60% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/BMWConnectedDriveHandlerFactory.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java index 19c5bf79aff9f..14be9b79a0957 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/BMWConnectedDriveHandlerFactory.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java @@ -12,13 +12,11 @@ */ package org.openhab.binding.bmwconnecteddrive.internal; -import static org.openhab.binding.bmwconnecteddrive.internal.BMWConnectedDriveBindingConstants.THING_TYPE_CONNECTED_CAR; - -import java.util.Collections; -import java.util.Set; +import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.thing.Bridge; import org.eclipse.smarthome.core.thing.Thing; import org.eclipse.smarthome.core.thing.ThingTypeUID; import org.eclipse.smarthome.core.thing.binding.BaseThingHandlerFactory; @@ -26,41 +24,50 @@ import org.eclipse.smarthome.core.thing.binding.ThingHandlerFactory; import org.eclipse.smarthome.io.net.http.HttpClientFactory; import org.openhab.binding.bmwconnecteddrive.internal.handler.ConnectedCarHandler; +import org.openhab.binding.bmwconnecteddrive.internal.handler.ConnectedDriveBridgeHandler; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; /** - * The {@link BMWConnectedDriveHandlerFactory} is responsible for creating things and thing + * The {@link ConnectedDriveHandlerFactory} is responsible for creating things and thing * handlers. * * @author Bernd Weymann - Initial contribution */ @NonNullByDefault @Component(configurationPid = "binding.bmwconnecteddrive", service = ThingHandlerFactory.class) -public class BMWConnectedDriveHandlerFactory extends BaseThingHandlerFactory { +public class ConnectedDriveHandlerFactory extends BaseThingHandlerFactory { - private static final Set SUPPORTED_THING_TYPES_UIDS = Collections.singleton(THING_TYPE_CONNECTED_CAR); private final HttpClientFactory httpClientFactory; @Activate - public BMWConnectedDriveHandlerFactory(final @Reference HttpClientFactory hcf) { + public ConnectedDriveHandlerFactory(final @Reference HttpClientFactory hcf) { httpClientFactory = hcf; } @Override public boolean supportsThingType(ThingTypeUID thingTypeUID) { - return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID); + return SUPPORTED_THING_SET.contains(thingTypeUID); } @Override protected @Nullable ThingHandler createHandler(Thing thing) { ThingTypeUID thingTypeUID = thing.getThingTypeUID(); - - if (THING_TYPE_CONNECTED_CAR.equals(thingTypeUID)) { - return new ConnectedCarHandler(thing, httpClientFactory.getCommonHttpClient()); + if (THING_TYPE_CONNECTED_DRIVE_ACCOUNT.equals(thingTypeUID)) { + return new ConnectedDriveBridgeHandler((Bridge) thing, httpClientFactory.getCommonHttpClient(), + bundleContext); + } else if (SUPPORTED_THING_SET.contains(thingTypeUID)) { + return new ConnectedCarHandler(thing, httpClientFactory.getCommonHttpClient(), thingTypeUID.getId()); } - return null; } + + @Override + protected void removeHandler(ThingHandler thingHandler) { + if (thingHandler instanceof ConnectedDriveBridgeHandler) { + // close Handler and remove Discovery Service + ((ConnectedDriveBridgeHandler) thingHandler).close(); + } + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java new file mode 100644 index 0000000000000..9e6c9deda26e6 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java @@ -0,0 +1,117 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.discovery; + +import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.SUPPORTED_THING_SET; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.smarthome.config.discovery.AbstractDiscoveryService; +import org.eclipse.smarthome.config.discovery.DiscoveryResultBuilder; +import org.eclipse.smarthome.core.thing.ThingUID; +import org.openhab.binding.bmwconnecteddrive.internal.dto.ConnectedDriveUserInfo; +import org.openhab.binding.bmwconnecteddrive.internal.dto.Vehicle; +import org.openhab.binding.bmwconnecteddrive.internal.handler.ConnectedDriveBridgeHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link ConnectedCarDiscovery} decodes the initial query from ConnectedDrive and is creating + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +// @Component(service = DiscoveryService.class, immediate = true, configurationPid = "discovery.bmwconnecteddrive") +public class ConnectedCarDiscovery extends AbstractDiscoveryService { + private final Logger logger = LoggerFactory.getLogger(ConnectedCarDiscovery.class); + private static final int DISCOVERY_TIMEOUT = 10; + + private ConnectedDriveBridgeHandler bridgeHandler; + + public ConnectedCarDiscovery(ConnectedDriveBridgeHandler bh) { + super(SUPPORTED_THING_SET, DISCOVERY_TIMEOUT, false); + bridgeHandler = bh; + logger.info("Created ConnectedCarDiscovery"); + } + + @Override + protected void startScan() { + // nothing to start - wait until first results of ConnectedDriveBridgeHandler results + } + + public void scan(ConnectedDriveUserInfo cdui) { + List vehicles = cdui.getVehicles(); + logger.info("Discovered {} Vehicles", vehicles.size()); + vehicles.forEach(vehicle -> { + ThingUID bridgeUID = bridgeHandler.getThing().getUID(); + // the DriveTrain field in the delivered json is defining the Vehicle Type + String vehicleType = vehicle.driveTrain; + SUPPORTED_THING_SET.forEach(entry -> { + if (entry.getId().equals(vehicleType)) { + ThingUID uid = new ThingUID(entry, vehicle.vin); + Map properties = new HashMap<>(); + properties.put("vin", vehicle.vin); + properties.put("refreshInterval", 5); + properties.put("model", vehicle.model); + properties.put("statisticsCommunityEnabled", vehicle.color); + properties.put("driveTrain", vehicle.driveTrain); + properties.put("brand", vehicle.brand); + properties.put("yearOfConstruction", vehicle.yearOfConstruction); + properties.put("bodytype", vehicle.bodytype); + properties.put("statisticsCommunityEnabled", vehicle.color); + properties.put("dealerName", vehicle.dealer.name); + properties.put("dealerAddress", vehicle.dealer.street + " " + vehicle.dealer.country + " " + + vehicle.dealer.postalCode + " " + vehicle.dealer.city); + properties.put("dealerPhone", vehicle.dealer.phone); + properties.put("breakdownNumber", vehicle.breakdownNumber); + StringBuffer chargingModes = new StringBuffer(); + if (vehicle.supportedChargingModes != null) { + vehicle.supportedChargingModes.forEach(e -> { + chargingModes.append(e + " "); + }); + } + + properties.put("activatedServcies", getObject(vehicle, Vehicle.ACTIVATED)); + properties.put("supportedServices", getObject(vehicle, Vehicle.SUPPORTED)); + properties.put("activatedServcies", getObject(vehicle, Vehicle.NOT_SUPPORTED)); + String carLabel = vehicle.brand + " " + vehicle.model; + logger.info("Thing {} discovered", carLabel); + thingDiscovered(DiscoveryResultBuilder.create(uid).withBridge(bridgeUID) + .withRepresentationProperty("vin").withLabel(carLabel).withProperties(properties).build()); + } + }); + + }); + } + + public String getObject(Object obj, String compare) { + StringBuffer buf = new StringBuffer(); + for (Field field : obj.getClass().getDeclaredFields()) { + // field.setAccessible(true); // if you want to modify private fields + try { + if (field.get(obj).equals(compare)) { + buf.append(field.getName()); + } + } catch (IllegalArgumentException e) { + logger.warn("Field {} not found {}", compare, e.getMessage()); + } catch (IllegalAccessException e) { + logger.warn("Field {} not found {}", compare, e.getMessage()); + } + } + return buf.toString(); + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/AttributesMap.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/AttributesMap.java new file mode 100644 index 0000000000000..645b57a6dcfbb --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/AttributesMap.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; + +/** + * The {@link AttributesMap} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class AttributesMap { + private DynamicVehicleRangeData attributesMap; + + public DynamicVehicleRangeData getAttributesMap() { + return attributesMap; + } + + public void setAttributesMap(DynamicVehicleRangeData attributesMap) { + this.attributesMap = attributesMap; + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexAttributes.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexAttributes.java new file mode 100644 index 0000000000000..22364473d2730 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexAttributes.java @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; + +import java.util.List; + +/** + * The {@link BevRexAttributes} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class BevRexAttributes { + public String unitOfLength; + public float mileage; // "17236", + public float beMaxRangeElectricKm; // "209.0", + public float beRemainingRangeElectric; // "179.0", + public float beRemainingRangeElectricKm; // "179.0", + public float beRemainingRangeFuelMile; // "41.0", + public float beRemainingRangeFuel; // "67.0", + public float beMaxRangeElectricMile; // "129.0", + public float beRemainingRangeElectricMile; // "111.0", + public float beRemainingRangeFuelKm; // "67.0", + public float kombi_current_remaining_range_fuel; // "67.0", + public float soc_hv_percent; // "82.6", + public float chargingLevelHv; // "89.0", + public float fuelPercent; // "47", + public float remaining_fuel; // "4", + + public String sunroof_state; // : "CLOSED" + public String chargingLogicCurrentlyActive;// ; // "NOT_CHARGING", + public int vehicle_tracking; // ; // "1", + public String updateTime_converted; // "22.08.2020 13:55", + public String door_driver_rear; // "CLOSED", + public String head_unit_pu_software; // "07/16", + public String door_passenger_rear; // "CLOSED", + public String door_driver_front; // "CLOSED", + public String shdStatusUnified; // "CLOSED", + public String hood_state; // "CLOSED", + public String charging_status; // "NOCHARGING", + public String beMaxRangeElectric; // "209.0", + public String window_driver_rear; // "CLOSED", + public String lastChargingEndResult; // "SUCCESS", + public String check_control_messages; // "", + public String unitOfEnergy; // "kWh", + public int sunroof_position; // "0", + public String single_immediate_charging; // "isUnused", + public String updateTime_converted_time; // "13:55", + public String chargingHVStatus; // "INVALID", + public String connectorStatus; // "DISCONNECTED", + public String chargingSystemStatus; // "NOCHARGING", + public String unitOfCombustionConsumption; // "l/100km", + public String window_driver_front; // "CLOSED", + public String Segment_LastTrip_ratio_electric_driven_distance; // "100", + public String condition_based_services; // "00003,OK,2021-11,;00017,OK,2021-11,;00001,OK,2021-11,;00032,OK,2021-11,", + public String window_passenger_front; // "CLOSED", + public String window_passenger_rear; // "CLOSED", + public String lastChargingEndReason; // "CHARGING_GOAL_REACHED", + public String updateTime_converted_date; // "22.08.2020", + public String door_passenger_front; // "CLOSED", + public String updateTime_converted_timestamp; // "1598104546000", + public String charging_inductive_positioning; // "not_positioned", + public String lsc_trigger; // "VEHCSHUTDOWN_SECURED", + public String lights_parking; // "OFF", + public String door_lock_state; // "SECURED", + public String updateTime; // "22.08.2020 12:55:46 UTC", + public String prognosisWhileChargingStatus; // "NOT_NEEDED", + public String head_unit; // "EntryNav", + public String trunk_state; // "CLOSED", + public int battery_size_max; // "33200", + public String charging_connection_type; // "CONDUCTIVE", + public String unitOfElectricConsumption; // "kWh/100km", + public String lastUpdateReason; // ": "VEHCSHUTDOWN_SECURED" + public List vehicleMessages; + + public float gps_lat; // "50.556164", + public float gps_lng; // "8.495482", + public float heading; // "41", + + public String Segment_LastTrip_time_segment_end_formatted; // "22.08.2020 14:52", + public String Segment_LastTrip_time_segment_end; // "22.08.2020 14:52:00 UTC", + public String Segment_LastTrip_time_segment_end_formatted_date; // "22.08.2020", + public String Segment_LastTrip_time_segment_end_formatted_time; // "14:52", +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexAttributesMap.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexAttributesMap.java new file mode 100644 index 0000000000000..5fd43e950658e --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexAttributesMap.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; + +/** + * The {@link BevRexAttributesMap} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class BevRexAttributesMap { + public BevRexAttributes attributesMap; +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CBSMessage.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CBSMessage.java new file mode 100644 index 0000000000000..91bd09078cd84 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CBSMessage.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; + +/** + * The {@link CBSMessage} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class CBSMessage { + public String description; // ": "Nächster Wechsel spätestens zum angegebenen Termin.", + public String text; // ": "Bremsflüssigkeit", + public int id; // ": 3, + public String status; // ": "OK", + public String messageType; // : "CBS", + public String date; // 2021-11" +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CarData.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CCMMessage.java similarity index 64% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CarData.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CCMMessage.java index e0ff1e8fde68e..81e376a775d8b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CarData.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CCMMessage.java @@ -12,15 +12,11 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.dto; -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.binding.bmwconnecteddrive.internal.ConnectedCarConfiguration; - /** - * The {@link ConnectedCarConfiguration} class contains fields mapping thing configuration parameters. + * The {@link CCMMessage} Data Transfer Object * * @author Bernd Weymann - Initial contribution */ -@NonNullByDefault -public class CarData { +public class CCMMessage { } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveUserInfo.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveUserInfo.java new file mode 100644 index 0000000000000..4d33963c73c25 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveUserInfo.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; + +import java.util.List; + +/** + * The {@link ConnectedDriveUserInfo} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class ConnectedDriveUserInfo { + // @SerializedName("sampling_rate") + // private int samplingRate; + private List vehicles; + + public List getVehicles() { + return vehicles; + } + + public void setVehicles(List vehicles) { + this.vehicles = vehicles; + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Dealer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Dealer.java new file mode 100644 index 0000000000000..aadc268478661 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Dealer.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; + +/** + * The {@link Dealer} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class Dealer { + public String name; + public String street; + public String postalCode; + public String city; + public String country; + public String phone; +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DynamicVehicleRangeData.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DynamicVehicleRangeData.java new file mode 100644 index 0000000000000..564a0c17d502d --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DynamicVehicleRangeData.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; + +/** + * The {@link DynamicVehicleRangeData} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class DynamicVehicleRangeData { + private int beRemainingRangeElectric; + + public int getBeRemainingRangeElectric() { + return beRemainingRangeElectric; + } + + public void setBeRemainingRangeElectric(int beRemainingRangeElectric) { + this.beRemainingRangeElectric = beRemainingRangeElectric; + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Vehicle.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Vehicle.java new file mode 100644 index 0000000000000..4411888fa54e5 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Vehicle.java @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; + +import java.util.ArrayList; +import java.util.List; + +/** + * The {@link Vehicle} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class Vehicle { + public final static String ACTIVATED = "ACTIVATED"; + public final static String SUPPORTED = "SUPPORTED"; + public final static String NOT_SUPPORTED = "NOT_SUPPORTED"; + public String vin; + public String model; + public String driveTrain; + public String brand; + public short yearOfConstruction; + public String bodytype; + public String color; + public boolean statisticsCommunityEnabled; + public boolean hasAlarmSystem; + public Dealer dealer; + public String breakdownNumber; + public List supportedChargingModes; + + public List activatedServices = new ArrayList(); + public List notActivatedServices = new ArrayList(); + public String vehicleFinder; // ACTIVATED + public String hornBlow; // ACTIVATED + public String lightFlash; // ACTIVATED + public String doorLock; // ACTIVATED + public String doorUnlock; // ACTIVATED + public String climateNow; // ACTIVATED + public String sendPoi; // ACTIVATED + + public List supportedServices = new ArrayList(); + public List notSupportedServices = new ArrayList(); + public String remote360; // SUPPORTED + public String climateControl; // SUPPORTED + public String chargeNow; // SUPPORTED + public String lastDestinations; // SUPPORTED + public String carCloud; // SUPPORTED + public String remoteSoftwareUpgrade; // SUPPORTED +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleMessages.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleMessages.java new file mode 100644 index 0000000000000..647e488015783 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleMessages.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; + +import java.util.List; + +/** + * The {@link VehicleMessages} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class VehicleMessages { + public List ccmMessages; + public List cbsMessages; +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java new file mode 100644 index 0000000000000..49406c9e4943b --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.smarthome.core.thing.ChannelUID; +import org.eclipse.smarthome.core.thing.Thing; +import org.eclipse.smarthome.core.thing.binding.BaseThingHandler; +import org.eclipse.smarthome.core.types.Command; + +/** + * The {@link ConnectedCarChannelHandler} is responsible for handling commands, which are + * sent to one of the channels. + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class ConnectedCarChannelHandler extends BaseThingHandler { + // Property Channels + protected ChannelUID brandChannel; + protected ChannelUID modelChannel; + protected ChannelUID drivetrainChannel; + protected ChannelUID bodyChannel; + protected ChannelUID colorChannel; + protected ChannelUID constructionYearChannel; + protected ChannelUID communityStatisticsChannel; + protected ChannelUID alarmChannel; + protected ChannelUID dealerNameChannel; + protected ChannelUID dealerAddressChannel; + protected ChannelUID dealerPhoneChannel; + protected ChannelUID breakdownPhoneChannel; + protected ChannelUID activatedServicesChannel; + protected ChannelUID deactivatedServicesChannel; + protected ChannelUID supportedServicesChannel; + protected ChannelUID notSupportedServicesChannel; + protected ChannelUID chargingModesChannel; + + // Vehcile channels + protected ChannelUID mileage; + protected ChannelUID remainingRange; + protected ChannelUID remainingRangeElectric; + protected ChannelUID remainingSoc; + protected ChannelUID remainingRangeFuel; + protected ChannelUID remainingFuel; + protected ChannelUID lastUpdate; + + protected ChannelUID imageChannel; + protected ChannelUID imageSizeChannel; + protected ChannelUID imageViewDirectionChannel; + + public ConnectedCarChannelHandler(Thing thing) { + super(thing); + + // create properties channels + brandChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_BRAND); + modelChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_MODEL); + drivetrainChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_DRIVETRAIN); + bodyChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_BODYTYPE); + colorChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_COLOR); + constructionYearChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, + PROPERTIES_CONSTRUCTION_YEAR); + communityStatisticsChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_COMMUNITY); + alarmChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_ALARM); + dealerNameChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_DEALER_NAME); + dealerAddressChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_DEALER_ADDRESS); + dealerPhoneChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_DEALER_PHONE); + breakdownPhoneChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_BREAKDOWN_PHONE); + activatedServicesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, + PROPERTIES_ACTIVATED_SERVICES); + deactivatedServicesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, + PROPERTIES_DEACTIVATED_SERVICES); + supportedServicesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, + PROPERTIES_SUPPORTED_SERVICES); + notSupportedServicesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, + PROPERTIES_NOT_SUPPORTED_SERVICES); + chargingModesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_CHARGING_MODES); + + mileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, MILEAGE); + remainingRange = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_RANGE); + remainingRangeElectric = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_RANGE_ELECTRIC); + remainingSoc = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_SOC); + remainingRangeFuel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_RANGE_FUEL); + remainingFuel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_FUEL); + lastUpdate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, LAST_UPDATE); + + imageChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CAR_IMAGE, IMAGE); + imageSizeChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CAR_IMAGE, IMAGE_VIEW_DIRECTION); + imageViewDirectionChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CAR_IMAGE, IMAGE_SIZE); + } + + @Override + public void handleCommand(ChannelUID channelUID, Command command) { + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java index 5bcb8c66ddfa8..040ac025d589c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java @@ -12,26 +12,42 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.handler; -import static org.openhab.binding.bmwconnecteddrive.internal.BMWConnectedDriveBindingConstants.CHANNEL_1; +import static org.openhab.binding.bmwconnecteddrive.internal.handler.HTTPConstants.CONTENT_TYPE_JSON; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; 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.smarthome.core.library.types.QuantityType; +import org.eclipse.smarthome.core.library.types.RawType; +import org.eclipse.smarthome.core.library.types.StringType; +import org.eclipse.smarthome.core.library.unit.ImperialUnits; +import org.eclipse.smarthome.core.library.unit.MetricPrefix; +import org.eclipse.smarthome.core.library.unit.SIUnits; +import org.eclipse.smarthome.core.library.unit.SmartHomeUnits; +import org.eclipse.smarthome.core.thing.Bridge; import org.eclipse.smarthome.core.thing.ChannelUID; import org.eclipse.smarthome.core.thing.Thing; import org.eclipse.smarthome.core.thing.ThingStatus; import org.eclipse.smarthome.core.thing.ThingStatusDetail; -import org.eclipse.smarthome.core.thing.binding.BaseThingHandler; +import org.eclipse.smarthome.core.thing.binding.BridgeHandler; import org.eclipse.smarthome.core.types.Command; -import org.eclipse.smarthome.core.types.RefreshType; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedCarConfiguration; -import org.openhab.binding.bmwconnecteddrive.internal.dto.CarData; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CarType; +import org.openhab.binding.bmwconnecteddrive.internal.dto.BevRexAttributes; +import org.openhab.binding.bmwconnecteddrive.internal.dto.BevRexAttributesMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.gson.Gson; + /** * The {@link ConnectedCarHandler} is responsible for handling commands, which are * sent to one of the channels. @@ -39,31 +55,34 @@ * @author Bernd Weymann - Initial contribution */ @NonNullByDefault -public class ConnectedCarHandler extends BaseThingHandler { +public class ConnectedCarHandler extends ConnectedCarChannelHandler { private final Logger logger = LoggerFactory.getLogger(ConnectedCarHandler.class); + private static final Gson GSON = new Gson(); + + private String driveTrain; + private HttpClient httpClient; + private Token token = new Token(); - private final ConnectedDrivePortalHandler cdpHandler; + private @Nullable ConnectedDriveBridgeHandler bridgeHandler; protected @Nullable ScheduledFuture refreshJob; - public ConnectedCarHandler(Thing thing, HttpClient hc) { + // Connected Drive APIs + private @Nullable String vehicleAPI; + private @Nullable String navigationAPI; + private @Nullable String efficiencyAPI; + private @Nullable String remoteControlAPI; + private @Nullable String remoteExecutionAPI; + private @Nullable String sendMessageAPI; + private @Nullable String imageAPI; + + public ConnectedCarHandler(Thing thing, HttpClient hc, String type) { super(thing); - cdpHandler = new ConnectedDrivePortalHandler(hc); + httpClient = hc; + driveTrain = type; } @Override public void handleCommand(ChannelUID channelUID, Command command) { - if (CHANNEL_1.equals(channelUID.getId())) { - if (command instanceof RefreshType) { - // TODO: handle data refresh - } - - // TODO: handle command - - // Note: if communication with thing fails for some reason, - // indicate that by setting the status with detail information: - // updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, - // "Could not control device at IP address x.x.x.x"); - } } @Override @@ -72,7 +91,47 @@ public void initialize() { ConnectedCarConfiguration config = getConfigAs(ConnectedCarConfiguration.class); if (config != null) { scheduler.execute(() -> { - cdpHandler.initialize(config); + Bridge bridge = getBridge(); + if (bridge != null) { + BridgeHandler handler = bridge.getHandler(); + if (handler != null) { + bridgeHandler = ((ConnectedDriveBridgeHandler) handler); + String baseUrl = "https://" + bridgeHandler.getRegionServer() + "/api/vehicle"; + + // https://b2vapi.bmwgroup.com/api/vehicle/dynamic/v1/ + // from bimmer_connect project + // r = requests.get(self.vehicleApi+'/dynamic/v1/'+self.bmwVin+'?offset=-60', + vehicleAPI = baseUrl + "/dynamic/v1/" + config.vin + "?offset=-60"; + // r = requests.post(self.vehicleApi+'/myinfo/v1', data=json.dumps(values), + sendMessageAPI = baseUrl + "/myinfo/v1"; + // r = requests.get(self.vehicleApi+'/navigation/v1/'+self.bmwVin, + // headers=headers,allow_redirects=True) + navigationAPI = baseUrl + "/navigation/v1/" + config.vin; + // r = requests.get(self.vehicleApi+'/efficiency/v1/'+self.bmwVin, + // headers=headers,allow_redirects=True) + efficiencyAPI = baseUrl + "/efficiency/v1/" + config.vin; + // r = requests.post(self.vehicleApi+'/remoteservices/v1/'+self.bmwVin+'/'+command, + remoteControlAPI = baseUrl + "/remoteservices/v1/" + config.vin; + // r = requests.get(self.vehicleApi+'/remoteservices/v1/'+self.bmwVin+'/state/execution', + remoteExecutionAPI = baseUrl + "/remoteservices/v1/" + config.vin + "/state/execution"; + imageAPI = "https://" + bridgeHandler.getRegionServer() + "/webapi/v1/user/vehicles/" + + config.vin + "/image?width=400&height=400&view=REARBIRDSEYE"; + + // String baseUrl = "https://" + bridgeHandler.getRegionServer(); + // statusAPI = baseUrl + "/webapi/v1/user/vehicles/" + config.vin + "/status"; + // lastTripAPI = baseUrl + "/webapi/v1/user/vehicles/" + config.vin + "/statistics/lastTrip"; + // /webapi/v1/user/vehicles/:VIN/chargingprofile + // /webapi/v1/user/vehicles/:VIN/destinations + // /webapi/v1/user/vehicles/:VIN/statistics/allTrips + // /webapi/v1/user/vehicles/:VIN/rangemap + } else { + logger.warn("Brdige Handler null"); + } + } else { + logger.warn("Bridge null"); + } + + getImage(); startSchedule(config.refreshInterval); }); } else { @@ -84,17 +143,13 @@ private void startSchedule(int interval) { ScheduledFuture localRefreshJob = refreshJob; if (localRefreshJob != null) { if (localRefreshJob.isCancelled()) { - refreshJob = scheduler.scheduleWithFixedDelay(this::dataUpdate, 0, interval, TimeUnit.MINUTES); + refreshJob = scheduler.scheduleWithFixedDelay(this::getData, 0, interval, TimeUnit.MINUTES); } // else - scheduler is already running! } else { - refreshJob = scheduler.scheduleWithFixedDelay(this::dataUpdate, 0, interval, TimeUnit.MINUTES); + refreshJob = scheduler.scheduleWithFixedDelay(this::getData, 0, interval, TimeUnit.MINUTES); } } - protected void dataUpdate() { - CarData carData = cdpHandler.getData(); - } - @Override public void dispose() { ScheduledFuture localRefreshJob = refreshJob; @@ -102,4 +157,113 @@ public void dispose() { localRefreshJob.cancel(true); } } + + public void getData() { + if (!tokenUpdate()) { + return; + } + + Request req = httpClient.newRequest(vehicleAPI); + req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); + req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); + try { + ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); + logger.info("Status {}", contentResponse.getStatus()); + logger.info("Reason {}", contentResponse.getReason()); + logger.info("Vehicle {}", contentResponse.getContentAsString()); + updateStatus(ThingStatus.ONLINE); + updateRangeStates(contentResponse.getContentAsString()); + } catch (InterruptedException | TimeoutException | ExecutionException e) { + logger.warn("Get Data Exception {}", e.getMessage()); + } + + req = httpClient.newRequest(efficiencyAPI); + req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); + req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); + try { + ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); + logger.info("Status {}", contentResponse.getStatus()); + logger.info("Reason {}", contentResponse.getReason()); + logger.info("Efficiency {}", contentResponse.getContentAsString()); + } catch (InterruptedException | TimeoutException | ExecutionException e) { + logger.warn("Get Data Exception {}", e.getMessage()); + } + + req = httpClient.newRequest(navigationAPI); + req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); + req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); + try { + ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); + logger.info("Status {}", contentResponse.getStatus()); + logger.info("Reason {}", contentResponse.getReason()); + logger.info("Navigation {}", contentResponse.getContentAsString()); + } catch (InterruptedException | TimeoutException | ExecutionException e) { + logger.warn("Get Data Exception {}", e.getMessage()); + } + } + + private void updateRangeStates(String content) { + if (driveTrain.equals(CarType.ELECTRIC_REX.toString())) { + BevRexAttributesMap data = GSON.fromJson(content, BevRexAttributesMap.class); + BevRexAttributes bevRexAttributes = data.attributesMap; + logger.info("Update Milage {} Channel {}", bevRexAttributes.mileage, mileage.toString()); + // based on unit of length decide if range shall be reported in km or miles + if (bevRexAttributes.unitOfLength.equals("km")) { + updateState(mileage, QuantityType.valueOf(bevRexAttributes.mileage, MetricPrefix.KILO(SIUnits.METRE))); + updateState(remainingRangeElectric, QuantityType.valueOf(bevRexAttributes.beRemainingRangeElectricKm, + MetricPrefix.KILO(SIUnits.METRE))); + updateState(remainingRangeFuel, QuantityType.valueOf(bevRexAttributes.beRemainingRangeFuelKm, + MetricPrefix.KILO(SIUnits.METRE))); + updateState(remainingRange, + QuantityType.valueOf( + bevRexAttributes.beRemainingRangeElectricKm + bevRexAttributes.beRemainingRangeFuelKm, + MetricPrefix.KILO(SIUnits.METRE))); + } else { + updateState(mileage, QuantityType.valueOf(bevRexAttributes.mileage, ImperialUnits.MILE)); + updateState(remainingRangeElectric, + QuantityType.valueOf(bevRexAttributes.beRemainingRangeElectricMile, ImperialUnits.MILE)); + updateState(remainingRangeFuel, + QuantityType.valueOf(bevRexAttributes.beRemainingRangeFuelMile, ImperialUnits.MILE)); + updateState(remainingRange, QuantityType.valueOf( + bevRexAttributes.beRemainingRangeElectricMile + bevRexAttributes.beRemainingRangeFuelMile, + ImperialUnits.MILE)); + } + updateState(remainingSoc, QuantityType.valueOf(bevRexAttributes.chargingLevelHv, SmartHomeUnits.PERCENT)); + updateState(remainingFuel, QuantityType.valueOf(bevRexAttributes.fuelPercent, SmartHomeUnits.PERCENT)); + updateState(lastUpdate, new StringType(bevRexAttributes.Segment_LastTrip_time_segment_end_formatted)); + } else { + logger.warn("No update of for {} which {}", driveTrain, CarType.ELECTRIC_REX.toString()); + } + } + + public void getImage() { + if (!tokenUpdate()) { + return; + } + + logger.info("Get image {}", imageAPI); + Request req = httpClient.newRequest(imageAPI); + req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); + req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); + try { + ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); + logger.info("getStatus {}", contentResponse.getStatus()); + logger.info("getMediaType {}", contentResponse.getMediaType()); + byte[] image = contentResponse.getContent(); + updateState(imageChannel, new RawType(image, RawType.DEFAULT_MIME_TYPE)); + } catch (InterruptedException | TimeoutException | ExecutionException e) { + logger.warn("Get Data Exception {}", e.getMessage()); + } + } + + public synchronized boolean tokenUpdate() { + if (token.isExpired()) { + token = bridgeHandler.getToken(); + if (token.isExpired() || !token.isValid()) { + logger.info("Token update failed!"); + return false; + } + } + return true; + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java new file mode 100644 index 0000000000000..a8910ccb924c6 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java @@ -0,0 +1,256 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; +import static org.openhab.binding.bmwconnecteddrive.internal.handler.HTTPConstants.*; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Hashtable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +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.client.util.StringContentProvider; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.util.MultiMap; +import org.eclipse.jetty.util.UrlEncoded; +import org.eclipse.smarthome.config.discovery.DiscoveryService; +import org.eclipse.smarthome.core.library.types.OnOffType; +import org.eclipse.smarthome.core.thing.Bridge; +import org.eclipse.smarthome.core.thing.ChannelUID; +import org.eclipse.smarthome.core.thing.ThingStatus; +import org.eclipse.smarthome.core.thing.ThingStatusDetail; +import org.eclipse.smarthome.core.thing.binding.BaseBridgeHandler; +import org.eclipse.smarthome.core.types.Command; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConfiguration; +import org.openhab.binding.bmwconnecteddrive.internal.discovery.ConnectedCarDiscovery; +import org.openhab.binding.bmwconnecteddrive.internal.dto.ConnectedDriveUserInfo; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; + +/** + * The {@link ConnectedDriveBridgeHandler} is responsible for handling commands, which are + * sent to one of the channels. + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class ConnectedDriveBridgeHandler extends BaseBridgeHandler { + private final Logger logger = LoggerFactory.getLogger(ConnectedDriveBridgeHandler.class); + private static final Gson GSON = new Gson(); + private HttpClient httpClient; + private Token token = new Token(); + private BundleContext bundleContext; + private ServiceRegistration discoveryServiceRegstration; + private ConnectedCarDiscovery discoveryService; + private @Nullable ConnectedDriveConfiguration configuration; + private @Nullable ScheduledFuture refreshJob; + private @Nullable String troubleshootFingerprint; + private @Nullable String authUri; + + public ConnectedDriveBridgeHandler(Bridge bridge, HttpClient hc, BundleContext bc) { + super(bridge); + httpClient = hc; + bundleContext = bc; + discoveryService = new ConnectedCarDiscovery(this); + discoveryServiceRegstration = bundleContext.registerService(DiscoveryService.class.getName(), discoveryService, + new Hashtable<>()); + } + + @Override + public void handleCommand(ChannelUID channelUID, Command command) { + if (channelUID.getIdWithoutGroup().equals(DISCOVERY_FINGERPRINT)) { + if (command instanceof OnOffType) { + if (command.equals(OnOffType.ON)) { + if (troubleshootFingerprint != null) { + logger.warn("BMW ConnectedDrive Binding - Discovery Troubleshoot fingerprint - BEGIN"); + logger.warn("{}", troubleshootFingerprint); + logger.warn("BMW ConnectedDrive Binding - Discovery Troubleshoot fingerprint - END"); + } else { + logger.warn( + "BMW ConnectedDrive Binding - No Discovery Troubleshoot fingerprint available. Please check for valid username and password Settings for proper connection towards ConnectDrive"); + } + } + // Switch back to off immediately + updateState(channelUID, OnOffType.OFF); + } + } else if (channelUID.getIdWithoutGroup().equals(DISCOVERY_TRIGGER)) { + if (command instanceof OnOffType) { + if (command.equals(OnOffType.ON)) { + // trigger discovery again - helpful after the user performed some changes in the ConnectedDrive + // Portal and + // wants to refresh the changes + scheduler.schedule(this::getPortalData, 0, TimeUnit.SECONDS); + } + // Switch back to off immediately + updateState(channelUID, OnOffType.OFF); + } + } + } + + @Override + public void initialize() { + updateStatus(ThingStatus.UNKNOWN); + configuration = getConfigAs(ConnectedDriveConfiguration.class); + if (configuration != null) { + // generate URI for Authorization + // https://customer.bmwgroup.com/one/app/oauth.js + StringBuffer uri = new StringBuffer(); + uri.append("https://customer.bmwgroup.com"); + if (BimmerConstants.SERVER_NORTH_AMERICA.equals(configuration.region)) { + uri.append("/gcdm/usa/oauth/authenticate"); + } else { + uri.append("/gcdm/oauth/authenticate"); + } + authUri = uri.toString(); + + scheduler.schedule(this::getPortalData, 0, TimeUnit.SECONDS); + } else { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR); + } + } + + @Override + public void dispose() { + ScheduledFuture localRefreshJob = refreshJob; + if (localRefreshJob != null) { + localRefreshJob.cancel(true); + } + } + + public void getPortalData() { + getToken(); + String webAPIUrl = "https://" + BimmerConstants.SERVER_MAP.get(configuration.region) + + "/webapi/v1/user/vehicles/"; + logger.info("Request {}", webAPIUrl); + Request req = httpClient.newRequest(webAPIUrl); + req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); + req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); + try { + ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); + logger.info("Status {}", contentResponse.getStatus()); + logger.info("Reason {}", contentResponse.getReason()); + logger.info("Info {}", contentResponse.getContentAsString()); + + ConnectedDriveUserInfo userInfo = GSON.fromJson(contentResponse.getContentAsString(), + ConnectedDriveUserInfo.class); + discoveryService.scan(userInfo); + updateStatus(ThingStatus.ONLINE); + if (userInfo.getVehicles() != null) { + if (userInfo.getVehicles().isEmpty()) { + troubleshootFingerprint = "No Cars found in your ConnectedDrive Account"; + } else { + userInfo.getVehicles().forEach(entry -> { + entry.vin = "xxx"; + }); + troubleshootFingerprint = GSON.toJson(userInfo); + } + } + } catch (InterruptedException | TimeoutException | ExecutionException e) { + logger.warn("Get Data Exception {}", e.getMessage()); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, + "Error during BMW ConnectedDrive Authorization " + e.getMessage()); + } + } + + public String getRegionServer() { + return BimmerConstants.SERVER_MAP.get(configuration.region); + } + + public Token getToken() { + if (token.isExpired() || !token.isValid()) { + token = getNewToken(); + } + return token; + } + + /** + * Authorize at BMW Connected Drive Portal and re + * + * @return + */ + public Token getNewToken() { + httpClient.setFollowRedirects(false); + Request req = httpClient.POST(authUri); + + req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); + req.header(HttpHeader.CONNECTION, KEEP_ALIVE); + req.header(HttpHeader.HOST, BimmerConstants.SERVER_MAP.get(configuration.region)); + req.header(HttpHeader.AUTHORIZATION, BimmerConstants.AUTHORIZATION_VALUE); + req.header(CREDENTIALS, BimmerConstants.CREDENTIAL_VALUES); + + MultiMap dataMap = new MultiMap(); + dataMap.add(CLIENT_ID, BimmerConstants.CLIENT_ID_VALUE); + dataMap.add(RESPONSE_TYPE, TOKEN); + dataMap.add(REDIRECT_URI, BimmerConstants.REDIRECT_URI_VALUE); + dataMap.add(SCOPE, BimmerConstants.SCOPE_VALUES); + dataMap.add(USERNAME, configuration.userName); + dataMap.add(PASSWORD, configuration.password); + String urlEncodedData = UrlEncoded.encode(dataMap, Charset.defaultCharset(), false); + + // logger.info("URL encoded data {}", urlEncodedData); + // logger.info("Data size {} ", urlEncodedData.length()); + req.header("Content-Length", urlEncodedData.length() + ""); + req.content(new StringContentProvider(urlEncodedData)); + try { + ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); + logger.info("Status {} ", contentResponse.getStatus()); + // logger.info("Reason {} ", contentResponse.getReason()); + // logger.info("Encoding {} ", contentResponse.getEncoding()); + // logger.info("Content length {} ", contentResponse.getContent().length); + // logger.info("Media Type {} ", contentResponse.getMediaType()); + HttpFields fields = contentResponse.getHeaders(); + HttpField field = fields.getField(HttpHeader.LOCATION); + return getTokenFromUrl(field.getValue()); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + logger.warn("Auth Exception: {}", e.getMessage()); + } + return new Token(); + } + + public Token getTokenFromUrl(String encodedUrl) { + MultiMap tokenMap = new MultiMap(); + UrlEncoded.decodeTo(encodedUrl, tokenMap, StandardCharsets.US_ASCII); + final Token token = new Token(); + tokenMap.forEach((key, value) -> { + logger.info("Key {} Value {}", key, value); + if (key.endsWith(ACCESS_TOKEN)) { + token.setToken(value.get(0).toString()); + } else if (key.equals(EXPIRES_IN)) { + logger.info("Expires {}", value.get(0).toString()); + token.setExpiration(Integer.parseInt(value.get(0).toString())); + } else if (key.equals(TOKEN_TYPE)) { + token.setType(value.get(0).toString()); + } + }); + return token; + } + + public void close() { + discoveryServiceRegstration.unregister(); + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDrivePortalHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDrivePortalHandler.java deleted file mode 100644 index d2bbcf8892a08..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDrivePortalHandler.java +++ /dev/null @@ -1,155 +0,0 @@ -/** - * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; - -import static org.openhab.binding.bmwconnecteddrive.internal.handler.HTTPConstants.*; - -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -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.client.util.StringContentProvider; -import org.eclipse.jetty.http.HttpField; -import org.eclipse.jetty.http.HttpFields; -import org.eclipse.jetty.http.HttpHeader; -import org.eclipse.jetty.util.MultiMap; -import org.eclipse.jetty.util.UrlEncoded; -import org.openhab.binding.bmwconnecteddrive.internal.ConnectedCarConfiguration; -import org.openhab.binding.bmwconnecteddrive.internal.dto.CarData; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * The {@link ConnectedDrivePortalHandler} Deals with the Authorization & Communication for one specific Car and the BMW - * Connected Drive Portal - * - * @author Bernd Weymann - Initial contribution - */ -@NonNullByDefault -public class ConnectedDrivePortalHandler { - private final Logger logger = LoggerFactory.getLogger(ConnectedDrivePortalHandler.class); - private final HttpClient httpClient; - private final Token token = new Token(); - private @Nullable ConnectedCarConfiguration configuration; - private @Nullable String vehicleAPI; - - public ConnectedDrivePortalHandler(HttpClient hc) { - httpClient = hc; - httpClient.setFollowRedirects(false); - } - - public void initialize(ConnectedCarConfiguration config) { - configuration = config; - vehicleAPI = "https://" + BimmerConstants.SERVER_MAP.get(configuration.region) - + "/api/vehicle/dynamic/v1/" + configuration.vin + "?offset=-60"; - logger.info("Vehicle API set to {}", vehicleAPI); - - // r = requests.get(self.vehicleApi+'/dynamic/v1/'+self.bmwVin+'?offset=-60', - // headers=headers,allow_redirects=True) - } - - /** - * Authorize at BMW Connected Drive Portal and re - * - * @return - */ - void auth() { - String uri = "https://customer.bmwgroup.com/gcdm/oauth/authenticate"; - Request req = httpClient.POST(uri); - - req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); - req.header(HttpHeader.CONNECTION, KEEP_ALIVE); - req.header(HttpHeader.HOST, BimmerConstants.SERVER_MAP.get(configuration.region)); - req.header(HttpHeader.AUTHORIZATION, BimmerConstants.AUTHORIZATION_VALUE); - req.header(CREDENTIALS, BimmerConstants.CREDENTIAL_VALUES); - - MultiMap map = new MultiMap(); - map.add(CLIENT_ID, BimmerConstants.CLIENT_ID_VALUE); - map.add(RESPONSE_TYPE, TOKEN); - map.add(REDIRECT_URI, BimmerConstants.REDIRECT_URI_VALUE); - map.add(SCOPE, BimmerConstants.SCOPE_VALUES); - map.add(USERNAME, configuration.userName); - map.add(PASSWORD, configuration.password); - String urlEncodedData = UrlEncoded.encode(map, Charset.defaultCharset(), false); - - logger.info("URL encoded data {}", urlEncodedData); - logger.info("Data size {} ", urlEncodedData.length()); - req.header("Content-Length", urlEncodedData.length() + ""); - req.content(new StringContentProvider(urlEncodedData)); - try { - ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); - logger.info("Status {} ", contentResponse.getStatus()); - logger.info("Reason {} ", contentResponse.getReason()); - logger.info("Encoding {} ", contentResponse.getEncoding()); - logger.info("Content length {} ", contentResponse.getContent().length); - logger.info("Media Type {} ", contentResponse.getMediaType()); - HttpFields fields = contentResponse.getHeaders(); - HttpField field = fields.getField(HttpHeader.LOCATION); - storeToken(field.getValue(), token); - // - // for (int i = 0; i < fields.size(); i++) { - // HttpField field = fields.getField(i); - // logger.info("Field {}, Name {}, Value {}", i, field.getName(), field.getValue()); - // } - // String content = contentResponse.getContentAsString(); - // logger.info("Auth response: {}", content); - } catch (InterruptedException | ExecutionException | TimeoutException e) { - logger.warn("Auth Exception: {}", e.getMessage()); - } - } - - public void storeToken(String urlEncoded, Token t) { - MultiMap map = new MultiMap(); - UrlEncoded.decodeTo(urlEncoded, map, StandardCharsets.US_ASCII); - map.forEach((key, value) -> { - logger.info("Key {} Value {}", key, value); - if (key.endsWith(ACCESS_TOKEN)) { - t.setToken(value.get(0).toString()); - } else if (key.equals(EXPIRES_IN)) { - logger.info("Expires {}", value.get(0).toString()); - t.setExpiration(Integer.parseInt(value.get(0).toString())); - } else if (key.equals(TOKEN_TYPE)) { - t.setType(value.get(0).toString()); - } - }); - } - - public @Nullable CarData getData() { - if (token.isExpired()) { - auth(); - if (token.isExpired()) { - return null; - } - } - Request req = httpClient.newRequest(vehicleAPI); - - req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); - req.header(HttpHeader.AUTHORIZATION, token.getToken()); - try { - ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); - logger.info("Status {}", contentResponse.getStatus()); - logger.info("Reason {}", contentResponse.getReason()); - logger.info("Reason {}", contentResponse.getContentAsString()); - } catch (InterruptedException | TimeoutException | ExecutionException e) { - logger.warn("Get Data Exception {}", e.getMessage()); - } - return null; - } -} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java index 1706b7cf8785e..91b769ce37b71 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java @@ -21,11 +21,12 @@ */ @NonNullByDefault public class Token { - private String token = ""; - private String tokenType = ""; + private static final String EMPTY = ""; + private String token = EMPTY; + private String tokenType = EMPTY; private long expiration = 0; - public String getToken() { + public String getBearerToken() { return tokenType + " " + token; } @@ -44,4 +45,8 @@ public boolean isExpired() { public void setType(String type) { tokenType = type; } + + public boolean isValid() { + return (!token.equals(EMPTY) && !tokenType.equals(EMPTY) && expiration > 0); + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/binding/binding.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/binding/binding.xml index a46634ca63664..bb1d905db4e35 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/binding/binding.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/binding/binding.xml @@ -3,7 +3,7 @@ xmlns:binding="https://openhab.org/schemas/binding/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd"> - BMW Connected Car + BMW ConnectedDrive Provides access to your Car via BMW Connected Drive Portal Bernd Weymann diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-connected-car.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml similarity index 53% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-connected-car.xml rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml index f1c99b8d0f0e0..fa508d7a95f1c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-connected-car.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml @@ -5,12 +5,13 @@ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - - - Car associated with the BMW Connected Drive Portal + + + Access to BMW ConnectedDrive Portal for a specific user - + + @@ -22,33 +23,29 @@ BMW Connected Drive Password - - - BMW Car VIN - - - Based on your location the appropriate BMW Server needs to be connected - Rest of the World + + Select your Region in order to connect to the appropriate BMW Server - - - - Data Refresh Rate for your Car values - 15 + Rest of the World - + - - - bmwconnecteddriveItem - - Sample channel for BMWConnectedDrive Binding + + Switch + + Forcing an update of the ConnectedDrive data. Useful if e.g. user has a new car connected / removed from + his Account + + + Switch + + Forcing a log entry with needed data needed for problem analysis diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-range-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-range-channel-groups.xml new file mode 100644 index 0000000000000..b987b64468f98 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-range-channel-groups.xml @@ -0,0 +1,19 @@ + + + + + Provides range, state of charge and fuel values + + + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-groups.xml new file mode 100644 index 0000000000000..88a4b11421ee0 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-groups.xml @@ -0,0 +1,14 @@ + + + + + Provides an Image of your Car based on the given View direction + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml new file mode 100644 index 0000000000000..3c71f20bb881e --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml @@ -0,0 +1,27 @@ + + + + Image + + + + trigger + + + + + + + + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-groups.xml new file mode 100644 index 0000000000000..cd6e0da2fa873 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-groups.xml @@ -0,0 +1,13 @@ + + + + + Provides values for the current Car Status, Electric charging state, remaining Range and more + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml new file mode 100644 index 0000000000000..279f375b86b4b --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml @@ -0,0 +1,34 @@ + + + + Number + + + + Number + + + + Number + + + + Number:Dimensionless + + + + Number + + + + Number:Dimensionless + + + + String + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml new file mode 100644 index 0000000000000..803ac09150592 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml @@ -0,0 +1,32 @@ + + + + + + + + + + Car associated with the BMW Connected Drive Portal + + + + + + + + + + BMW Car VIN + + + + Data Refresh Rate for your Car values + 5 + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BEV_REX_VehcileValues.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BEV_REX_VehcileValues.java new file mode 100644 index 0000000000000..bc9b7710885ff --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BEV_REX_VehcileValues.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; + +import static org.junit.Assert.assertEquals; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.junit.Test; +import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; + +import com.google.gson.Gson; + +/** + * The {@link BEV_REX_VehcileValues} Test json responses from ConnectedDrive Portal + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class BEV_REX_VehcileValues { + private static final Gson GSON = new Gson(); + + @Test + public void testtestBEV_REX_Values() { + String resource1 = FileReader.readFileInString("src/test/resources/vehicle.json"); + BevRexAttributesMap attributesMap = GSON.fromJson(resource1, BevRexAttributesMap.class); + BevRexAttributes attributes = attributesMap.attributesMap; + System.out.println("Mileage " + attributes.mileage); + assertEquals("Mileage", 17236.0, attributes.mileage, 0.1); + System.out.println(attributes.beRemainingRangeFuel); + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java new file mode 100644 index 0000000000000..21b635c58bfd3 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.smarthome.core.thing.ThingTypeUID; +import org.junit.Test; +import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; + +import com.google.gson.Gson; + +/** + * The {@link ConnectedDriveTest} Test json responses from ConnectedDrive Portal + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class ConnectedDriveTest { + private static final Gson GSON = new Gson(); + + @Test + public void testUserInfo() { + String resource1 = FileReader.readFileInString("src/test/resources/connected-drive-account-info.json"); + ConnectedDriveUserInfo userInfo = GSON.fromJson(resource1, ConnectedDriveUserInfo.class); + List vehicles = userInfo.getVehicles(); + assertEquals("Number of Vehicles", 1, vehicles.size()); + Vehicle v = vehicles.get(0); + // assertEquals("VIN", "WBY1Z81040V905639", v.getVin()); + // assertEquals("Model", "i3 94 (+ REX)", v.getModel()); + // assertEquals("DriveTrain", "BEV_REX", v.getDriveTrain()); + // assertEquals("Brand", "BMW_I", v.getBrand()); + // assertEquals("Year of Construction", 2017, v.getYearOfConstruction()); + // System.out.println(v.getDealer()); + // System.out.println(v.getBodytype()); + // System.out.println(v.getSupportedServices()); + // System.out.println(v.getNotSupportedServices()); + // System.out.println(v.getActivatedServices()); + // System.out.println(v.getNotActivatedServices()); + } + + @Test + public void testChannelUID() { + ThingTypeUID THING_TYPE_PHEV = new ThingTypeUID("bmwconnecteddrive", "plugin-hybrid-car"); + assertEquals("Car Type", "plugin-hybrid-car", THING_TYPE_PHEV.getId()); + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java index b59277d033e62..10862b01465b5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java @@ -13,23 +13,13 @@ package org.openhab.binding.bmwconnecteddrive.internal.handler; import static org.junit.Assert.assertEquals; - -import java.nio.charset.Charset; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; +import static org.mockito.Mockito.mock; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.AuthenticationStore; -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.client.api.Request; -import org.eclipse.jetty.client.util.StringContentProvider; -import org.eclipse.jetty.http.HttpField; -import org.eclipse.jetty.http.HttpFields; -import org.eclipse.jetty.util.MultiMap; -import org.eclipse.jetty.util.UrlEncoded; +import org.eclipse.smarthome.core.thing.Bridge; import org.junit.Test; +import org.osgi.framework.BundleContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,93 +33,13 @@ public class AuthTest { private final Logger logger = LoggerFactory.getLogger(ConnectedCarHandler.class); - @Test - public void test() { - HttpClient httpClient = new HttpClient(); - try { - httpClient.start(); - } catch (Exception e1) { - // TODO Auto-generated catch block - // e1.printStackTrace(); - } - String uri = "https://customer.bmwgroup.com/gcdm/oauth/authenticate"; - Request req = httpClient.POST(uri); - AuthenticationStore authStore = httpClient.getAuthenticationStore(); - // Authentication a = new Authentication(); - - // "Content-Type": "application/x-www-form-urlencoded", - // "Content-Length": "124", - // "Connection": "Keep-Alive", - // "Host": self.serverUrl, - // "Accept-Encoding": "gzip", - // "Authorization": "Basic blF2NkNxdHhKdVhXUDc0eGYzQ0p3VUVQOjF6REh4NnVuNGNEanli" - // "TEVOTjNreWZ1bVgya0VZaWdXUGNRcGR2RFJwSUJrN3JPSg==", - // "Credentials": "nQv6CqtxJuXWP74xf3CJwUEP:1zDHx6un4cDjybLENN3kyfumX2kEYigWPcQpdvDRpIBk7rOJ", - // "User-Agent": "okhttp/2.60", - req.header("Content-Type", "application/x-www-form-urlencoded"); - req.header("Connection", "Keep-Alive"); - req.header("Host", "b2vapi.bmwgroup.com"); - req.header("Authorization", - "Basic blF2NkNxdHhKdVhXUDc0eGYzQ0p3VUVQOjF6REh4NnVuNGNEanliTEVOTjNreWZ1bVgya0VZaWdXUGNRcGR2RFJwSUJrN3JPSg=="); - req.header("Credentials", "nQv6CqtxJuXWP74xf3CJwUEP:1zDHx6un4cDjybLENN3kyfumX2kEYigWPcQpdvDRpIBk7rOJ"); - - // 'client_id': 'dbf0a542-ebd1-4ff0-a9a7-55172fbfce35', - // 'response_type': 'token', - // 'redirect_uri': 'https://www.bmw-connecteddrive.com/app/static/external-dispatch.html', - // 'scope': 'authenticate_user vehicle_data remote_services', - // 'username': self.bmwUsername, - // 'password': self.bmwPassword - - String data = " {'client_id': 'dbf0a542-ebd1-4ff0-a9a7-55172fbfce35'," + " 'response_type': 'token'," - + " 'redirect_uri': 'https://www.bmw-connecteddrive.com/app/static/external-dispatch.html'," - + " 'scope': 'authenticate_user vehicle_data remote_services'," - + " 'username': 'marika.weymann@gmail.com'," + " 'password': 'P4nd4b3r'}"; - MultiMap map = new MultiMap(); - map.add("client_id", "dbf0a542-ebd1-4ff0-a9a7-55172fbfce35"); - map.add("response_type", "token"); - map.add("redirect_uri", "https://www.bmw-connecteddrive.com/app/static/external-dispatch.html"); - map.add("scope", "authenticate_user vehicle_data remote_services"); - map.add("username", "marika.weymann@gmail.com"); - map.add("password", "P4nd4b3r"); - String urlEncodedData = UrlEncoded.encode(map, Charset.defaultCharset(), false); - logger.info("URL encoded data {}", urlEncodedData); - logger.info("Data size {} ", urlEncodedData.length()); - req.header("Content-Length", urlEncodedData.length() + ""); - req.content(new StringContentProvider(urlEncodedData)); - try { - ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); - logger.info("Status {} ", contentResponse.getStatus()); - logger.info("Reason {} ", contentResponse.getReason()); - logger.info("Encoding {} ", contentResponse.getEncoding()); - logger.info("Content length {} ", contentResponse.getContent().length); - logger.info("Media Type {} ", contentResponse.getMediaType()); - HttpFields fields = contentResponse.getHeaders(); - for (int i = 0; i < fields.size(); i++) { - HttpField field = fields.getField(i); - logger.info("Field {}, Name {}, Value {}", i, field.getName(), field.getValue()); - } - String content = contentResponse.getContentAsString(); - logger.info("Auth response: {}", content); - } catch (InterruptedException | ExecutionException | TimeoutException e) { - logger.info("Auth Exception: {}", e.getMessage()); - // e.printStackTrace(); - } - try { - httpClient.stop(); - } catch (Exception e) { - // TODO Auto-generated catch block - // e.printStackTrace(); - } - httpClient.destroy(); - } - @Test public void testTokenDecoding() { - Token t = new Token(); - ConnectedDrivePortalHandler cdpHandler = new ConnectedDrivePortalHandler(new HttpClient()); + Bridge b = mock(Bridge.class); + ConnectedDriveBridgeHandler cdbh = new ConnectedDriveBridgeHandler(b, new HttpClient(), + mock(BundleContext.class)); String headerValue = "https://www.bmw-connecteddrive.com/app/static/external-dispatch.html#access_token=SfXKgkEXeeFJkVqdD4XMmfUU224MRuyh&token_type=Bearer&expires_in=7199"; - MultiMap map = new MultiMap(); - cdpHandler.storeToken(headerValue, t); - assertEquals("Token", "Bearer SfXKgkEXeeFJkVqdD4XMmfUU224MRuyh", t.getToken()); + Token t = cdbh.getTokenFromUrl(headerValue); + assertEquals("Token", "Bearer SfXKgkEXeeFJkVqdD4XMmfUU224MRuyh", t.getBearerToken()); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/FileReader.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/FileReader.java new file mode 100644 index 0000000000000..d806270cb76b4 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/FileReader.java @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.util; + +import static org.junit.Assert.assertTrue; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * The {@link FileReader} Helper Util to read test resource files + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class FileReader { + + public static @Nullable String readFileInString(String filename) { + try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filename), "CP1252"));) { + StringBuffer buf = new StringBuffer(); + String sCurrentLine; + + while ((sCurrentLine = br.readLine()) != null) { + buf.append(sCurrentLine); + } + return buf.toString(); + } catch (IOException e) { + // fail if file cannot be read + assertTrue(false); + } + return null; + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/connected-drive-account-info.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/connected-drive-account-info.json new file mode 100644 index 0000000000000..91674a046db1e --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/connected-drive-account-info.json @@ -0,0 +1,63 @@ +{ + "vehicles": [ + { + "vin": "WBY1Z81040V905639", + "model": "i3 94 (+ REX)", + "bodytype": "I01", + "driveTrain": "BEV_REX", + "color": "CAPPARISWEISS MIT AKZENT BMW I BLAU", + "colorCode": "B85", + "brand": "BMW_I", + "yearOfConstruction": 2017, + "statisticsCommunityEnabled": false, + "statisticsAvailable": true, + "hub": "HUB_ECE", + "hasAlarmSystem": true, + "dealer": { + "name": "Andreas Ehrl Potsdam GmbH & Co. KG", + "street": "Fritz-Zubeil-Str. 95", + "postalCode": "14482", + "city": "Potsdam", + "country": "DE", + "phone": "+49 331 888888" + }, + "breakdownNumber": "+4989358957103", + "countryCode": "V6", + "egoVehiclePath": "", + "chargingUpdateMode": "NORMAL_PROGNOSE_BASED", + "steering": "LH", + "vehicleFinderRestriction": "NONE", + "hmiVersion": "ID4", + "a4a": "USB_ONLY", + "vehicleFinder": "ACTIVATED", + "remote360": "NOT_SUPPORTED", + "hornBlow": "ACTIVATED", + "lightFlash": "ACTIVATED", + "doorLock": "ACTIVATED", + "doorUnlock": "ACTIVATED", + "climateControl": "NOT_SUPPORTED", + "climateNow": "ACTIVATED", + "climateNowRES": "NOT_SUPPORTED", + "climateControlRES": "NOT_SUPPORTED", + "chargingControl": "WEEKLY_PLANNER", + "chargeNow": "NOT_SUPPORTED", + "sendPoi": "ACTIVATED", + "rangeMap": "RANGE_CIRCLE", + "lastDestinations": "SUPPORTED", + "intermodalRouting": "NOT_AVAILABLE", + "climateFunction": "AIRCONDITIONING", + "onlineSearchMode": "MAP", + "onlineSearchProvider": "GOOGLE", + "smartSolution": "NOT_SUPPORTED", + "carCloud": "NOT_SUPPORTED", + "supportedChargingModes": [ + "AC_LOW", + "DC" + ], + "lscType": "I_LSC_IMM", + "ipa": "NOT_SUPPORTED", + "puStep": "1119", + "remoteSoftwareUpgrade": "NOT_SUPPORTED" + } + ] +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/efficiency.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/efficiency.json new file mode 100644 index 0000000000000..227dabe5c20b9 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/efficiency.json @@ -0,0 +1,85 @@ +Efficiency { + "communitySwitch": false, + "modelType": "I3", + "scoreList": [ + { + "attrName": "AVERAGE_ELECTRIC_CONSUMPTION", + "attrUnit": "KWH_PER_100KM", + "minValue": 0.0, + "maxValue": 40.0, + "lifeTime": 16.5 + }, + { + "attrName": "AVERAGE_RECUPERATED_ENERGY_PER_100_KM", + "attrUnit": "KWH_PER_100KM", + "minValue": 0.0, + "maxValue": 20.0, + "lifeTime": 4.5 + }, + { + "attrName": "CUMULATED_ELECTRIC_DRIVEN_DISTANCE", + "attrUnit": "KM", + "minValue": 0.0, + "maxValue": 16593.4, + "lifeTime": 16592.4 + }, + { + "attrName": "LONGEST_DISTANCE_WITHOUT_CHARGING", + "attrUnit": "KM", + "minValue": 0.0, + "maxValue": 270.0, + "lifeTime": 185.5 + } + ], + "lastTripList": [ + { + "name": "LASTTRIP_DELTA_KM", + "unit": "KM", + "lastTrip": "2.0" + }, + { + "name": "ACTUAL_DISTANCE_WITHOUT_CHARGING", + "unit": "KM", + "lastTrip": "31.0" + }, + { + "name": "AVERAGE_ELECTRIC_CONSUMPTION", + "unit": "KWH_PER_100KM", + "lastTrip": "14.5" + }, + { + "name": "AVERAGE_RECUPERATED_ENERGY_PER_100_KM", + "unit": "KWH_PER_100KM", + "lastTrip": "8.0" + }, + { + "name": "CUMULATED_ELECTRIC_DRIVEN_DISTANCE", + "unit": "KM", + "lastTrip": "16592.4" + } + ], + "lifeTimeList": [], + "efficiencyQuotient": 44, + "characteristicList": [ + { + "characteristic": "TOTAL_CONSUMPTION", + "quantity": 2 + }, + { + "characteristic": "AUXILIARY_CONSUMPTION", + "quantity": 2 + }, + { + "characteristic": "DRIVING_MODE", + "quantity": 0 + }, + { + "characteristic": "ACCELERATION", + "quantity": 3 + }, + { + "characteristic": "ANTICIPATION", + "quantity": 3 + } + ] +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/navigation.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/navigation.json new file mode 100644 index 0000000000000..54cbb6c82185c --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/navigation.json @@ -0,0 +1,12 @@ +{ + "latitude": 50.556164, + "longitude": 8.495482, + "isoCountryCode": "DEU", + "auxPowerRegular": 1.4, + "auxPowerEcoPro": 1.2, + "auxPowerEcoProPlus": 0.4, + "soc": 25.952999114990234, + "pendingUpdate": false, + "vehicleTracking": true, + "socmax": 29.84 +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/test.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/test.json similarity index 98% rename from bundles/org.openhab.binding.bmwconnecteddrive/test.json rename to bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/test.json index 64fdbd3784cef..d04e75423052f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/test.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/test.json @@ -37,10 +37,10 @@ "chargingSystemStatus": "CHARGINGACTIVE", "fuelPercent": "47", "unitOfCombustionConsumption": "l/100km", - "gps_lat": "50.556034", + "gps_lat": "xxx", "window_driver_front": "CLOSED", "Segment_LastTrip_ratio_electric_driven_distance": "100", - "gps_lng": "8.49561", + "gps_lng": "xxx", "condition_based_services": "00003,OK,2021-11,;00017,OK,2021-11,;00001,OK,2021-11,;00032,OK,2021-11,", "window_passenger_front": "CLOSED", "window_passenger_rear": "CLOSED", diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/vehicle.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/vehicle.json new file mode 100644 index 0000000000000..7f160ad90e45b --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/vehicle.json @@ -0,0 +1,108 @@ +{ + "attributesMap": { + "unitOfLength": "km", + "sunroof_state": "CLOSED", + "chargingLogicCurrentlyActive": "NOT_CHARGING", + "vehicle_tracking": "1", + "chargeNowAllowed": "NOT_ALLOWED", + "updateTime_converted": "22.08.2020 13:55", + "door_driver_rear": "CLOSED", + "head_unit_pu_software": "07/16", + "beMaxRangeElectricKm": "209.0", + "door_passenger_rear": "CLOSED", + "beRemainingRangeFuelKm": "67.0", + "Segment_LastTrip_time_segment_end_formatted_date": "22.08.2020", + "door_driver_front": "CLOSED", + "shdStatusUnified": "CLOSED", + "hood_state": "CLOSED", + "charging_status": "NOCHARGING", + "kombi_current_remaining_range_fuel": "67.0", + "beMaxRangeElectric": "209.0", + "window_driver_rear": "CLOSED", + "beRemainingRangeElectricKm": "179.0", + "mileage": "17236", + "Segment_LastTrip_time_segment_end_formatted_time": "14:52", + "beMaxRangeElectricMile": "129.0", + "Segment_LastTrip_time_segment_end_formatted": "22.08.2020 14:52", + "lastChargingEndResult": "SUCCESS", + "check_control_messages": "", + "unitOfEnergy": "kWh", + "beRemainingRangeElectric": "179.0", + "sunroof_position": "0", + "soc_hv_percent": "82.6", + "single_immediate_charging": "isUnused", + "updateTime_converted_time": "13:55", + "chargingHVStatus": "INVALID", + "connectorStatus": "DISCONNECTED", + "chargingLevelHv": "89.0", + "chargingSystemStatus": "NOCHARGING", + "fuelPercent": "47", + "unitOfCombustionConsumption": "l/100km", + "gps_lat": "50.556164", + "window_driver_front": "CLOSED", + "Segment_LastTrip_ratio_electric_driven_distance": "100", + "gps_lng": "8.495482", + "condition_based_services": "00003,OK,2021-11,;00017,OK,2021-11,;00001,OK,2021-11,;00032,OK,2021-11,", + "window_passenger_front": "CLOSED", + "window_passenger_rear": "CLOSED", + "lastChargingEndReason": "CHARGING_GOAL_REACHED", + "updateTime_converted_date": "22.08.2020", + "beRemainingRangeFuelMile": "41.0", + "beRemainingRangeFuel": "67.0", + "door_passenger_front": "CLOSED", + "updateTime_converted_timestamp": "1598104546000", + "remaining_fuel": "4", + "charging_inductive_positioning": "not_positioned", + "heading": "41", + "lsc_trigger": "VEHCSHUTDOWN_SECURED", + "lights_parking": "OFF", + "door_lock_state": "SECURED", + "updateTime": "22.08.2020 12:55:46 UTC", + "prognosisWhileChargingStatus": "NOT_NEEDED", + "head_unit": "EntryNav", + "trunk_state": "CLOSED", + "battery_size_max": "33200", + "charging_connection_type": "CONDUCTIVE", + "beRemainingRangeElectricMile": "111.0", + "unitOfElectricConsumption": "kWh/100km", + "Segment_LastTrip_time_segment_end": "22.08.2020 14:52:00 UTC", + "lastUpdateReason": "VEHCSHUTDOWN_SECURED" + }, + "vehicleMessages": { + "ccmMessages": [], + "cbsMessages": [ + { + "description": "Nächster Wechsel spätestens zum angegebenen Termin.", + "text": "Bremsflüssigkeit", + "id": 3, + "status": "OK", + "messageType": "CBS", + "date": "2021-11" + }, + { + "description": "Nächste Sichtprüfung nach der angegebenen Fahrstrecke oder zum angegebenen Termin.", + "text": "Fahrzeug-Check", + "id": 17, + "status": "OK", + "messageType": "CBS", + "date": "2021-11" + }, + { + "description": "Nächster Wechsel nach der angegebenen Fahrstrecke oder zum angegebenen Termin.", + "text": "Motoröl", + "id": 1, + "status": "OK", + "messageType": "CBS", + "date": "2021-11" + }, + { + "description": "Nächste gesetzliche Fahrzeuguntersuchung zum angegebenen Termin.", + "text": "§ Fahrzeuguntersuchung", + "id": 32, + "status": "OK", + "messageType": "CBS", + "date": "2021-11" + } + ] + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi-status.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi-status.json new file mode 100644 index 0000000000000..c206df971941e --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi-status.json @@ -0,0 +1,76 @@ +{ + "vehicleStatus": { + "vin": "WBY1Z81040V905639", + "mileage": 17131, + "updateReason": "VEHICLE_SECURED", + "updateTime": "2020-08-18T17:54:12+0000", + "doorDriverFront": "CLOSED", + "doorDriverRear": "CLOSED", + "doorPassengerFront": "CLOSED", + "doorPassengerRear": "CLOSED", + "windowDriverFront": "CLOSED", + "windowDriverRear": "CLOSED", + "windowPassengerFront": "CLOSED", + "windowPassengerRear": "CLOSED", + "sunroof": "CLOSED", + "trunk": "CLOSED", + "rearWindow": "INVALID", + "hood": "CLOSED", + "doorLockState": "SECURED", + "parkingLight": "OFF", + "positionLight": "ON", + "remainingFuel": 4, + "remainingRangeElectric": 184, + "remainingRangeElectricMls": 114, + "remainingRangeFuel": 72, + "remainingRangeFuelMls": 44, + "maxRangeElectric": 224, + "maxRangeElectricMls": 139, + "maxFuel": 8.5, + "connectionStatus": "DISCONNECTED", + "chargingStatus": "INVALID", + "chargingLevelHv": 84, + "lastChargingEndReason": "END_REQUESTED_BY_DRIVER", + "lastChargingEndResult": "SUCCESS", + "position": { + "lat": 50.55603, + "lon": 8.4956, + "heading": 41, + "status": "OK" + }, + "internalDataTimeUTC": "2020-08-18T17:54:12", + "singleImmediateCharging": false, + "chargingConnectionType": "CONDUCTIVE", + "chargingInductivePositioning": "NOT_POSITIONED", + "vehicleCountry": "DE", + "checkControlMessages": [], + "cbsData": [ + { + "cbsType": "BRAKE_FLUID", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next change due at the latest by the stated date." + }, + { + "cbsType": "VEHICLE_CHECK", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next visual inspection due when the stated distance has been covered or by the stated date." + }, + { + "cbsType": "OIL", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next change due when the stated distance has been covered or by the specified date." + }, + { + "cbsType": "VEHICLE_TUV", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next statutory vehicle inspection due by the stated date." + } + ], + "DCS_CCH_Activation": "NA", + "DCS_CCH_Ongoing": false + } +} \ No newline at end of file From e4f68c4b03559f70200c592a9033f270f6ac7e47 Mon Sep 17 00:00:00 2001 From: Bernd Date: Sun, 23 Aug 2020 23:13:27 +0200 Subject: [PATCH 004/176] last-trip and lifetime values Signed-off-by: Bernd (cherry picked from commit 35ac78874620aafee52355cfd2512736517a9990) Signed-off-by: Bernd --- .../internal/ConnectedDriveConstants.java | 14 ++++ .../dto/efficiency/CharacterristicsScore.java | 42 ++++++++++ .../internal/dto/efficiency/Efficiency.java | 30 +++++++ .../internal/dto/efficiency/Score.java | 59 +++++++++++++ .../internal/dto/efficiency/TripEntry.java | 57 +++++++++++++ .../handler/ConnectedCarChannelHandler.java | 26 ++++++ .../internal/handler/ConnectedCarHandler.java | 82 +++++++++++++++++++ .../thing/ev-last-trip-channel-types.xml | 22 +++++ .../ESH-INF/thing/ev-last-trip-groups.xml | 16 ++++ .../thing/ev-lifetime-channel-types.xml | 22 +++++ .../ESH-INF/thing/ev-lifetime-groups.xml | 16 ++++ .../ESH-INF/thing/range-channel-types.xml | 8 +- .../resources/ESH-INF/thing/thing-bev_rex.xml | 2 + .../thing/troubleshoot-channel-groups.xml | 13 +++ .../thing/troubleshoot-channel-types.xml | 10 +++ ...cileValues.java => BevRexVehicleTest.java} | 4 +- .../internal/dto/EfficiencyTest.java | 82 +++++++++++++++++++ .../src/test/resources/efficiency.json | 2 +- 18 files changed, 500 insertions(+), 7 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/CharacterristicsScore.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/Efficiency.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/Score.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/TripEntry.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-channel-types.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-groups.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-channel-types.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-groups.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-groups.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml rename bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/{BEV_REX_VehcileValues.java => BevRexVehicleTest.java} (91%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/EfficiencyTest.java diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 0d22069a83c17..06b9825e995d9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -83,10 +83,13 @@ public String toString() { // Bridge Channels public static final String DISCOVERY_TRIGGER = "discovery-trigger"; public static final String DISCOVERY_FINGERPRINT = "discovery-fingerprint"; + public static final String CARDATA_FINGERPRINT = "cardata-fingerprint"; // Group definitions public static final String CHANNEL_GROUP_PROPERTIES = "properties"; public static final String CHANNEL_GROUP_RANGE = "range"; + public static final String CHANNEL_GROUP_LIFETIME = "lifetime"; + public static final String CHANNEL_GROUP_LAST_TRIP = "last-trip"; public static final String CHANNEL_GROUP_CAR_STATUS = "status"; public static final String CHANNEL_GROUP_CAR_IMAGE = "image"; @@ -112,6 +115,7 @@ public String toString() { public static final String IMAGE_SIZE = "size"; public static final String IMAGE_VIEW_DIRECTION = "view-direction"; + // Range public static final String MILEAGE = "mileage"; public static final String REMAINING_RANGE = "remaining-range"; public static final String REMAINING_RANGE_ELECTRIC = "remaining-range-electric"; @@ -119,4 +123,14 @@ public String toString() { public static final String REMAINING_RANGE_FUEL = "remaining-range-fuel"; public static final String REMAINING_FUEL = "remaining-fuel"; public static final String LAST_UPDATE = "last-update"; + + // Lifetime + public static final String AVG_CONSUMPTION = "average-consumption"; + public static final String AVG_RECUPERATION = "average-recuperation"; + public static final String CUMULATED_DRIVEN_DISTANCE = "cumulated-driven-distance"; + public static final String SINGLE_LONGEST_DISTANCE = "single-longest-distance"; + + // Last Trip + public static final String DISTANCE = "distance"; + public static final String DISTANCE_SINCE_CHARGING = "distance-since-charging"; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/CharacterristicsScore.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/CharacterristicsScore.java new file mode 100644 index 0000000000000..c2c1a70d555b1 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/CharacterristicsScore.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.efficiency; + +/** + * The {@link CharacterristicsScore} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class CharacterristicsScore { + public String characteristic; + public int quantity; + // "characteristic": "TOTAL_CONSUMPTION", + // "quantity": 2 + // }, + // { + // "characteristic": "AUXILIARY_CONSUMPTION", + // "quantity": 2 + // }, + // { + // "characteristic": "DRIVING_MODE", + // "quantity": 0 + // }, + // { + // "characteristic": "ACCELERATION", + // "quantity": 3 + // }, + // { + // "characteristic": "ANTICIPATION", + // "quantity": 3 + // } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/Efficiency.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/Efficiency.java new file mode 100644 index 0000000000000..0436fbbdbe955 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/Efficiency.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.efficiency; + +import java.util.List; + +/** + * The {@link Efficiency} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class Efficiency { + public boolean communitySwitch;// ": false, + public String modelType; // ": "I3"," + public int efficiencyQuotient; // ": 44, + public List lifeTimeList; // ": [], + public List scoreList; + public List lastTripList; + public List characteristicList; +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/Score.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/Score.java new file mode 100644 index 0000000000000..ad9f7f8a67c61 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/Score.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.efficiency; + +/** + * The {@link Score} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class Score { + public final static String AVERAGE_ELECTRIC_CONSUMPTION = "AVERAGE_ELECTRIC_CONSUMPTION"; + public final static String AVERAGE_RECUPERATED_ENERGY_PER_100_KM = "AVERAGE_RECUPERATED_ENERGY_PER_100_KM"; + public final static String CUMULATED_ELECTRIC_DRIVEN_DISTANCE = "CUMULATED_ELECTRIC_DRIVEN_DISTANCE"; + public final static String LONGEST_DISTANCE_WITHOUT_CHARGING = "LONGEST_DISTANCE_WITHOUT_CHARGING"; + + public String attrName; + public String attrUnit; + public float minValue; + public float maxValue; + public float lifeTime; + // { + // "attrName": "AVERAGE_ELECTRIC_CONSUMPTION", + // "attrUnit": "KWH_PER_100KM", + // "minValue": 0.0, + // "maxValue": 40.0, + // "lifeTime": 16.5 + // }, + // { + // "attrName": "AVERAGE_RECUPERATED_ENERGY_PER_100_KM", + // "attrUnit": "KWH_PER_100KM", + // "minValue": 0.0, + // "maxValue": 20.0, + // "lifeTime": 4.5 + // }, + // { + // "attrName": "CUMULATED_ELECTRIC_DRIVEN_DISTANCE", + // "attrUnit": "KM", + // "minValue": 0.0, + // "maxValue": 16593.4, + // "lifeTime": 16592.4 + // }, + // { + // "attrName": "LONGEST_DISTANCE_WITHOUT_CHARGING", + // "attrUnit": "KM", + // "minValue": 0.0, + // "maxValue": 270.0, + // "lifeTime": 185.5 + // }], +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/TripEntry.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/TripEntry.java new file mode 100644 index 0000000000000..1faec732525be --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/TripEntry.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.efficiency; + +/** + * The {@link TripEntry} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class TripEntry { + public final static String LASTTRIP_DELTA_KM = "LASTTRIP_DELTA_KM"; + public final static String ACTUAL_DISTANCE_WITHOUT_CHARGING = "ACTUAL_DISTANCE_WITHOUT_CHARGING"; + public final static String AVERAGE_ELECTRIC_CONSUMPTION = "AVERAGE_ELECTRIC_CONSUMPTION"; + public final static String AVERAGE_RECUPERATED_ENERGY_PER_100_KM = "AVERAGE_RECUPERATED_ENERGY_PER_100_KM"; + public final static String CUMULATED_ELECTRIC_DRIVEN_DISTANCE = "CUMULATED_ELECTRIC_DRIVEN_DISTANCE"; + + public String name; + public String unit; + public float lastTrip; + // "lastTripList": [ + // { + // "name": "LASTTRIP_DELTA_KM", + // "unit": "KM", + // "lastTrip": "2.0" + // }, + // { + // "name": "ACTUAL_DISTANCE_WITHOUT_CHARGING", + // "unit": "KM", + // "lastTrip": "31.0" + // }, + // { + // "name": "AVERAGE_ELECTRIC_CONSUMPTION", + // "unit": "KWH_PER_100KM", + // "lastTrip": "14.5" + // }, + // { + // "name": "AVERAGE_RECUPERATED_ENERGY_PER_100_KM", + // "unit": "KWH_PER_100KM", + // "lastTrip": "8.0" + // }, + // { + // "name": "CUMULATED_ELECTRIC_DRIVEN_DISTANCE", + // "unit": "KM", + // "lastTrip": "16592.4" + // } + // ], +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java index 49406c9e4943b..62bd7c3282396 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java @@ -56,6 +56,18 @@ public class ConnectedCarChannelHandler extends BaseThingHandler { protected ChannelUID remainingFuel; protected ChannelUID lastUpdate; + // Lifetime Efficiency Channels + protected ChannelUID lifeTimeAverageConsumption; + protected ChannelUID lifeTimeAverageRecuperation; + protected ChannelUID lifeTimeCumulatedDrivenDistance; + protected ChannelUID lifeTimeSingleLongestDistance; + + // Last Trip Channels + protected ChannelUID tripDistance; + protected ChannelUID tripDistanceSinceCharging; + protected ChannelUID tripAvgConsumption; + protected ChannelUID tripAvgRecuperation; + protected ChannelUID imageChannel; protected ChannelUID imageSizeChannel; protected ChannelUID imageViewDirectionChannel; @@ -87,6 +99,7 @@ public ConnectedCarChannelHandler(Thing thing) { PROPERTIES_NOT_SUPPORTED_SERVICES); chargingModesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_CHARGING_MODES); + // range Channels mileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, MILEAGE); remainingRange = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_RANGE); remainingRangeElectric = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_RANGE_ELECTRIC); @@ -95,6 +108,19 @@ public ConnectedCarChannelHandler(Thing thing) { remainingFuel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_FUEL); lastUpdate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, LAST_UPDATE); + // Last Trip Channels + tripDistance = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, DISTANCE); + tripDistanceSinceCharging = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, DISTANCE_SINCE_CHARGING); + tripAvgConsumption = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, AVG_CONSUMPTION); + tripAvgRecuperation = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, AVG_RECUPERATION); + + // Lifetime Channels + lifeTimeAverageConsumption = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, AVG_CONSUMPTION); + lifeTimeAverageRecuperation = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, AVG_RECUPERATION); + lifeTimeCumulatedDrivenDistance = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, + CUMULATED_DRIVEN_DISTANCE); + lifeTimeSingleLongestDistance = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, SINGLE_LONGEST_DISTANCE); + imageChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CAR_IMAGE, IMAGE); imageSizeChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CAR_IMAGE, IMAGE_VIEW_DIRECTION); imageViewDirectionChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CAR_IMAGE, IMAGE_SIZE); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java index 040ac025d589c..777857dda6a15 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java @@ -12,6 +12,7 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.handler; +import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CARDATA_FINGERPRINT; import static org.openhab.binding.bmwconnecteddrive.internal.handler.HTTPConstants.CONTENT_TYPE_JSON; import java.util.concurrent.ExecutionException; @@ -25,6 +26,7 @@ import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.smarthome.core.library.types.OnOffType; import org.eclipse.smarthome.core.library.types.QuantityType; import org.eclipse.smarthome.core.library.types.RawType; import org.eclipse.smarthome.core.library.types.StringType; @@ -43,6 +45,9 @@ import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CarType; import org.openhab.binding.bmwconnecteddrive.internal.dto.BevRexAttributes; import org.openhab.binding.bmwconnecteddrive.internal.dto.BevRexAttributesMap; +import org.openhab.binding.bmwconnecteddrive.internal.dto.efficiency.Efficiency; +import org.openhab.binding.bmwconnecteddrive.internal.dto.efficiency.Score; +import org.openhab.binding.bmwconnecteddrive.internal.dto.efficiency.TripEntry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -66,6 +71,9 @@ public class ConnectedCarHandler extends ConnectedCarChannelHandler { private @Nullable ConnectedDriveBridgeHandler bridgeHandler; protected @Nullable ScheduledFuture refreshJob; + private @Nullable String vehicleFingerprint; + private @Nullable String efficiencyFingerprint; + // Connected Drive APIs private @Nullable String vehicleAPI; private @Nullable String navigationAPI; @@ -83,6 +91,23 @@ public ConnectedCarHandler(Thing thing, HttpClient hc, String type) { @Override public void handleCommand(ChannelUID channelUID, Command command) { + if (channelUID.getIdWithoutGroup().equals(CARDATA_FINGERPRINT)) { + if (command instanceof OnOffType) { + if (command.equals(OnOffType.ON)) { + if (vehicleFingerprint != null) { + logger.warn("BMW ConnectedDrive Binding - Car Data Troubleshoot fingerprint - BEGIN"); + logger.warn("{}", vehicleFingerprint); + logger.warn("{}", efficiencyFingerprint); + logger.warn("BMW ConnectedDrive Binding - Car Data Troubleshoot fingerprint - END"); + } else { + logger.warn( + "BMW ConnectedDrive Binding - No Car Data Troubleshoot fingerprint available. Please check for valid username and password Settings for proper connection towards ConnectDrive"); + } + } + // Switch back to off immediately + updateState(channelUID, OnOffType.OFF); + } + } } @Override @@ -185,6 +210,7 @@ public void getData() { logger.info("Status {}", contentResponse.getStatus()); logger.info("Reason {}", contentResponse.getReason()); logger.info("Efficiency {}", contentResponse.getContentAsString()); + updateEfficiencyStates(contentResponse.getContentAsString()); } catch (InterruptedException | TimeoutException | ExecutionException e) { logger.warn("Get Data Exception {}", e.getMessage()); } @@ -202,6 +228,58 @@ public void getData() { } } + private void updateEfficiencyStates(String content) { + efficiencyFingerprint = content; + if (driveTrain.equals(CarType.ELECTRIC_REX.toString()) || driveTrain.equals(CarType.ELECTRIC.toString())) { + Efficiency eff = GSON.fromJson(content, Efficiency.class); + + if (eff.lastTripList != null) { + eff.lastTripList.forEach(entry -> { + if (entry.name.equals(TripEntry.LASTTRIP_DELTA_KM)) { + logger.info("Update {} with {}", tripDistance.toString(), entry.lastTrip); + updateState(tripDistance, + QuantityType.valueOf(entry.lastTrip, MetricPrefix.KILO(SIUnits.METRE))); + } else if (entry.name.equals(TripEntry.ACTUAL_DISTANCE_WITHOUT_CHARGING)) { + logger.info("Update {} with {}", tripDistanceSinceCharging.toString(), entry.lastTrip); + updateState(tripDistanceSinceCharging, + QuantityType.valueOf(entry.lastTrip, MetricPrefix.KILO(SIUnits.METRE))); + } else if (entry.name.equals(TripEntry.AVERAGE_ELECTRIC_CONSUMPTION)) { + logger.info("Update {} with {}", tripAvgConsumption.toString(), entry.lastTrip); + updateState(tripAvgConsumption, + QuantityType.valueOf(entry.lastTrip, SmartHomeUnits.KILOWATT_HOUR)); + } else if (entry.name.equals(TripEntry.AVERAGE_RECUPERATED_ENERGY_PER_100_KM)) { + logger.info("Update {} with {}", tripAvgRecuperation.toString(), entry.lastTrip); + updateState(tripAvgRecuperation, + QuantityType.valueOf(entry.lastTrip, SmartHomeUnits.KILOWATT_HOUR)); + } + }); + } + if (eff.scoreList != null) { + eff.scoreList.forEach(entry -> { + if (entry.attrName.equals(Score.CUMULATED_ELECTRIC_DRIVEN_DISTANCE)) { + logger.info("Update {} with {}", lifeTimeCumulatedDrivenDistance.toString(), entry.lifeTime); + updateState(lifeTimeCumulatedDrivenDistance, + QuantityType.valueOf(entry.lifeTime, MetricPrefix.KILO(SIUnits.METRE))); + } else if (entry.attrName.equals(Score.LONGEST_DISTANCE_WITHOUT_CHARGING)) { + logger.info("Update {} with {}", lifeTimeSingleLongestDistance.toString(), entry.lifeTime); + updateState(lifeTimeSingleLongestDistance, + QuantityType.valueOf(entry.lifeTime, MetricPrefix.KILO(SIUnits.METRE))); + } else if (entry.attrName.equals(Score.AVERAGE_ELECTRIC_CONSUMPTION)) { + logger.info("Update {} with {}", lifeTimeAverageConsumption.toString(), entry.lifeTime); + updateState(lifeTimeAverageConsumption, + QuantityType.valueOf(entry.lifeTime, SmartHomeUnits.KILOWATT_HOUR)); + } else if (entry.attrName.equals(Score.AVERAGE_RECUPERATED_ENERGY_PER_100_KM)) { + logger.info("Update {} with {}", lifeTimeAverageRecuperation.toString(), entry.lifeTime); + updateState(lifeTimeAverageRecuperation, + QuantityType.valueOf(entry.lifeTime, SmartHomeUnits.KILOWATT_HOUR)); + } + }); + } + } else { + logger.warn("No Efficiency values for {} supported yet", driveTrain); + } + } + private void updateRangeStates(String content) { if (driveTrain.equals(CarType.ELECTRIC_REX.toString())) { BevRexAttributesMap data = GSON.fromJson(content, BevRexAttributesMap.class); @@ -231,7 +309,11 @@ private void updateRangeStates(String content) { updateState(remainingSoc, QuantityType.valueOf(bevRexAttributes.chargingLevelHv, SmartHomeUnits.PERCENT)); updateState(remainingFuel, QuantityType.valueOf(bevRexAttributes.fuelPercent, SmartHomeUnits.PERCENT)); updateState(lastUpdate, new StringType(bevRexAttributes.Segment_LastTrip_time_segment_end_formatted)); + bevRexAttributes.gps_lat = (float) 0.0; + bevRexAttributes.gps_lng = (float) 0.0; + vehicleFingerprint = GSON.toJson(bevRexAttributes); } else { + vehicleFingerprint = content; logger.warn("No update of for {} which {}", driveTrain, CarType.ELECTRIC_REX.toString()); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-channel-types.xml new file mode 100644 index 0000000000000..44451718b62fb --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-channel-types.xml @@ -0,0 +1,22 @@ + + + + Number:Length + + + + Number:Length + + + + Number:Energy + + + + Number:Energy + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-groups.xml new file mode 100644 index 0000000000000..f38e476d70769 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-groups.xml @@ -0,0 +1,16 @@ + + + + + EV Consumption Values and Distances for the Last Trip + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-channel-types.xml new file mode 100644 index 0000000000000..95d1458ae4cd8 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-channel-types.xml @@ -0,0 +1,22 @@ + + + + Number:Energy + + + + Number:Energy + + + + Number:Length + + + + Number:Length + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-groups.xml new file mode 100644 index 0000000000000..794859215b7af --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-groups.xml @@ -0,0 +1,16 @@ + + + + + EV Consumption Values and Distances over Lifetime + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml index 279f375b86b4b..6be20e3a59921 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml @@ -4,15 +4,15 @@ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - Number + Number:Length - Number + Number:Length - Number + Number:Length @@ -20,7 +20,7 @@ - Number + Number:Length diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml index 803ac09150592..73b69f218fcb5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml @@ -14,6 +14,8 @@ + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-groups.xml new file mode 100644 index 0000000000000..d8493cc70d7d9 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-groups.xml @@ -0,0 +1,13 @@ + + + + + EV Consumption Values and Distances over Lifetime + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml new file mode 100644 index 0000000000000..20cdb04babeaf --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml @@ -0,0 +1,10 @@ + + + + Switch + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BEV_REX_VehcileValues.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexVehicleTest.java similarity index 91% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BEV_REX_VehcileValues.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexVehicleTest.java index bc9b7710885ff..236a1df269b45 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BEV_REX_VehcileValues.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexVehicleTest.java @@ -21,12 +21,12 @@ import com.google.gson.Gson; /** - * The {@link BEV_REX_VehcileValues} Test json responses from ConnectedDrive Portal + * The {@link BevRexVehicleTest} Test json responses from ConnectedDrive Portal * * @author Bernd Weymann - Initial contribution */ @NonNullByDefault -public class BEV_REX_VehcileValues { +public class BevRexVehicleTest { private static final Gson GSON = new Gson(); @Test diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/EfficiencyTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/EfficiencyTest.java new file mode 100644 index 0000000000000..b2df28146bf24 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/EfficiencyTest.java @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.junit.Test; +import org.openhab.binding.bmwconnecteddrive.internal.dto.efficiency.CharacterristicsScore; +import org.openhab.binding.bmwconnecteddrive.internal.dto.efficiency.Efficiency; +import org.openhab.binding.bmwconnecteddrive.internal.dto.efficiency.Score; +import org.openhab.binding.bmwconnecteddrive.internal.dto.efficiency.TripEntry; +import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; + +import com.google.gson.Gson; + +/** + * The {@link EfficiencyTest} Test json responses from ConnectedDrive Portal + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class EfficiencyTest { + private static final Gson GSON = new Gson(); + + @Test + public void testtestBEV_REX_Values() { + String resource1 = FileReader.readFileInString("src/test/resources/efficiency.json"); + Efficiency eff = GSON.fromJson(resource1, Efficiency.class); + + assertEquals("Community", false, eff.communitySwitch); + assertEquals("Quotient", 44, eff.efficiencyQuotient); + assertEquals("Model", "I3", eff.modelType); + + List scoreList = eff.scoreList; + assertEquals("Score List", 4, scoreList.size()); + List lastTripList = eff.lastTripList; + assertEquals("Score List", 5, lastTripList.size()); + List characteristicList = eff.characteristicList; + assertEquals("Score List", 5, characteristicList.size()); + + if (eff.lastTripList != null) { + eff.lastTripList.forEach(entry -> { + System.out.println(entry.name + ":" + entry.lastTrip); + if (entry.name.equals(TripEntry.LASTTRIP_DELTA_KM)) { + assertEquals("Trip Delta km", 2, entry.lastTrip, 0.01); + } else if (entry.name.equals(TripEntry.ACTUAL_DISTANCE_WITHOUT_CHARGING)) { + assertEquals("Charge Delta km", 31, entry.lastTrip, 0.01); + } else if (entry.name.equals(TripEntry.AVERAGE_ELECTRIC_CONSUMPTION)) { + assertEquals("Average Consumption", 14.5, entry.lastTrip, 0.01); + } else if (entry.name.equals(TripEntry.AVERAGE_RECUPERATED_ENERGY_PER_100_KM)) { + assertEquals("Average Recuperation", 8.0, entry.lastTrip, 0.01); + } + }); + } + if (eff.scoreList != null) { + eff.scoreList.forEach(entry -> { + if (entry.attrName.equals(Score.CUMULATED_ELECTRIC_DRIVEN_DISTANCE)) { + assertEquals("Trip Delta km", 16592.4, entry.lifeTime, 0.01); + } else if (entry.attrName.equals(Score.LONGEST_DISTANCE_WITHOUT_CHARGING)) { + assertEquals("Trip Delta km", 185.5, entry.lifeTime, 0.01); + } else if (entry.attrName.equals(Score.AVERAGE_ELECTRIC_CONSUMPTION)) { + assertEquals("Average Consumption", 16.5, entry.lifeTime, 0.01); + } else if (entry.attrName.equals(Score.AVERAGE_RECUPERATED_ENERGY_PER_100_KM)) { + assertEquals("Average Recuperation", 4.5, entry.lifeTime, 0.01); + } + }); + } + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/efficiency.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/efficiency.json index 227dabe5c20b9..cf3436c1088b7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/efficiency.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/efficiency.json @@ -1,4 +1,4 @@ -Efficiency { +{ "communitySwitch": false, "modelType": "I3", "scoreList": [ From caf85308b68fda57fdefe601e25324e2f4c8ce7f Mon Sep 17 00:00:00 2001 From: Bernd Date: Mon, 24 Aug 2020 22:18:43 +0200 Subject: [PATCH 005/176] add location group Signed-off-by: Bernd (cherry picked from commit 33b7983c129d5c58513ce364a88733788348dd97) Signed-off-by: Bernd --- .../internal/ConnectedDriveConstants.java | 8 +++ .../handler/ConnectedCarChannelHandler.java | 14 +++++ .../internal/handler/ConnectedCarHandler.java | 61 +++++++++++++++---- .../thing/ev-last-trip-channel-types.xml | 4 +- .../ESH-INF/thing/ev-last-trip-groups.xml | 4 +- .../ESH-INF/thing/ev-lifetime-groups.xml | 6 +- .../ESH-INF/thing/location-channel-groups.xml | 17 ++++++ .../ESH-INF/thing/loction-channel-types.xml | 26 ++++++++ .../resources/ESH-INF/thing/thing-bev_rex.xml | 2 + .../thing/troubleshoot-channel-groups.xml | 2 +- .../thing/troubleshoot-channel-types.xml | 2 +- .../internal/dto/BevRexVehicleTest.java | 3 +- .../internal/dto/EfficiencyTest.java | 2 +- 13 files changed, 128 insertions(+), 23 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/location-channel-groups.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/loction-channel-types.xml diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 06b9825e995d9..b5bd44bce5fba 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -91,6 +91,7 @@ public String toString() { public static final String CHANNEL_GROUP_LIFETIME = "lifetime"; public static final String CHANNEL_GROUP_LAST_TRIP = "last-trip"; public static final String CHANNEL_GROUP_CAR_STATUS = "status"; + public static final String CHANNEL_GROUP_LOCATION = "location"; public static final String CHANNEL_GROUP_CAR_IMAGE = "image"; public static final String PROPERTIES_BRAND = "brand"; @@ -133,4 +134,11 @@ public String toString() { // Last Trip public static final String DISTANCE = "distance"; public static final String DISTANCE_SINCE_CHARGING = "distance-since-charging"; + + // Lifetime + public static final String LONGITUDE = "longitude"; + public static final String LATITUDE = "latitude"; + public static final String LATLONG = "latlong"; + public static final String HEADING = "heading"; + public static final String RANGE_RADIUS = "range-radius"; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java index 62bd7c3282396..2021cf1eab334 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java @@ -68,6 +68,13 @@ public class ConnectedCarChannelHandler extends BaseThingHandler { protected ChannelUID tripAvgConsumption; protected ChannelUID tripAvgRecuperation; + // Location Channels + protected ChannelUID longitude; + protected ChannelUID latitude; + protected ChannelUID latlong; + protected ChannelUID heading; + protected ChannelUID rangeRadius; + protected ChannelUID imageChannel; protected ChannelUID imageSizeChannel; protected ChannelUID imageViewDirectionChannel; @@ -121,6 +128,13 @@ public ConnectedCarChannelHandler(Thing thing) { CUMULATED_DRIVEN_DISTANCE); lifeTimeSingleLongestDistance = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, SINGLE_LONGEST_DISTANCE); + // Location Channels + longitude = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, LONGITUDE); + latitude = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, LATITUDE); + latlong = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, LATLONG); + heading = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, HEADING); + rangeRadius = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, RANGE_RADIUS); + imageChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CAR_IMAGE, IMAGE); imageSizeChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CAR_IMAGE, IMAGE_VIEW_DIRECTION); imageViewDirectionChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CAR_IMAGE, IMAGE_SIZE); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java index 777857dda6a15..bdf4453ea6bf1 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java @@ -12,7 +12,7 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.handler; -import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CARDATA_FINGERPRINT; +import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; import static org.openhab.binding.bmwconnecteddrive.internal.handler.HTTPConstants.CONTENT_TYPE_JSON; import java.util.concurrent.ExecutionException; @@ -26,6 +26,7 @@ import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.smarthome.core.library.types.DecimalType; import org.eclipse.smarthome.core.library.types.OnOffType; import org.eclipse.smarthome.core.library.types.QuantityType; import org.eclipse.smarthome.core.library.types.RawType; @@ -40,7 +41,9 @@ import org.eclipse.smarthome.core.thing.ThingStatus; import org.eclipse.smarthome.core.thing.ThingStatusDetail; import org.eclipse.smarthome.core.thing.binding.BridgeHandler; +import org.eclipse.smarthome.core.thing.binding.ThingHandlerCallback; import org.eclipse.smarthome.core.types.Command; +import org.eclipse.smarthome.core.types.RefreshType; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedCarConfiguration; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CarType; import org.openhab.binding.bmwconnecteddrive.internal.dto.BevRexAttributes; @@ -83,6 +86,9 @@ public class ConnectedCarHandler extends ConnectedCarChannelHandler { private @Nullable String sendMessageAPI; private @Nullable String imageAPI; + private @Nullable String vehicleCache; + private @Nullable String efficiencyCache; + public ConnectedCarHandler(Thing thing, HttpClient hc, String type) { super(thing); httpClient = hc; @@ -91,7 +97,19 @@ public ConnectedCarHandler(Thing thing, HttpClient hc, String type) { @Override public void handleCommand(ChannelUID channelUID, Command command) { + if (command instanceof RefreshType) { + String group = channelUID.getGroupId(); + logger.info("REFRESH {}", group); + if (CHANNEL_GROUP_LAST_TRIP.equals(group) || CHANNEL_GROUP_LAST_TRIP.equals(group)) { + updateEfficiencyStates(efficiencyCache); + } else if (CHANNEL_GROUP_CAR_STATUS.equals(group) || CHANNEL_GROUP_LOCATION.equals(group)) { + updateRangeStates(vehicleCache); + } + } else { + logger.info("No refresh"); + } if (channelUID.getIdWithoutGroup().equals(CARDATA_FINGERPRINT)) { + logger.info("Trigger CarData Fingerprint"); if (command instanceof OnOffType) { if (command.equals(OnOffType.ON)) { if (vehicleFingerprint != null) { @@ -228,7 +246,11 @@ public void getData() { } } - private void updateEfficiencyStates(String content) { + private void updateEfficiencyStates(@Nullable String content) { + if (content == null) { + logger.warn("No Efficiency Values available"); + } + efficiencyCache = content; efficiencyFingerprint = content; if (driveTrain.equals(CarType.ELECTRIC_REX.toString()) || driveTrain.equals(CarType.ELECTRIC.toString())) { Efficiency eff = GSON.fromJson(content, Efficiency.class); @@ -236,19 +258,17 @@ private void updateEfficiencyStates(String content) { if (eff.lastTripList != null) { eff.lastTripList.forEach(entry -> { if (entry.name.equals(TripEntry.LASTTRIP_DELTA_KM)) { - logger.info("Update {} with {}", tripDistance.toString(), entry.lastTrip); updateState(tripDistance, QuantityType.valueOf(entry.lastTrip, MetricPrefix.KILO(SIUnits.METRE))); } else if (entry.name.equals(TripEntry.ACTUAL_DISTANCE_WITHOUT_CHARGING)) { - logger.info("Update {} with {}", tripDistanceSinceCharging.toString(), entry.lastTrip); updateState(tripDistanceSinceCharging, QuantityType.valueOf(entry.lastTrip, MetricPrefix.KILO(SIUnits.METRE))); } else if (entry.name.equals(TripEntry.AVERAGE_ELECTRIC_CONSUMPTION)) { - logger.info("Update {} with {}", tripAvgConsumption.toString(), entry.lastTrip); updateState(tripAvgConsumption, QuantityType.valueOf(entry.lastTrip, SmartHomeUnits.KILOWATT_HOUR)); } else if (entry.name.equals(TripEntry.AVERAGE_RECUPERATED_ENERGY_PER_100_KM)) { - logger.info("Update {} with {}", tripAvgRecuperation.toString(), entry.lastTrip); + ThingHandlerCallback thcb = super.getCallback(); + logger.info("Callback {}", thcb); updateState(tripAvgRecuperation, QuantityType.valueOf(entry.lastTrip, SmartHomeUnits.KILOWATT_HOUR)); } @@ -257,19 +277,19 @@ private void updateEfficiencyStates(String content) { if (eff.scoreList != null) { eff.scoreList.forEach(entry -> { if (entry.attrName.equals(Score.CUMULATED_ELECTRIC_DRIVEN_DISTANCE)) { - logger.info("Update {} with {}", lifeTimeCumulatedDrivenDistance.toString(), entry.lifeTime); updateState(lifeTimeCumulatedDrivenDistance, QuantityType.valueOf(entry.lifeTime, MetricPrefix.KILO(SIUnits.METRE))); } else if (entry.attrName.equals(Score.LONGEST_DISTANCE_WITHOUT_CHARGING)) { - logger.info("Update {} with {}", lifeTimeSingleLongestDistance.toString(), entry.lifeTime); updateState(lifeTimeSingleLongestDistance, QuantityType.valueOf(entry.lifeTime, MetricPrefix.KILO(SIUnits.METRE))); } else if (entry.attrName.equals(Score.AVERAGE_ELECTRIC_CONSUMPTION)) { - logger.info("Update {} with {}", lifeTimeAverageConsumption.toString(), entry.lifeTime); updateState(lifeTimeAverageConsumption, QuantityType.valueOf(entry.lifeTime, SmartHomeUnits.KILOWATT_HOUR)); } else if (entry.attrName.equals(Score.AVERAGE_RECUPERATED_ENERGY_PER_100_KM)) { - logger.info("Update {} with {}", lifeTimeAverageRecuperation.toString(), entry.lifeTime); + // create channel on demand + // ChannelUID cuid = new ChannelUID(thing.getUID(), ConnectedDriveConstants.AVG_RECUPERATION); + // logger.info("update {} with {}", cuid, entry.lifeTime); + // updateState(cuid, QuantityType.valueOf(entry.lifeTime, SmartHomeUnits.KILOWATT_HOUR)); updateState(lifeTimeAverageRecuperation, QuantityType.valueOf(entry.lifeTime, SmartHomeUnits.KILOWATT_HOUR)); } @@ -280,7 +300,11 @@ private void updateEfficiencyStates(String content) { } } - private void updateRangeStates(String content) { + private void updateRangeStates(@Nullable String content) { + if (content == null) { + logger.warn("No Vehicle Values available"); + } + vehicleCache = content; if (driveTrain.equals(CarType.ELECTRIC_REX.toString())) { BevRexAttributesMap data = GSON.fromJson(content, BevRexAttributesMap.class); BevRexAttributes bevRexAttributes = data.attributesMap; @@ -296,6 +320,10 @@ private void updateRangeStates(String content) { QuantityType.valueOf( bevRexAttributes.beRemainingRangeElectricKm + bevRexAttributes.beRemainingRangeFuelKm, MetricPrefix.KILO(SIUnits.METRE))); + updateState(rangeRadius, + new DecimalType( + (bevRexAttributes.beRemainingRangeElectricKm + bevRexAttributes.beRemainingRangeFuelKm) + * 1000)); } else { updateState(mileage, QuantityType.valueOf(bevRexAttributes.mileage, ImperialUnits.MILE)); updateState(remainingRangeElectric, @@ -305,10 +333,21 @@ private void updateRangeStates(String content) { updateState(remainingRange, QuantityType.valueOf( bevRexAttributes.beRemainingRangeElectricMile + bevRexAttributes.beRemainingRangeFuelMile, ImperialUnits.MILE)); + updateState(rangeRadius, new DecimalType( + (bevRexAttributes.beRemainingRangeElectricMile + bevRexAttributes.beRemainingRangeFuelMile) + * 1000)); } updateState(remainingSoc, QuantityType.valueOf(bevRexAttributes.chargingLevelHv, SmartHomeUnits.PERCENT)); updateState(remainingFuel, QuantityType.valueOf(bevRexAttributes.fuelPercent, SmartHomeUnits.PERCENT)); updateState(lastUpdate, new StringType(bevRexAttributes.Segment_LastTrip_time_segment_end_formatted)); + + updateState(longitude, new DecimalType(bevRexAttributes.gps_lng)); + updateState(latitude, new DecimalType(bevRexAttributes.gps_lat)); + updateState(latlong, new StringType(bevRexAttributes.gps_lat + "," + bevRexAttributes.gps_lng)); + logger.info("Update {} with {}", heading.toString(), bevRexAttributes.heading); + updateState(heading, QuantityType.valueOf(bevRexAttributes.heading, SmartHomeUnits.DEGREE_ANGLE)); + // updateState(headingChannleUID, new DecimalType(bevRexAttributes.heading)); + bevRexAttributes.gps_lat = (float) 0.0; bevRexAttributes.gps_lng = (float) 0.0; vehicleFingerprint = GSON.toJson(bevRexAttributes); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-channel-types.xml index 44451718b62fb..969e75230bd8d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-channel-types.xml @@ -11,11 +11,11 @@ Number:Length - + Number:Energy - + Number:Energy diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-groups.xml index f38e476d70769..36cc1a2de0154 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-groups.xml @@ -9,8 +9,8 @@ - - + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-groups.xml index 794859215b7af..1c32dd2edfc96 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-groups.xml @@ -7,10 +7,10 @@ EV Consumption Values and Distances over Lifetime - + - - + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/location-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/location-channel-groups.xml new file mode 100644 index 0000000000000..6f0918d31ff86 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/location-channel-groups.xml @@ -0,0 +1,17 @@ + + + + + All values needed to locate your Car on a Map + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/loction-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/loction-channel-types.xml new file mode 100644 index 0000000000000..e8bd5dd3a60d7 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/loction-channel-types.xml @@ -0,0 +1,26 @@ + + + + Number + + + + Number + + + + String + + + + Number:Angle + + + + Number + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml index 73b69f218fcb5..a548721367f26 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml @@ -16,7 +16,9 @@ + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-groups.xml index d8493cc70d7d9..a127e58b1754a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-groups.xml @@ -7,7 +7,7 @@ EV Consumption Values and Distances over Lifetime - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml index 20cdb04babeaf..88d804f301b0f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml @@ -3,7 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - + Switch diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexVehicleTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexVehicleTest.java index 236a1df269b45..482fadf7929b1 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexVehicleTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexVehicleTest.java @@ -34,8 +34,7 @@ public void testtestBEV_REX_Values() { String resource1 = FileReader.readFileInString("src/test/resources/vehicle.json"); BevRexAttributesMap attributesMap = GSON.fromJson(resource1, BevRexAttributesMap.class); BevRexAttributes attributes = attributesMap.attributesMap; - System.out.println("Mileage " + attributes.mileage); assertEquals("Mileage", 17236.0, attributes.mileage, 0.1); - System.out.println(attributes.beRemainingRangeFuel); + assertEquals("Heading", 41, attributes.heading, 0.0001); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/EfficiencyTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/EfficiencyTest.java index b2df28146bf24..22156c8d3a2e0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/EfficiencyTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/EfficiencyTest.java @@ -53,7 +53,7 @@ public void testtestBEV_REX_Values() { if (eff.lastTripList != null) { eff.lastTripList.forEach(entry -> { - System.out.println(entry.name + ":" + entry.lastTrip); + // logger.info(entry.name + ":" + entry.lastTrip); if (entry.name.equals(TripEntry.LASTTRIP_DELTA_KM)) { assertEquals("Trip Delta km", 2, entry.lastTrip, 0.01); } else if (entry.name.equals(TripEntry.ACTUAL_DISTANCE_WITHOUT_CHARGING)) { From 3f0a812458b87fb0963c3e201c9e83aacabbd1ea Mon Sep 17 00:00:00 2001 From: Bernd Date: Mon, 24 Aug 2020 23:11:17 +0200 Subject: [PATCH 006/176] add location group Signed-off-by: Bernd (cherry picked from commit 2658091445223a8fb9998ee0be3b66da4ec5363a) Signed-off-by: Bernd --- .../internal/handler/ConnectedCarHandler.java | 109 ++++++++++++++---- 1 file changed, 89 insertions(+), 20 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java index bdf4453ea6bf1..928532a5453c6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java @@ -15,6 +15,8 @@ import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; import static org.openhab.binding.bmwconnecteddrive.internal.handler.HTTPConstants.CONTENT_TYPE_JSON; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -86,6 +88,12 @@ public class ConnectedCarHandler extends ConnectedCarChannelHandler { private @Nullable String sendMessageAPI; private @Nullable String imageAPI; + private @Nullable String lastTripAPI;// = baseUrl + "/statistics/lastTrip"; + private @Nullable String allTripsAPI;// = baseUrl + "/statistics/allTrips"; + private @Nullable String chargeAPI;// = baseUrl + "/chargingprofile"; + private @Nullable String destinationAPI;// = baseUrl + "/destinations"; + private List allAPIs = new ArrayList(); + private @Nullable String vehicleCache; private @Nullable String efficiencyCache; @@ -128,6 +136,25 @@ public void handleCommand(ChannelUID channelUID, Command command) { } } + /** + * URLs taken from https://github.com/bimmerconnected/bimmer_connected/blob/master/bimmer_connected/const.py + * + * """URLs for different services and error code mapping.""" + * + * AUTH_URL = 'https://customer.bmwgroup.com/{gcdm_oauth_endpoint}/authenticate' + * AUTH_URL_LEGACY = 'https://{server}/gcdm/oauth/token' + * BASE_URL = 'https://{server}/webapi/v1' + * + * VEHICLES_URL = BASE_URL + '/user/vehicles' + * VEHICLE_VIN_URL = VEHICLES_URL + '/{vin}' + * VEHICLE_STATUS_URL = VEHICLE_VIN_URL + '/status' + * REMOTE_SERVICE_STATUS_URL = VEHICLE_VIN_URL + '/serviceExecutionStatus?serviceType={service_type}' + * REMOTE_SERVICE_URL = VEHICLE_VIN_URL + "/executeService" + * VEHICLE_IMAGE_URL = VEHICLE_VIN_URL + "/image?width={width}&height={height}&view={view}" + * VEHICLE_POI_URL = VEHICLE_VIN_URL + '/sendpoi' + * + * } + */ @Override public void initialize() { updateStatus(ThingStatus.UNKNOWN); @@ -139,26 +166,43 @@ public void initialize() { BridgeHandler handler = bridge.getHandler(); if (handler != null) { bridgeHandler = ((ConnectedDriveBridgeHandler) handler); - String baseUrl = "https://" + bridgeHandler.getRegionServer() + "/api/vehicle"; - - // https://b2vapi.bmwgroup.com/api/vehicle/dynamic/v1/ - // from bimmer_connect project - // r = requests.get(self.vehicleApi+'/dynamic/v1/'+self.bmwVin+'?offset=-60', - vehicleAPI = baseUrl + "/dynamic/v1/" + config.vin + "?offset=-60"; - // r = requests.post(self.vehicleApi+'/myinfo/v1', data=json.dumps(values), - sendMessageAPI = baseUrl + "/myinfo/v1"; - // r = requests.get(self.vehicleApi+'/navigation/v1/'+self.bmwVin, - // headers=headers,allow_redirects=True) - navigationAPI = baseUrl + "/navigation/v1/" + config.vin; - // r = requests.get(self.vehicleApi+'/efficiency/v1/'+self.bmwVin, - // headers=headers,allow_redirects=True) - efficiencyAPI = baseUrl + "/efficiency/v1/" + config.vin; - // r = requests.post(self.vehicleApi+'/remoteservices/v1/'+self.bmwVin+'/'+command, - remoteControlAPI = baseUrl + "/remoteservices/v1/" + config.vin; - // r = requests.get(self.vehicleApi+'/remoteservices/v1/'+self.bmwVin+'/state/execution', - remoteExecutionAPI = baseUrl + "/remoteservices/v1/" + config.vin + "/state/execution"; - imageAPI = "https://" + bridgeHandler.getRegionServer() + "/webapi/v1/user/vehicles/" - + config.vin + "/image?width=400&height=400&view=REARBIRDSEYE"; + String baseUrl = "https://" + bridgeHandler.getRegionServer() + "/webapi/v1/user/vehicles/" + + config.vin; + vehicleAPI = baseUrl + "/status"; + allAPIs.add(vehicleAPI); + lastTripAPI = baseUrl + "/statistics/lastTrip"; + allAPIs.add(lastTripAPI); + allTripsAPI = baseUrl + "/statistics/allTrips"; + allAPIs.add(allTripsAPI); + chargeAPI = baseUrl + "/chargingprofile"; + allAPIs.add(chargeAPI); + destinationAPI = baseUrl + "/destinations"; + allAPIs.add(destinationAPI); + imageAPI = baseUrl + "/image?width=200&height=200&view=FRONT"; + allAPIs.add(imageAPI); + tokenUpdate(); + allAPIs.forEach(entry -> { + Request req = httpClient.newRequest(entry); + req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); + req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); + try { + ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); + logger.info("Status {}", contentResponse.getStatus()); + logger.info("Reason {}", contentResponse.getReason()); + logger.info("{}", entry); + logger.info("{}", contentResponse.getContentAsString()); + } catch (InterruptedException | TimeoutException | ExecutionException e) { + logger.warn("Get Data Exception {}", e.getMessage()); + } + }); + + /** + * REMOTE_SERVICE_STATUS_URL = VEHICLE_VIN_URL + + * '/serviceExecutionStatus?serviceType={service_type}' + * REMOTE_SERVICE_URL = VEHICLE_VIN_URL + "/executeService" + * VEHICLE_IMAGE_URL = VEHICLE_VIN_URL + "/image?width={width}&height={height}&view={view}" + * VEHICLE_POI_URL = VEHICLE_VIN_URL + '/sendpoi' + */ // String baseUrl = "https://" + bridgeHandler.getRegionServer(); // statusAPI = baseUrl + "/webapi/v1/user/vehicles/" + config.vin + "/status"; @@ -182,6 +226,31 @@ public void initialize() { } } + /** + * old APIS + * + * String baseUrl = "https://" + bridgeHandler.getRegionServer() + "/api/vehicle"; + * // https://b2vapi.bmwgroup.com/api/vehicle/dynamic/v1/ + * // from bimmer_connect project + * // r = requests.get(self.vehicleApi+'/dynamic/v1/'+self.bmwVin+'?offset=-60', + * vehicleAPI = baseUrl + "/dynamic/v1/" + config.vin + "?offset=-60"; + * // r = requests.post(self.vehicleApi+'/myinfo/v1', data=json.dumps(values), + * sendMessageAPI = baseUrl + "/myinfo/v1"; + * // r = requests.get(self.vehicleApi+'/navigation/v1/'+self.bmwVin, + * // headers=headers,allow_redirects=True) + * navigationAPI = baseUrl + "/navigation/v1/" + config.vin; + * // r = requests.get(self.vehicleApi+'/efficiency/v1/'+self.bmwVin, + * // headers=headers,allow_redirects=True) + * efficiencyAPI = baseUrl + "/efficiency/v1/" + config.vin; + * // r = requests.post(self.vehicleApi+'/remoteservices/v1/'+self.bmwVin+'/'+command, + * remoteControlAPI = baseUrl + "/remoteservices/v1/" + config.vin; + * // r = requests.get(self.vehicleApi+'/remoteservices/v1/'+self.bmwVin+'/state/execution', + * remoteExecutionAPI = baseUrl + "/remoteservices/v1/" + config.vin + "/state/execution"; + * imageAPI = "https://" + bridgeHandler.getRegionServer() + "/webapi/v1/user/vehicles/" + * + config.vin + "/image?width=400&height=400&view=REARBIRDSEYE"; + * + */ + private void startSchedule(int interval) { ScheduledFuture localRefreshJob = refreshJob; if (localRefreshJob != null) { From fac2914535257c9167e96c8b5a20707bcad60da6 Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 25 Aug 2020 16:46:23 +0200 Subject: [PATCH 007/176] switch to webapi Signed-off-by: Bernd (cherry picked from commit 68bc41ba36a28e6d1f3484427b2aada6f373c1c7) Signed-off-by: Bernd --- .../Clustering.txt | 77 ----- .../api/vehicle}/BevRexAttributes.java | 0 .../efficiency/CharacterristicsScore.java | 0 .../efficiency/Efficiency.java | 0 .../dto => obsolete}/efficiency/Score.java | 0 .../efficiency/TripEntry.java | 0 .../internal/ConnectedCarConfiguration.java | 18 ++ .../internal/dto/DynamicVehicleRangeData.java | 30 -- .../AllTrips.java} | 8 +- .../internal/dto/statistics/Community.java | 31 ++ .../CommunityChargeCycleEntry.java} | 20 +- .../CommunityEletricDistanceEntry.java | 25 ++ .../dto/statistics/CommunityPowerEntry.java | 25 ++ .../LastTrip.java} | 8 +- .../internal/dto/statistics/Trip.java | 36 +++ .../internal/dto/{ => status}/CBSMessage.java | 2 +- .../internal/dto/status/CCMMessage.java | 27 ++ .../internal/dto/status/Position.java | 25 ++ .../Status.java} | 11 +- .../internal/dto/status/VehicleStatus.java | 65 ++++ .../internal/handler/ConnectedCarHandler.java | 302 ++++++++---------- .../internal/utils/Converter.java | 30 ++ ...oups.xml => conv-range-channel-groups.xml} | 7 +- .../ESH-INF/thing/ev-range-channel-groups.xml | 16 + .../ESH-INF/thing/image-channel-groups.xml | 1 - .../ESH-INF/thing/image-channel-types.xml | 17 - .../resources/ESH-INF/thing/thing-bev.xml | 54 ++++ .../resources/ESH-INF/thing/thing-bev_rex.xml | 20 +- .../resources/ESH-INF/thing/thing-conv.xml | 52 +++ .../resources/ESH-INF/thing/thing-phev.xml | 54 ++++ .../internal/dto/ConnectedDriveTest.java | 2 +- .../internal/dto/EfficiencyTest.java | 82 ----- .../internal/dto/statistics/LastTripTest.java | 40 +++ .../dto/{ => status}/BevRexVehicleTest.java | 19 +- .../{ => api/vehicle}/efficiency.json | 0 .../{ => api/vehicle}/navigation.json | 0 .../resources/{ => api/vehicle}/test.json | 0 .../resources/{ => api/vehicle}/vehicle.json | 0 .../{ => api/vehicle}/webapi-status.json | 0 .../src/test/resources/webapi/all-trips.json | 40 +++ .../resources/webapi/charging-profile.json | 34 ++ .../connected-drive-account-info.json | 0 .../test/resources/webapi/destinations.json | 91 ++++++ .../src/test/resources/webapi/last-trip.json | 19 ++ .../test/resources/webapi/vehicle-status.json | 76 +++++ 45 files changed, 945 insertions(+), 419 deletions(-) delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/Clustering.txt rename bundles/org.openhab.binding.bmwconnecteddrive/{src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto => obsolete/api/vehicle}/BevRexAttributes.java (100%) rename bundles/org.openhab.binding.bmwconnecteddrive/{src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto => obsolete}/efficiency/CharacterristicsScore.java (100%) rename bundles/org.openhab.binding.bmwconnecteddrive/{src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto => obsolete}/efficiency/Efficiency.java (100%) rename bundles/org.openhab.binding.bmwconnecteddrive/{src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto => obsolete}/efficiency/Score.java (100%) rename bundles/org.openhab.binding.bmwconnecteddrive/{src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto => obsolete}/efficiency/TripEntry.java (100%) delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DynamicVehicleRangeData.java rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/{BevRexAttributesMap.java => statistics/AllTrips.java} (69%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/Community.java rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/{AttributesMap.java => statistics/CommunityChargeCycleEntry.java} (52%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityEletricDistanceEntry.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityPowerEntry.java rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/{CCMMessage.java => statistics/LastTrip.java} (72%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/Trip.java rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/{ => status}/CBSMessage.java (92%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CCMMessage.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/{VehicleMessages.java => status/Status.java} (64%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/{range-channel-groups.xml => conv-range-channel-groups.xml} (66%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-groups.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/EfficiencyTest.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripTest.java rename bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/{ => status}/BevRexVehicleTest.java (58%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/{ => api/vehicle}/efficiency.json (100%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/{ => api/vehicle}/navigation.json (100%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/{ => api/vehicle}/test.json (100%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/{ => api/vehicle}/vehicle.json (100%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/{ => api/vehicle}/webapi-status.json (100%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/all-trips.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/charging-profile.json rename bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/{ => webapi}/connected-drive-account-info.json (100%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/destinations.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/last-trip.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status.json diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/Clustering.txt b/bundles/org.openhab.binding.bmwconnecteddrive/Clustering.txt deleted file mode 100644 index 43b13c8d0c870..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/Clustering.txt +++ /dev/null @@ -1,77 +0,0 @@ - "door_driver_front": "CLOSED", - "door_driver_rear": "CLOSED", - "door_passenger_rear": "CLOSED", - "door_lock_state": "SECURED", - "sunroof_state": "CLOSED", - "sunroof_position": "0", - "hood_state": "CLOSED", - "trunk_state": "CLOSED", - "window_driver_front": "CLOSED", - "window_passenger_front": "CLOSED", - "window_driver_rear": "CLOSED", - "window_passenger_rear": "CLOSED", - "shdStatusUnified": "CLOSED", - "lastUpdateReason": "VEHCSHUTDOWN_SECURED" - "head_unit_pu_software": "07/16", - "vehicle_tracking": "1", - "lsc_trigger": "VEHCSHUTDOWN_SECURED", - "lights_parking": "OFF", - "battery_size_max": "33200", - "head_unit": "EntryNav", - - "unitOfEnergy": "kWh", - "unitOfLength": "km", - "unitOfCombustionConsumption": "l/100km", - "unitOfElectricConsumption": "kWh/100km", - - "charging_status": "NOCHARGING", - "lastChargingEndResult": "SUCCESS", - "lastChargingEndReason": "END_REQUESTED_BY_DRIVER", - - "chargingSystemStatus": "NOCHARGING", - "chargingHVStatus": "INVALID", - "connectorStatus": "DISCONNECTED", - "single_immediate_charging": "isUnused", - "chargingLogicCurrentlyActive": "NOT_CHARGING", - "chargeNowAllowed": "NOT_ALLOWED", - "prognosisWhileChargingStatus": "NOT_NEEDED", - "charging_inductive_positioning": "not_positioned", - "charging_connection_type": "CONDUCTIVE", - - - "heading": "219", - "gps_lat": "50.57321", - "gps_lng": "8.66393", - - - "check_control_messages": "", - - "beMaxRangeElectric": "202.0", - "beMaxRangeElectricKm": "202.0", - "beMaxRangeElectricMile": "125.0", - "beRemainingRangeElectric": "113.0", - "beRemainingRangeElectricKm": "113.0", - "beRemainingRangeElectricMile": "70.0", - "beRemainingRangeFuel": "65.0", - "beRemainingRangeFuelKm": "65.0", - "beRemainingRangeFuelMile": "40.0", - "kombi_current_remaining_range_fuel": "65.0", - "mileage": "17107", - "soc_hv_percent": "58.1", - "chargingLevelHv": "58.0", - "fuelPercent": "47", - "remaining_fuel": "4", - "Segment_LastTrip_ratio_electric_driven_distance": "100", - - "condition_based_services": "00003,OK,2021-11,;00017,OK,2021-11,;00001,OK,2021-11,;00032,OK,2021-11,", - - "updateTime_converted": "18.08.2020 05:44", - "updateTime_converted_date": "18.08.2020", - "updateTime_converted_timestamp": "1597729475000", - "updateTime": "18.08.2020 04:44:35 UTC", - "updateTime_converted_time": "05:44", - "Segment_LastTrip_time_segment_end": "18.08.2020 06:45:00 UTC", - "Segment_LastTrip_time_segment_end_formatted_time": "06:45", - "Segment_LastTrip_time_segment_end_formatted_date": "18.08.2020", - "Segment_LastTrip_time_segment_end_formatted": "18.08.2020 06:45", - \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexAttributes.java b/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/api/vehicle/BevRexAttributes.java similarity index 100% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexAttributes.java rename to bundles/org.openhab.binding.bmwconnecteddrive/obsolete/api/vehicle/BevRexAttributes.java diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/CharacterristicsScore.java b/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/CharacterristicsScore.java similarity index 100% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/CharacterristicsScore.java rename to bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/CharacterristicsScore.java diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/Efficiency.java b/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/Efficiency.java similarity index 100% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/Efficiency.java rename to bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/Efficiency.java diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/Score.java b/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/Score.java similarity index 100% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/Score.java rename to bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/Score.java diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/TripEntry.java b/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/TripEntry.java similarity index 100% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/efficiency/TripEntry.java rename to bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/TripEntry.java diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java index fffcb4d27f58a..caafedeebaf63 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java @@ -30,4 +30,22 @@ public class ConnectedCarConfiguration { * Data refresh rate in minutes */ public int refreshInterval = 15; + + /** + * image size - width & length (square) + */ + public int imageSize = 300; + + /** + * image viewport defined as options in thing xml + * + * + * + * + * + * + * + * + */ + public String imageViewport = "FRONT"; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DynamicVehicleRangeData.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DynamicVehicleRangeData.java deleted file mode 100644 index 564a0c17d502d..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DynamicVehicleRangeData.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; - -/** - * The {@link DynamicVehicleRangeData} Data Transfer Object - * - * @author Bernd Weymann - Initial contribution - */ -public class DynamicVehicleRangeData { - private int beRemainingRangeElectric; - - public int getBeRemainingRangeElectric() { - return beRemainingRangeElectric; - } - - public void setBeRemainingRangeElectric(int beRemainingRangeElectric) { - this.beRemainingRangeElectric = beRemainingRangeElectric; - } -} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexAttributesMap.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/AllTrips.java similarity index 69% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexAttributesMap.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/AllTrips.java index 5fd43e950658e..46baa6ba99664 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexAttributesMap.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/AllTrips.java @@ -10,13 +10,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.bmwconnecteddrive.internal.dto; +package org.openhab.binding.bmwconnecteddrive.internal.dto.statistics; /** - * The {@link BevRexAttributesMap} Data Transfer Object + * The {@link AllTrips} Data Transfer Object * * @author Bernd Weymann - Initial contribution */ -public class BevRexAttributesMap { - public BevRexAttributes attributesMap; +public class AllTrips { + public Community allTrips; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/Community.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/Community.java new file mode 100644 index 0000000000000..9c9d6e1510800 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/Community.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.statistics; + +/** + * The {@link Community} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class Community { + public CommunityPowerEntry avgElectricConsumption; + public CommunityPowerEntry avgRecuperation; + public CommunityChargeCycleEntry chargecycleRange; + public CommunityEletricDistanceEntry totalElectricDistance; + public CommunityPowerEntry avgCombinedConsumption; + public float savedCO2;// ":461.083," + public float savedCO2greenEnergy;// ":2712.255," + public float totalSavedFuel;// ":0," + public String resetDate;// ":"2020-08-24T14:40:40+0000"," + public int batterySizeMax;// ":33200 +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/AttributesMap.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityChargeCycleEntry.java similarity index 52% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/AttributesMap.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityChargeCycleEntry.java index 645b57a6dcfbb..c5e2473e5b9a3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/AttributesMap.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityChargeCycleEntry.java @@ -10,21 +10,17 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.bmwconnecteddrive.internal.dto; +package org.openhab.binding.bmwconnecteddrive.internal.dto.statistics; /** - * The {@link AttributesMap} Data Transfer Object + * The {@link CommunityChargeCycleEntry} Data Transfer Object * * @author Bernd Weymann - Initial contribution */ -public class AttributesMap { - private DynamicVehicleRangeData attributesMap; - - public DynamicVehicleRangeData getAttributesMap() { - return attributesMap; - } - - public void setAttributesMap(DynamicVehicleRangeData attributesMap) { - this.attributesMap = attributesMap; - } +public class CommunityChargeCycleEntry { + public float communityAverage;// ": 194.21, + public float communityHigh;// ": 270, + public float userAverage;// ": 57.3, + public float userHigh;// ": 185.48, + public float userCurrentChargeCycle;// ": 68 } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityEletricDistanceEntry.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityEletricDistanceEntry.java new file mode 100644 index 0000000000000..754e1050e13b1 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityEletricDistanceEntry.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.statistics; + +/** + * The {@link CommunityEletricDistanceEntry} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class CommunityEletricDistanceEntry { + public float communityLow;// ": 19, + public float communityAverage;// ": 40850.56, + public float communityHigh;// ": 193006, + public float userTotal;// ": 16629.4 +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityPowerEntry.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityPowerEntry.java new file mode 100644 index 0000000000000..0c35ab55cc4e0 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityPowerEntry.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.statistics; + +/** + * The {@link CommunityPowerEntry} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class CommunityPowerEntry { + public float communityLow;// ": 11.05, + public float communityAverage;// ": 16.28, + public float communityHigh;// ": 21.99, + public float userAverage;// ": 16.46 +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CCMMessage.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTrip.java similarity index 72% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CCMMessage.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTrip.java index 81e376a775d8b..26969685f839c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CCMMessage.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTrip.java @@ -10,13 +10,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.bmwconnecteddrive.internal.dto; +package org.openhab.binding.bmwconnecteddrive.internal.dto.statistics; /** - * The {@link CCMMessage} Data Transfer Object + * The {@link LastTrip} Data Transfer Object * * @author Bernd Weymann - Initial contribution */ -public class CCMMessage { - +public class LastTrip { + public Trip lastTrip; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/Trip.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/Trip.java new file mode 100644 index 0000000000000..ddba08abc38bc --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/Trip.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.statistics; + +/** + * The {@link Trip} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class Trip { + public float efficiencyValue;// ": 0.98, + public float totalDistance;// ": 2, + public float electricDistance;// ": 2, + public float avgElectricConsumption;// ": 7, + public float avgRecuperation;// ": 6, + public float drivingModeValue;// ": 0.87, + public float accelerationValue;// ": 0.99, + public float anticipationValue;// ": 0.99, + public float totalConsumptionValue;// ": 1.25, + public float auxiliaryConsumptionValue;// ": 0.78, + public float avgCombinedConsumption;// ": 0, + public float electricDistanceRatio;// ": 100, + public float savedFuel;// ": 0, + public String date;// ": "2020-08-24T17:55:00+0000", + public float duration;// ": 5 +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CBSMessage.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java similarity index 92% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CBSMessage.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java index 91bd09078cd84..ff74d248a399a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/CBSMessage.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.bmwconnecteddrive.internal.dto; +package org.openhab.binding.bmwconnecteddrive.internal.dto.status; /** * The {@link CBSMessage} Data Transfer Object diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CCMMessage.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CCMMessage.java new file mode 100644 index 0000000000000..6b3f726d8458b --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CCMMessage.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.status; + +/** + * The {@link CCMMessage} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class CCMMessage { + public String ccmDescriptionLong;// ": "You can continue driving. Check tyre pressure when tyres are cold and adjust + // if necessary. Perform reset after adjustment. See Owner's Handbook for further + // information.", + public String ccmDescriptionShort;// ": "Tyre pressure notification", + public int ccmId;// ": 955, + public int ccmMileage;// ": 41544 +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java new file mode 100644 index 0000000000000..8cc55ed87e864 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.status; + +/** + * The {@link Position} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class Position { + public float lat;// ": 50.55605, + public float lon;// ": 8.495669, + public int heading;// ": 219, + public String status;// ": "OK" +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleMessages.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Status.java similarity index 64% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleMessages.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Status.java index 647e488015783..2297ee88f21c6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleMessages.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Status.java @@ -10,16 +10,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.bmwconnecteddrive.internal.dto; - -import java.util.List; +package org.openhab.binding.bmwconnecteddrive.internal.dto.status; /** - * The {@link VehicleMessages} Data Transfer Object + * The {@link Status} Data Transfer Object * * @author Bernd Weymann - Initial contribution */ -public class VehicleMessages { - public List ccmMessages; - public List cbsMessages; +public class Status { + public VehicleStatus vehicleStatus; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java new file mode 100644 index 0000000000000..1ba071fee5696 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.status; + +import java.util.List; + +/** + * The {@link VehicleStatus} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class VehicleStatus { + public int mileage;// ": 17273, + public float remainingFuel;// ": 4, + public float remainingRangeElectric;// ": 148, + public float remainingRangeElectricMls;// ": 91, + public float remainingRangeFuel;// ": 70," + public float remainingRangeFuelMls;// ":43," + public float maxRangeElectric;// ":216," + public float maxRangeElectricMls;// ":134," + public float maxFuel;// ":8.5, + public float chargingLevelHv;// ":71, + public String vin;// : "WBY1Z81040V905639", + public String updateReason;// ": "VEHICLE_SHUTDOWN_SECURED", + public String updateTime;// ": "2020-08-24 T15:55:32+0000", + public String doorDriverFront;// ": "CLOSED", + public String doorDriverRear;// ": "CLOSED", + public String doorPassengerFront;// ": "CLOSED", + public String doorPassengerRear;// ": "CLOSED", + public String windowDriverFront;// ": "CLOSED", + public String windowDriverRear;// ": "CLOSED", + public String windowPassengerFront;// ": "CLOSED", + public String windowPassengerRear;// ": "CLOSED", + public String sunroof;// ": "CLOSED", + public String trunk;// ": "CLOSED", + public String rearWindow;// ": "INVALID", + public String hood;// ": "CLOSED", + public String doorLockState;// ": "SECURED", + public String parkingLight;// ": "OFF", + public String positionLight;// ": "ON", + public String connectionStatus;// ": "DISCONNECTED", + public String chargingStatus;// ": "INVALID"," + public String lastChargingEndReason;// ": "CHARGING_GOAL_REACHED", + public String lastChargingEndResult;// ": "SUCCESS"," + public Position position; + public String internalDataTimeUTC;// ": "2020-08-24 T15:55:32", + public boolean singleImmediateCharging;// ":false, + public String chargingConnectionType;// ": "CONDUCTIVE", + public String chargingInductivePositioning;// ": "NOT_POSITIONED", + public String vehicleCountry;// ": "DE","+" + public String DCS_CCH_Activation;// ": "NA", + public boolean DCS_CCH_Ongoing;// ":false + public List checkControlMessages;// ":[], + public List cbsData; +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java index 928532a5453c6..67ff14fb9be83 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java @@ -12,11 +12,10 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.handler; -import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; +import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CARDATA_FINGERPRINT; import static org.openhab.binding.bmwconnecteddrive.internal.handler.HTTPConstants.CONTENT_TYPE_JSON; -import java.util.ArrayList; -import java.util.List; +import java.time.LocalDateTime; import java.util.concurrent.ExecutionException; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -43,16 +42,19 @@ import org.eclipse.smarthome.core.thing.ThingStatus; import org.eclipse.smarthome.core.thing.ThingStatusDetail; import org.eclipse.smarthome.core.thing.binding.BridgeHandler; -import org.eclipse.smarthome.core.thing.binding.ThingHandlerCallback; import org.eclipse.smarthome.core.types.Command; import org.eclipse.smarthome.core.types.RefreshType; +import org.eclipse.smarthome.io.net.http.HttpUtil; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedCarConfiguration; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CarType; -import org.openhab.binding.bmwconnecteddrive.internal.dto.BevRexAttributes; -import org.openhab.binding.bmwconnecteddrive.internal.dto.BevRexAttributesMap; -import org.openhab.binding.bmwconnecteddrive.internal.dto.efficiency.Efficiency; -import org.openhab.binding.bmwconnecteddrive.internal.dto.efficiency.Score; -import org.openhab.binding.bmwconnecteddrive.internal.dto.efficiency.TripEntry; +import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTrips; +import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.Community; +import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTrip; +import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.Trip; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Position; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Status; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -67,12 +69,13 @@ @NonNullByDefault public class ConnectedCarHandler extends ConnectedCarChannelHandler { private final Logger logger = LoggerFactory.getLogger(ConnectedCarHandler.class); - private static final Gson GSON = new Gson(); + private final static Gson GSON = new Gson(); private String driveTrain; private HttpClient httpClient; private Token token = new Token(); + private @Nullable ConnectedCarConfiguration configuration; private @Nullable ConnectedDriveBridgeHandler bridgeHandler; protected @Nullable ScheduledFuture refreshJob; @@ -81,21 +84,11 @@ public class ConnectedCarHandler extends ConnectedCarChannelHandler { // Connected Drive APIs private @Nullable String vehicleAPI; - private @Nullable String navigationAPI; - private @Nullable String efficiencyAPI; - private @Nullable String remoteControlAPI; - private @Nullable String remoteExecutionAPI; - private @Nullable String sendMessageAPI; private @Nullable String imageAPI; - - private @Nullable String lastTripAPI;// = baseUrl + "/statistics/lastTrip"; - private @Nullable String allTripsAPI;// = baseUrl + "/statistics/allTrips"; - private @Nullable String chargeAPI;// = baseUrl + "/chargingprofile"; - private @Nullable String destinationAPI;// = baseUrl + "/destinations"; - private List allAPIs = new ArrayList(); - - private @Nullable String vehicleCache; - private @Nullable String efficiencyCache; + private @Nullable String lastTripAPI; + private @Nullable String allTripsAPI; + private @Nullable String chargeAPI; + private @Nullable String destinationAPI; public ConnectedCarHandler(Thing thing, HttpClient hc, String type) { super(thing); @@ -108,11 +101,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { if (command instanceof RefreshType) { String group = channelUID.getGroupId(); logger.info("REFRESH {}", group); - if (CHANNEL_GROUP_LAST_TRIP.equals(group) || CHANNEL_GROUP_LAST_TRIP.equals(group)) { - updateEfficiencyStates(efficiencyCache); - } else if (CHANNEL_GROUP_CAR_STATUS.equals(group) || CHANNEL_GROUP_LOCATION.equals(group)) { - updateRangeStates(vehicleCache); - } } else { logger.info("No refresh"); } @@ -159,6 +147,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { public void initialize() { updateStatus(ThingStatus.UNKNOWN); ConnectedCarConfiguration config = getConfigAs(ConnectedCarConfiguration.class); + configuration = config; if (config != null) { scheduler.execute(() -> { Bridge bridge = getBridge(); @@ -169,32 +158,25 @@ public void initialize() { String baseUrl = "https://" + bridgeHandler.getRegionServer() + "/webapi/v1/user/vehicles/" + config.vin; vehicleAPI = baseUrl + "/status"; - allAPIs.add(vehicleAPI); lastTripAPI = baseUrl + "/statistics/lastTrip"; - allAPIs.add(lastTripAPI); allTripsAPI = baseUrl + "/statistics/allTrips"; - allAPIs.add(allTripsAPI); chargeAPI = baseUrl + "/chargingprofile"; - allAPIs.add(chargeAPI); destinationAPI = baseUrl + "/destinations"; - allAPIs.add(destinationAPI); - imageAPI = baseUrl + "/image?width=200&height=200&view=FRONT"; - allAPIs.add(imageAPI); - tokenUpdate(); - allAPIs.forEach(entry -> { - Request req = httpClient.newRequest(entry); - req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); - req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); - try { - ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); - logger.info("Status {}", contentResponse.getStatus()); - logger.info("Reason {}", contentResponse.getReason()); - logger.info("{}", entry); - logger.info("{}", contentResponse.getContentAsString()); - } catch (InterruptedException | TimeoutException | ExecutionException e) { - logger.warn("Get Data Exception {}", e.getMessage()); - } - }); + imageAPI = baseUrl + "/image"; + // allAPIs.forEach(entry -> { + // Request req = httpClient.newRequest(entry); + // req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); + // req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); + // try { + // ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); + // logger.info("Status {}", contentResponse.getStatus()); + // logger.info("Reason {}", contentResponse.getReason()); + // logger.info("{}", entry); + // logger.info("{}", contentResponse.getContentAsString()); + // } catch (InterruptedException | TimeoutException | ExecutionException e) { + // logger.warn("Get Data Exception {}", e.getMessage()); + // } + // }); /** * REMOTE_SERVICE_STATUS_URL = VEHICLE_VIN_URL + @@ -217,7 +199,6 @@ public void initialize() { } else { logger.warn("Bridge null"); } - getImage(); startSchedule(config.refreshInterval); }); @@ -274,152 +255,117 @@ public void getData() { if (!tokenUpdate()) { return; } + String vehicleStatusData = getJSON(vehicleAPI); + updateVehicleStatus(vehicleStatusData); + String lastTripData = getJSON(lastTripAPI); + updateLastTrip(lastTripData); + String allTripData = getJSON(allTripsAPI); + updateTripStatistics(allTripData); + String chargeData = getJSON(chargeAPI); + String destinationData = getJSON(destinationAPI); + } - Request req = httpClient.newRequest(vehicleAPI); - req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); - req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); - try { - ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); - logger.info("Status {}", contentResponse.getStatus()); - logger.info("Reason {}", contentResponse.getReason()); - logger.info("Vehicle {}", contentResponse.getContentAsString()); - updateStatus(ThingStatus.ONLINE); - updateRangeStates(contentResponse.getContentAsString()); - } catch (InterruptedException | TimeoutException | ExecutionException e) { - logger.warn("Get Data Exception {}", e.getMessage()); - } - - req = httpClient.newRequest(efficiencyAPI); - req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); - req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); - try { - ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); - logger.info("Status {}", contentResponse.getStatus()); - logger.info("Reason {}", contentResponse.getReason()); - logger.info("Efficiency {}", contentResponse.getContentAsString()); - updateEfficiencyStates(contentResponse.getContentAsString()); - } catch (InterruptedException | TimeoutException | ExecutionException e) { - logger.warn("Get Data Exception {}", e.getMessage()); + public @Nullable String getJSON(@Nullable String url) { + if (url == null) { + return null; } - - req = httpClient.newRequest(navigationAPI); + Request req = httpClient.newRequest(url); req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); try { ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); - logger.info("Status {}", contentResponse.getStatus()); - logger.info("Reason {}", contentResponse.getReason()); - logger.info("Navigation {}", contentResponse.getContentAsString()); + if (contentResponse.getStatus() != 200) { + logger.info("URL {}", url); + logger.info("Status {}", contentResponse.getStatus()); + logger.info("Reason {}", contentResponse.getReason()); + } else { + updateStatus(ThingStatus.ONLINE); + return contentResponse.getContentAsString(); + } } catch (InterruptedException | TimeoutException | ExecutionException e) { logger.warn("Get Data Exception {}", e.getMessage()); } + return null; } - private void updateEfficiencyStates(@Nullable String content) { + private void updateTripStatistics(@Nullable String content) { if (content == null) { - logger.warn("No Efficiency Values available"); + logger.warn("No Vehicle Values available"); } - efficiencyCache = content; - efficiencyFingerprint = content; - if (driveTrain.equals(CarType.ELECTRIC_REX.toString()) || driveTrain.equals(CarType.ELECTRIC.toString())) { - Efficiency eff = GSON.fromJson(content, Efficiency.class); + AllTrips at = GSON.fromJson(content, AllTrips.class); + Community c = at.allTrips; + updateState(lifeTimeCumulatedDrivenDistance, QuantityType + .valueOf(Converter.round(c.totalElectricDistance.userTotal), MetricPrefix.KILO(SIUnits.METRE))); + updateState(lifeTimeSingleLongestDistance, + QuantityType.valueOf(Converter.round(c.chargecycleRange.userHigh), MetricPrefix.KILO(SIUnits.METRE))); + updateState(lifeTimeAverageConsumption, QuantityType + .valueOf(Converter.round(c.avgElectricConsumption.userAverage), SmartHomeUnits.KILOWATT_HOUR)); + updateState(lifeTimeAverageRecuperation, + QuantityType.valueOf(Converter.round(c.avgRecuperation.userAverage), SmartHomeUnits.KILOWATT_HOUR)); + updateState(tripDistanceSinceCharging, QuantityType + .valueOf(Converter.round(c.chargecycleRange.userCurrentChargeCycle), MetricPrefix.KILO(SIUnits.METRE))); + } - if (eff.lastTripList != null) { - eff.lastTripList.forEach(entry -> { - if (entry.name.equals(TripEntry.LASTTRIP_DELTA_KM)) { - updateState(tripDistance, - QuantityType.valueOf(entry.lastTrip, MetricPrefix.KILO(SIUnits.METRE))); - } else if (entry.name.equals(TripEntry.ACTUAL_DISTANCE_WITHOUT_CHARGING)) { - updateState(tripDistanceSinceCharging, - QuantityType.valueOf(entry.lastTrip, MetricPrefix.KILO(SIUnits.METRE))); - } else if (entry.name.equals(TripEntry.AVERAGE_ELECTRIC_CONSUMPTION)) { - updateState(tripAvgConsumption, - QuantityType.valueOf(entry.lastTrip, SmartHomeUnits.KILOWATT_HOUR)); - } else if (entry.name.equals(TripEntry.AVERAGE_RECUPERATED_ENERGY_PER_100_KM)) { - ThingHandlerCallback thcb = super.getCallback(); - logger.info("Callback {}", thcb); - updateState(tripAvgRecuperation, - QuantityType.valueOf(entry.lastTrip, SmartHomeUnits.KILOWATT_HOUR)); - } - }); - } - if (eff.scoreList != null) { - eff.scoreList.forEach(entry -> { - if (entry.attrName.equals(Score.CUMULATED_ELECTRIC_DRIVEN_DISTANCE)) { - updateState(lifeTimeCumulatedDrivenDistance, - QuantityType.valueOf(entry.lifeTime, MetricPrefix.KILO(SIUnits.METRE))); - } else if (entry.attrName.equals(Score.LONGEST_DISTANCE_WITHOUT_CHARGING)) { - updateState(lifeTimeSingleLongestDistance, - QuantityType.valueOf(entry.lifeTime, MetricPrefix.KILO(SIUnits.METRE))); - } else if (entry.attrName.equals(Score.AVERAGE_ELECTRIC_CONSUMPTION)) { - updateState(lifeTimeAverageConsumption, - QuantityType.valueOf(entry.lifeTime, SmartHomeUnits.KILOWATT_HOUR)); - } else if (entry.attrName.equals(Score.AVERAGE_RECUPERATED_ENERGY_PER_100_KM)) { - // create channel on demand - // ChannelUID cuid = new ChannelUID(thing.getUID(), ConnectedDriveConstants.AVG_RECUPERATION); - // logger.info("update {} with {}", cuid, entry.lifeTime); - // updateState(cuid, QuantityType.valueOf(entry.lifeTime, SmartHomeUnits.KILOWATT_HOUR)); - updateState(lifeTimeAverageRecuperation, - QuantityType.valueOf(entry.lifeTime, SmartHomeUnits.KILOWATT_HOUR)); - } - }); - } - } else { - logger.warn("No Efficiency values for {} supported yet", driveTrain); + private void updateLastTrip(@Nullable String content) { + if (content == null) { + logger.warn("No Vehicle Values available"); } + LastTrip lt = GSON.fromJson(content, LastTrip.class); + Trip trip = lt.lastTrip; + updateState(tripDistance, + QuantityType.valueOf(Converter.round(trip.totalDistance), MetricPrefix.KILO(SIUnits.METRE))); + // updateState(tripDistanceSinceCharging, + // QuantityType.valueOf(entry.lastTrip, MetricPrefix.KILO(SIUnits.METRE))); + updateState(tripAvgConsumption, + QuantityType.valueOf(Converter.round(trip.avgElectricConsumption), SmartHomeUnits.KILOWATT_HOUR)); + updateState(tripAvgRecuperation, + QuantityType.valueOf(Converter.round(trip.avgRecuperation), SmartHomeUnits.KILOWATT_HOUR)); } - private void updateRangeStates(@Nullable String content) { + private void updateVehicleStatus(@Nullable String content) { if (content == null) { logger.warn("No Vehicle Values available"); } - vehicleCache = content; if (driveTrain.equals(CarType.ELECTRIC_REX.toString())) { - BevRexAttributesMap data = GSON.fromJson(content, BevRexAttributesMap.class); - BevRexAttributes bevRexAttributes = data.attributesMap; - logger.info("Update Milage {} Channel {}", bevRexAttributes.mileage, mileage.toString()); + Status status = GSON.fromJson(content, Status.class); + VehicleStatus vStatus = status.vehicleStatus; + logger.info("Update Milage {} Channel {}", vStatus.mileage, mileage.toString()); // based on unit of length decide if range shall be reported in km or miles - if (bevRexAttributes.unitOfLength.equals("km")) { - updateState(mileage, QuantityType.valueOf(bevRexAttributes.mileage, MetricPrefix.KILO(SIUnits.METRE))); - updateState(remainingRangeElectric, QuantityType.valueOf(bevRexAttributes.beRemainingRangeElectricKm, - MetricPrefix.KILO(SIUnits.METRE))); - updateState(remainingRangeFuel, QuantityType.valueOf(bevRexAttributes.beRemainingRangeFuelKm, - MetricPrefix.KILO(SIUnits.METRE))); - updateState(remainingRange, - QuantityType.valueOf( - bevRexAttributes.beRemainingRangeElectricKm + bevRexAttributes.beRemainingRangeFuelKm, - MetricPrefix.KILO(SIUnits.METRE))); + if (true) { + updateState(mileage, QuantityType.valueOf(vStatus.mileage, MetricPrefix.KILO(SIUnits.METRE))); + updateState(remainingRangeElectric, + QuantityType.valueOf(vStatus.remainingRangeElectric, MetricPrefix.KILO(SIUnits.METRE))); + updateState(remainingRangeFuel, + QuantityType.valueOf(vStatus.remainingRangeFuel, MetricPrefix.KILO(SIUnits.METRE))); + updateState(remainingRange, QuantityType.valueOf( + vStatus.remainingRangeElectric + vStatus.remainingRangeFuel, MetricPrefix.KILO(SIUnits.METRE))); updateState(rangeRadius, - new DecimalType( - (bevRexAttributes.beRemainingRangeElectricKm + bevRexAttributes.beRemainingRangeFuelKm) - * 1000)); + new DecimalType((vStatus.remainingRangeElectric + vStatus.remainingRangeFuel) * 1000)); } else { - updateState(mileage, QuantityType.valueOf(bevRexAttributes.mileage, ImperialUnits.MILE)); + updateState(mileage, QuantityType.valueOf(vStatus.mileage, ImperialUnits.MILE)); updateState(remainingRangeElectric, - QuantityType.valueOf(bevRexAttributes.beRemainingRangeElectricMile, ImperialUnits.MILE)); + QuantityType.valueOf(vStatus.remainingRangeElectricMls, ImperialUnits.MILE)); updateState(remainingRangeFuel, - QuantityType.valueOf(bevRexAttributes.beRemainingRangeFuelMile, ImperialUnits.MILE)); + QuantityType.valueOf(vStatus.remainingRangeFuelMls, ImperialUnits.MILE)); updateState(remainingRange, QuantityType.valueOf( - bevRexAttributes.beRemainingRangeElectricMile + bevRexAttributes.beRemainingRangeFuelMile, - ImperialUnits.MILE)); - updateState(rangeRadius, new DecimalType( - (bevRexAttributes.beRemainingRangeElectricMile + bevRexAttributes.beRemainingRangeFuelMile) - * 1000)); + vStatus.remainingRangeElectricMls + vStatus.remainingRangeFuelMls, ImperialUnits.MILE)); + updateState(rangeRadius, + new DecimalType((vStatus.remainingRangeElectricMls + vStatus.remainingRangeFuelMls) * 1000)); } - updateState(remainingSoc, QuantityType.valueOf(bevRexAttributes.chargingLevelHv, SmartHomeUnits.PERCENT)); - updateState(remainingFuel, QuantityType.valueOf(bevRexAttributes.fuelPercent, SmartHomeUnits.PERCENT)); - updateState(lastUpdate, new StringType(bevRexAttributes.Segment_LastTrip_time_segment_end_formatted)); + updateState(remainingSoc, QuantityType.valueOf(vStatus.chargingLevelHv, SmartHomeUnits.PERCENT)); + updateState(remainingFuel, + QuantityType.valueOf(vStatus.remainingFuel * 100 / vStatus.maxFuel, SmartHomeUnits.PERCENT)); + + LocalDateTime datetime = LocalDateTime.parse(vStatus.internalDataTimeUTC, Converter.inputPattern); + updateState(lastUpdate, new StringType(datetime.format(Converter.outputPattern))); - updateState(longitude, new DecimalType(bevRexAttributes.gps_lng)); - updateState(latitude, new DecimalType(bevRexAttributes.gps_lat)); - updateState(latlong, new StringType(bevRexAttributes.gps_lat + "," + bevRexAttributes.gps_lng)); - logger.info("Update {} with {}", heading.toString(), bevRexAttributes.heading); - updateState(heading, QuantityType.valueOf(bevRexAttributes.heading, SmartHomeUnits.DEGREE_ANGLE)); - // updateState(headingChannleUID, new DecimalType(bevRexAttributes.heading)); + Position p = vStatus.position; + updateState(latitude, new DecimalType(p.lat)); + updateState(longitude, new DecimalType(p.lon)); + updateState(latlong, new StringType(p.lat + "," + p.lon)); + updateState(heading, QuantityType.valueOf(p.heading, SmartHomeUnits.DEGREE_ANGLE)); - bevRexAttributes.gps_lat = (float) 0.0; - bevRexAttributes.gps_lng = (float) 0.0; - vehicleFingerprint = GSON.toJson(bevRexAttributes); + vehicleFingerprint = GSON.toJson(vStatus); } else { vehicleFingerprint = content; logger.warn("No update of for {} which {}", driveTrain, CarType.ELECTRIC_REX.toString()); @@ -428,26 +374,34 @@ private void updateRangeStates(@Nullable String content) { public void getImage() { if (!tokenUpdate()) { + logger.warn("Car image Authorization failed"); + return; + } + ConnectedCarConfiguration localConfig = configuration; + if (localConfig == null) { + logger.warn("Car image cannot be retrieved without config data"); return; } - logger.info("Get image {}", imageAPI); - Request req = httpClient.newRequest(imageAPI); + Request req = httpClient.newRequest(imageAPI + "?width=" + localConfig.imageSize + "&height=" + + localConfig.imageSize + "&view=" + localConfig.imageViewport); req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); try { ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); - logger.info("getStatus {}", contentResponse.getStatus()); - logger.info("getMediaType {}", contentResponse.getMediaType()); + // logger.info("getStatus {}", contentResponse.getStatus()); + // logger.info("getMediaType {}", contentResponse.getMediaType()); byte[] image = contentResponse.getContent(); - updateState(imageChannel, new RawType(image, RawType.DEFAULT_MIME_TYPE)); + String contentType = HttpUtil.guessContentTypeFromData(image); + logger.info("Image Content Type {} Size {}", contentType, image.length); + updateState(imageChannel, new RawType(image, contentType)); } catch (InterruptedException | TimeoutException | ExecutionException e) { logger.warn("Get Data Exception {}", e.getMessage()); } } public synchronized boolean tokenUpdate() { - if (token.isExpired()) { + if (token.isExpired() || !token.isValid()) { token = bridgeHandler.getToken(); if (token.isExpired() || !token.isValid()) { logger.info("Token update failed!"); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java new file mode 100644 index 0000000000000..25cf62262d971 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.utils; + +import java.time.format.DateTimeFormatter; + +/** + * The {@link Converter} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class Converter { + public final static DateTimeFormatter inputPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); + public final static DateTimeFormatter outputPattern = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); + + public static double round(double value) { + double scale = Math.pow(10, 1); + return Math.round(value * scale) / scale; + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/conv-range-channel-groups.xml similarity index 66% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-groups.xml rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/conv-range-channel-groups.xml index cd6e0da2fa873..5f0b7509e4d9a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/conv-range-channel-groups.xml @@ -3,11 +3,14 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - + Provides values for the current Car Status, Electric charging state, remaining Range and more - + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-groups.xml new file mode 100644 index 0000000000000..111caf92779e4 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-groups.xml @@ -0,0 +1,16 @@ + + + + + Provides range, state of charge and fuel values + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-groups.xml index 88a4b11421ee0..063265cc0d372 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-groups.xml @@ -8,7 +8,6 @@ Provides an Image of your Car based on the given View direction - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml index 3c71f20bb881e..7a2847f1f6c75 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml @@ -7,21 +7,4 @@ Image - - trigger - - - - - - - - - - - - - - - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml new file mode 100644 index 0000000000000..9ade47b0fdaee --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml @@ -0,0 +1,54 @@ + + + + + + + + + + Electric Car + + + + + + + + + + + + + + BMW Car VIN + + + + Data Refresh Rate for your Car values + 5 + + + + Car Image size for width and length + + + + Viewport of Car Image + + + + + + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml index a548721367f26..f20194ede7137 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml @@ -10,7 +10,7 @@ - Car associated with the BMW Connected Drive Portal + Electric Car with Range Extender @@ -31,6 +31,24 @@ Data Refresh Rate for your Car values 5 + + + Car Image size for width and length + + + + Viewport of Car Image + + + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml new file mode 100644 index 0000000000000..a0db79c87443e --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml @@ -0,0 +1,52 @@ + + + + + + + + + + Conventional Fuel Car + + + + + + + + + + + + BMW Car VIN + + + + Data Refresh Rate for your Car values + 5 + + + + Car Image size for width and length + + + + Viewport of Car Image + + + + + + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml new file mode 100644 index 0000000000000..cac3d4fd2a0b2 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml @@ -0,0 +1,54 @@ + + + + + + + + + + Conventional Fuel Car with supporting Electric Engine + + + + + + + + + + + + + + BMW Car VIN + + + + Data Refresh Rate for your Car values + 5 + + + + Car Image size for width and length + + + + Viewport of Car Image + + + + + + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java index 21b635c58bfd3..c79ebca53f74a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java @@ -34,7 +34,7 @@ public class ConnectedDriveTest { @Test public void testUserInfo() { - String resource1 = FileReader.readFileInString("src/test/resources/connected-drive-account-info.json"); + String resource1 = FileReader.readFileInString("src/test/resources/webapi/connected-drive-account-info.json"); ConnectedDriveUserInfo userInfo = GSON.fromJson(resource1, ConnectedDriveUserInfo.class); List vehicles = userInfo.getVehicles(); assertEquals("Number of Vehicles", 1, vehicles.size()); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/EfficiencyTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/EfficiencyTest.java deleted file mode 100644 index 22156c8d3a2e0..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/EfficiencyTest.java +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; - -import static org.junit.Assert.assertEquals; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.junit.Test; -import org.openhab.binding.bmwconnecteddrive.internal.dto.efficiency.CharacterristicsScore; -import org.openhab.binding.bmwconnecteddrive.internal.dto.efficiency.Efficiency; -import org.openhab.binding.bmwconnecteddrive.internal.dto.efficiency.Score; -import org.openhab.binding.bmwconnecteddrive.internal.dto.efficiency.TripEntry; -import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; - -import com.google.gson.Gson; - -/** - * The {@link EfficiencyTest} Test json responses from ConnectedDrive Portal - * - * @author Bernd Weymann - Initial contribution - */ -@NonNullByDefault -public class EfficiencyTest { - private static final Gson GSON = new Gson(); - - @Test - public void testtestBEV_REX_Values() { - String resource1 = FileReader.readFileInString("src/test/resources/efficiency.json"); - Efficiency eff = GSON.fromJson(resource1, Efficiency.class); - - assertEquals("Community", false, eff.communitySwitch); - assertEquals("Quotient", 44, eff.efficiencyQuotient); - assertEquals("Model", "I3", eff.modelType); - - List scoreList = eff.scoreList; - assertEquals("Score List", 4, scoreList.size()); - List lastTripList = eff.lastTripList; - assertEquals("Score List", 5, lastTripList.size()); - List characteristicList = eff.characteristicList; - assertEquals("Score List", 5, characteristicList.size()); - - if (eff.lastTripList != null) { - eff.lastTripList.forEach(entry -> { - // logger.info(entry.name + ":" + entry.lastTrip); - if (entry.name.equals(TripEntry.LASTTRIP_DELTA_KM)) { - assertEquals("Trip Delta km", 2, entry.lastTrip, 0.01); - } else if (entry.name.equals(TripEntry.ACTUAL_DISTANCE_WITHOUT_CHARGING)) { - assertEquals("Charge Delta km", 31, entry.lastTrip, 0.01); - } else if (entry.name.equals(TripEntry.AVERAGE_ELECTRIC_CONSUMPTION)) { - assertEquals("Average Consumption", 14.5, entry.lastTrip, 0.01); - } else if (entry.name.equals(TripEntry.AVERAGE_RECUPERATED_ENERGY_PER_100_KM)) { - assertEquals("Average Recuperation", 8.0, entry.lastTrip, 0.01); - } - }); - } - if (eff.scoreList != null) { - eff.scoreList.forEach(entry -> { - if (entry.attrName.equals(Score.CUMULATED_ELECTRIC_DRIVEN_DISTANCE)) { - assertEquals("Trip Delta km", 16592.4, entry.lifeTime, 0.01); - } else if (entry.attrName.equals(Score.LONGEST_DISTANCE_WITHOUT_CHARGING)) { - assertEquals("Trip Delta km", 185.5, entry.lifeTime, 0.01); - } else if (entry.attrName.equals(Score.AVERAGE_ELECTRIC_CONSUMPTION)) { - assertEquals("Average Consumption", 16.5, entry.lifeTime, 0.01); - } else if (entry.attrName.equals(Score.AVERAGE_RECUPERATED_ENERGY_PER_100_KM)) { - assertEquals("Average Recuperation", 4.5, entry.lifeTime, 0.01); - } - }); - } - } -} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripTest.java new file mode 100644 index 0000000000000..3c5374ee63c3f --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripTest.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.statistics; + +import static org.junit.Assert.assertNotNull; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.junit.Test; +import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; + +import com.google.gson.Gson; + +/** + * The {@link LastTripTest} Test json responses from ConnectedDrive Portal + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class LastTripTest { + private static final Gson GSON = new Gson(); + + @Test + public void testUserInfo() { + String content = FileReader.readFileInString("src/test/resources/webapi/last-trip.json"); + LastTrip lt = GSON.fromJson(content, LastTrip.class); + Trip trip = lt.lastTrip; + assertNotNull(trip); + System.out.println(trip.totalDistance); + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexVehicleTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/BevRexVehicleTest.java similarity index 58% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexVehicleTest.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/BevRexVehicleTest.java index 482fadf7929b1..6edc85142c32b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/BevRexVehicleTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/BevRexVehicleTest.java @@ -10,13 +10,16 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.bmwconnecteddrive.internal.dto; +package org.openhab.binding.bmwconnecteddrive.internal.dto.status; import static org.junit.Assert.assertEquals; +import java.time.LocalDateTime; + import org.eclipse.jdt.annotation.NonNullByDefault; import org.junit.Test; import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import com.google.gson.Gson; @@ -31,10 +34,14 @@ public class BevRexVehicleTest { @Test public void testtestBEV_REX_Values() { - String resource1 = FileReader.readFileInString("src/test/resources/vehicle.json"); - BevRexAttributesMap attributesMap = GSON.fromJson(resource1, BevRexAttributesMap.class); - BevRexAttributes attributes = attributesMap.attributesMap; - assertEquals("Mileage", 17236.0, attributes.mileage, 0.1); - assertEquals("Heading", 41, attributes.heading, 0.0001); + String resource1 = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); + Status status = GSON.fromJson(resource1, Status.class); + VehicleStatus vStatus = status.vehicleStatus; + assertEquals("Mileage", 17273.0, vStatus.mileage, 0.1); + Position p = vStatus.position; + assertEquals("Heading", 219, p.heading); + + LocalDateTime datetime = LocalDateTime.parse(vStatus.internalDataTimeUTC, Converter.inputPattern); + assertEquals("Date", "24.08.2020 15:55", datetime.format(Converter.outputPattern)); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/efficiency.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/efficiency.json similarity index 100% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/efficiency.json rename to bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/efficiency.json diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/navigation.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/navigation.json similarity index 100% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/navigation.json rename to bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/navigation.json diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/test.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/test.json similarity index 100% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/test.json rename to bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/test.json diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/vehicle.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/vehicle.json similarity index 100% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/vehicle.json rename to bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/vehicle.json diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi-status.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/webapi-status.json similarity index 100% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi-status.json rename to bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/webapi-status.json diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/all-trips.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/all-trips.json new file mode 100644 index 0000000000000..3fe434ee6c21a --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/all-trips.json @@ -0,0 +1,40 @@ +{ + "allTrips": { + "avgElectricConsumption": { + "communityLow": 11.05, + "communityAverage": 16.28, + "communityHigh": 21.99, + "userAverage": 16.46 + }, + "avgRecuperation": { + "communityLow": 0.47, + "communityAverage": 3.37, + "communityHigh": 11.51, + "userAverage": 4.53 + }, + "chargecycleRange": { + "communityAverage": 194.21, + "communityHigh": 270, + "userAverage": 57.3, + "userHigh": 185.48, + "userCurrentChargeCycle": 68 + }, + "totalElectricDistance": { + "communityLow": 19, + "communityAverage": 40850.56, + "communityHigh": 193006, + "userTotal": 16629.4 + }, + "avgCombinedConsumption": { + "communityLow": 0, + "communityAverage": 0.92, + "communityHigh": 4.44, + "userAverage": 0.64 + }, + "savedCO2": 461.083, + "savedCO2greenEnergy": 2712.255, + "totalSavedFuel": 0, + "resetDate": "2020-08-24T14:40:40+0000", + "batterySizeMax": 33200 + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/charging-profile.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/charging-profile.json new file mode 100644 index 0000000000000..04dee7537f6b2 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/charging-profile.json @@ -0,0 +1,34 @@ +{ + "weeklyPlanner": { + "climatizationEnabled": false, + "chargingMode": "IMMEDIATE_CHARGING", + "chargingPreferences": "CHARGING_WINDOW", + "timer1": { + "departureTime": "05:00", + "timerEnabled": false, + "weekdays": [ + "MONDAY", + "TUESDAY", + "WEDNESDAY", + "THURSDAY", + "FRIDAY" + ] + }, + "timer2": { + "departureTime": "12:00", + "timerEnabled": false, + "weekdays": [ + "SATURDAY" + ] + }, + "timer3": { + "departureTime": "00:00", + "timerEnabled": false, + "weekdays": [] + }, + "preferredChargingWindow": { + "startTime": "00:00", + "endTime": "00:00" + } + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/connected-drive-account-info.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/connected-drive-account-info.json similarity index 100% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/connected-drive-account-info.json rename to bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/connected-drive-account-info.json diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/destinations.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/destinations.json new file mode 100644 index 0000000000000..0e993d22f7ebb --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/destinations.json @@ -0,0 +1,91 @@ +{ + "destinations": [ + { + "lat": 50.55577087402344, + "lon": 8.495763778686523, + "country": "DEUTSCHLAND", + "city": "WETZLAR", + "street": "UFERSTRASSE", + "streetNumber": "4", + "type": "DESTINATION", + "createdAt": "2020-08-16T12:52:58+0000" + }, + { + "lat": 50.539329528808594, + "lon": 8.25927734375, + "country": "DEUTSCHLAND", + "city": "LÖHNBERG", + "street": "RINGSTRASSE", + "streetNumber": "2", + "type": "DESTINATION", + "createdAt": "2020-08-12T17:03:35+0000" + }, + { + "lat": 50.22248840332031, + "lon": 8.548190116882324, + "country": "DEUTSCHLAND", + "city": "OBERURSEL (TAUNUS)", + "street": "FORSTHAUSWEG", + "streetNumber": "15", + "type": "DESTINATION", + "createdAt": "2020-08-03T08:15:20+0000" + }, + { + "lat": 51.48691940307617, + "lon": 9.385430335998535, + "country": "DEUTSCHLAND", + "city": "34369 HOFGEISMAR", + "street": "KELZER WEG", + "streetNumber": "22", + "type": "DESTINATION", + "createdAt": "2020-07-31T13:09:15+0000" + }, + { + "lat": 50.555870056152344, + "lon": 8.495736122131348, + "country": "DEUTSCHLAND", + "city": "WETZLAR", + "street": "UFERSTRASSE", + "streetNumber": "4", + "type": "DESTINATION", + "createdAt": "2020-07-25T11:20:18+0000" + }, + { + "lat": 50.78496170043945, + "lon": 8.761188507080078, + "country": "DEUTSCHLAND", + "city": "MARBURG", + "street": "BAHNHAUS", + "streetNumber": "1", + "type": "DESTINATION", + "createdAt": "2020-07-18T11:22:37+0000" + }, + { + "lat": 50.56787872314453, + "lon": 8.661417007446289, + "country": "DEUTSCHLAND", + "city": "GIESSEN", + "street": "CARL-FRANZ-STRASSE", + "type": "DESTINATION", + "createdAt": "2020-02-08T11:06:52+0000" + }, + { + "lat": 50.555763244628906, + "lon": 8.4972562789917, + "country": "DEUTSCHLAND", + "city": "WETZLAR", + "street": "HAARPLATZ", + "type": "DESTINATION", + "createdAt": "2020-02-02T14:07:54+0000" + }, + { + "lat": 50.44765853881836, + "lon": 8.516128540039062, + "country": "DEUTSCHLAND", + "city": "WALDSOLMS", + "street": "OBERGASSE", + "type": "DESTINATION", + "createdAt": "2020-02-02T13:24:36+0000" + } + ] +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/last-trip.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/last-trip.json new file mode 100644 index 0000000000000..d5ddc98512762 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/last-trip.json @@ -0,0 +1,19 @@ +{ + "lastTrip": { + "efficiencyValue": 0.98, + "totalDistance": 2, + "electricDistance": 2, + "avgElectricConsumption": 7, + "avgRecuperation": 6, + "drivingModeValue": 0.87, + "accelerationValue": 0.99, + "anticipationValue": 0.99, + "totalConsumptionValue": 1.25, + "auxiliaryConsumptionValue": 0.78, + "avgCombinedConsumption": 0, + "electricDistanceRatio": 100, + "savedFuel": 0, + "date": "2020-08-24T17:55:00+0000", + "duration": 5 + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status.json new file mode 100644 index 0000000000000..e747105d8d4f3 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status.json @@ -0,0 +1,76 @@ +{ + "vehicleStatus": { + "vin": "WBY1Z81040V905639", + "mileage": 17273, + "updateReason": "VEHICLE_SHUTDOWN_SECURED", + "updateTime": "2020-08-24T15:55:32+0000", + "doorDriverFront": "CLOSED", + "doorDriverRear": "CLOSED", + "doorPassengerFront": "CLOSED", + "doorPassengerRear": "CLOSED", + "windowDriverFront": "CLOSED", + "windowDriverRear": "CLOSED", + "windowPassengerFront": "CLOSED", + "windowPassengerRear": "CLOSED", + "sunroof": "CLOSED", + "trunk": "CLOSED", + "rearWindow": "INVALID", + "hood": "CLOSED", + "doorLockState": "SECURED", + "parkingLight": "OFF", + "positionLight": "ON", + "remainingFuel": 4, + "remainingRangeElectric": 148, + "remainingRangeElectricMls": 91, + "remainingRangeFuel": 70, + "remainingRangeFuelMls": 43, + "maxRangeElectric": 216, + "maxRangeElectricMls": 134, + "maxFuel": 8.5, + "connectionStatus": "DISCONNECTED", + "chargingStatus": "INVALID", + "chargingLevelHv": 71, + "lastChargingEndReason": "CHARGING_GOAL_REACHED", + "lastChargingEndResult": "SUCCESS", + "position": { + "lat": 50.55605, + "lon": 8.495669, + "heading": 219, + "status": "OK" + }, + "internalDataTimeUTC": "2020-08-24T15:55:32", + "singleImmediateCharging": false, + "chargingConnectionType": "CONDUCTIVE", + "chargingInductivePositioning": "NOT_POSITIONED", + "vehicleCountry": "DE", + "checkControlMessages": [], + "cbsData": [ + { + "cbsType": "BRAKE_FLUID", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next change due at the latest by the stated date." + }, + { + "cbsType": "VEHICLE_CHECK", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next visual inspection due when the stated distance has been covered or by the stated date." + }, + { + "cbsType": "OIL", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next change due when the stated distance has been covered or by the specified date." + }, + { + "cbsType": "VEHICLE_TUV", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next statutory vehicle inspection due by the stated date." + } + ], + "DCS_CCH_Activation": "NA", + "DCS_CCH_Ongoing": false + } +} \ No newline at end of file From 1de2bb567d43de7362a4fd1c9974fac5120827e2 Mon Sep 17 00:00:00 2001 From: Bernd Date: Wed, 26 Aug 2020 20:38:13 +0200 Subject: [PATCH 008/176] local date time conversion Signed-off-by: Bernd (cherry picked from commit 9294e53c5be20c8c69cd4cd8139bd6f616664a42) Signed-off-by: Bernd --- .../README.md | 10 + .../internal/ConnectedDriveConstants.java | 10 +- .../ConnectedDriveHandlerFactory.java | 8 +- .../internal/handler/BimmerConstants.java | 1 + .../handler/ConnectedCarChannelHandler.java | 4 +- .../internal/handler/ConnectedCarHandler.java | 141 ++++-- .../internal/utils/Converter.java | 21 +- .../thing/conv-range-channel-groups.xml | 6 +- .../ESH-INF/thing/ev-range-channel-groups.xml | 8 +- .../thing/hybrid-range-channel-groups.xml | 6 +- .../ESH-INF/thing/range-channel-types.xml | 4 +- .../resources/ESH-INF/thing/thing-bev.xml | 5 +- .../resources/ESH-INF/thing/thing-bev_rex.xml | 4 + ...ehicleTest.java => VehicleStatusTest.java} | 10 +- .../internal/handler/CarTests.java | 74 ++++ .../internal/util/LocaleTest.java | 52 +++ .../test/resources/responses/F15/status.json | 66 +++ .../test/resources/responses/F31/status.json | 14 + .../test/resources/responses/F35/status.json | 12 + .../test/resources/responses/F45/status.json | 12 + .../test/resources/responses/F48/status.json | 62 +++ .../responses/G31_NBTevo/auth_response.json | 7 + .../responses/G31_NBTevo/flash_delivered.json | 10 + .../responses/G31_NBTevo/flash_executed.json | 11 + .../responses/G31_NBTevo/flash_initiated.json | 7 + .../responses/G31_NBTevo/flash_pending.json | 10 + .../responses/G31_NBTevo/status.json | 55 +++ .../G31_NBTevo/status_position_disabled.json | 52 +++ .../resources/responses/I01_NOREX/status.json | 61 +++ .../resources/responses/I01_REX/status.json | 61 +++ .../test/resources/responses/vehicles.json | 407 ++++++++++++++++++ .../webapi/vehicle-status-charging.json | 77 ++++ .../test3.json | 76 ++++ 33 files changed, 1294 insertions(+), 70 deletions(-) rename bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/{BevRexVehicleTest.java => VehicleStatusTest.java} (75%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F15/status.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F31/status.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F35/status.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F45/status.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F48/status.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/auth_response.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/flash_delivered.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/flash_executed.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/flash_initiated.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/flash_pending.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/status.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/status_position_disabled.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_NOREX/status.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/status.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/vehicles.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status-charging.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/test3.json diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index af3c37315896b..bd703e1caccc3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -14,6 +14,16 @@ _Note that it is planned to generate some part of this based on the XML files wi _Describe the available auto-discovery features here. Mention for what it works and what needs to be kept in mind when using it._ +## TroubleShooting + +### Discovery + +### Car Data + +### Update Timestamp + +Check your Locale Time Settings of your Raspi / PC + ## Binding Configuration _If your binding requires or supports general configuration settings, please create a folder ```cfg``` and place the configuration file ```.cfg``` inside it. In this section, you should link to this file and provide some information about the options. The file could e.g. look like:_ diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index b5bd44bce5fba..922effab4627d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -64,6 +64,14 @@ public String toString() { } }; + // Countries with Mileage display + public static final Set MILE_COUNTRIES = new HashSet() { + { + add("US"); + add("GB"); + } + }; + // List of all Thing Type UIDs public static final ThingTypeUID THING_TYPE_CONNECTED_DRIVE_ACCOUNT = new ThingTypeUID(BINDING_ID, "account"); public static final ThingTypeUID THING_TYPE_CONV = new ThingTypeUID(BINDING_ID, CarType.CONVENTIONAL.toString()); @@ -118,7 +126,7 @@ public String toString() { // Range public static final String MILEAGE = "mileage"; - public static final String REMAINING_RANGE = "remaining-range"; + public static final String REMAINING_RANGE_HYBRID = "remaining-range-hybrid"; public static final String REMAINING_RANGE_ELECTRIC = "remaining-range-electric"; public static final String REMAINING_SOC = "remaining-soc"; public static final String REMAINING_RANGE_FUEL = "remaining-range-fuel"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java index 14be9b79a0957..7dd503ffa8a02 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java @@ -16,6 +16,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.i18n.LocaleProvider; import org.eclipse.smarthome.core.thing.Bridge; import org.eclipse.smarthome.core.thing.Thing; import org.eclipse.smarthome.core.thing.ThingTypeUID; @@ -40,10 +41,12 @@ public class ConnectedDriveHandlerFactory extends BaseThingHandlerFactory { private final HttpClientFactory httpClientFactory; + private boolean imperial = false; @Activate - public ConnectedDriveHandlerFactory(final @Reference HttpClientFactory hcf) { + public ConnectedDriveHandlerFactory(final @Reference HttpClientFactory hcf, final @Reference LocaleProvider lp) { httpClientFactory = hcf; + imperial = MILE_COUNTRIES.contains(lp.getLocale().getCountry()); } @Override @@ -58,7 +61,8 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { return new ConnectedDriveBridgeHandler((Bridge) thing, httpClientFactory.getCommonHttpClient(), bundleContext); } else if (SUPPORTED_THING_SET.contains(thingTypeUID)) { - return new ConnectedCarHandler(thing, httpClientFactory.getCommonHttpClient(), thingTypeUID.getId()); + return new ConnectedCarHandler(thing, httpClientFactory.getCommonHttpClient(), thingTypeUID.getId(), + imperial); } return null; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BimmerConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BimmerConstants.java index c904318a7e862..4c47e26c7d362 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BimmerConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BimmerConstants.java @@ -22,6 +22,7 @@ * are taken from the Bimmercode from github {@link https://github.com/bimmerconnected/bimmer_connected} * File defining these constants * {@link https://github.com/bimmerconnected/bimmer_connected/blob/master/bimmer_connected/account.py} + * https://customer.bmwgroup.com/one/app/oauth.js * * @author Bernd Weymann - Initial contribution */ diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java index 2021cf1eab334..d48d49fea0faf 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java @@ -49,7 +49,7 @@ public class ConnectedCarChannelHandler extends BaseThingHandler { // Vehcile channels protected ChannelUID mileage; - protected ChannelUID remainingRange; + protected ChannelUID remainingRangeHybrid; protected ChannelUID remainingRangeElectric; protected ChannelUID remainingSoc; protected ChannelUID remainingRangeFuel; @@ -108,7 +108,7 @@ public ConnectedCarChannelHandler(Thing thing) { // range Channels mileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, MILEAGE); - remainingRange = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_RANGE); + remainingRangeHybrid = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_RANGE_HYBRID); remainingRangeElectric = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_RANGE_ELECTRIC); remainingSoc = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_SOC); remainingRangeFuel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_RANGE_FUEL); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java index 67ff14fb9be83..0133546c946b0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java @@ -12,10 +12,9 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.handler; -import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CARDATA_FINGERPRINT; +import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; import static org.openhab.binding.bmwconnecteddrive.internal.handler.HTTPConstants.CONTENT_TYPE_JSON; -import java.time.LocalDateTime; import java.util.concurrent.ExecutionException; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -74,6 +73,10 @@ public class ConnectedCarHandler extends ConnectedCarChannelHandler { private String driveTrain; private HttpClient httpClient; private Token token = new Token(); + private boolean imperial = false; + private boolean hasFuel = false; + private boolean isElectric = false; + private boolean isHybrid = false; private @Nullable ConnectedCarConfiguration configuration; private @Nullable ConnectedDriveBridgeHandler bridgeHandler; @@ -90,16 +93,40 @@ public class ConnectedCarHandler extends ConnectedCarChannelHandler { private @Nullable String chargeAPI; private @Nullable String destinationAPI; - public ConnectedCarHandler(Thing thing, HttpClient hc, String type) { + private @Nullable String vehicleStatusCache; + private @Nullable String lastTripCache; + private @Nullable String allTripsCache; + + public ConnectedCarHandler(Thing thing, HttpClient hc, String type, boolean imperial) { super(thing); httpClient = hc; driveTrain = type; + this.imperial = imperial; + hasFuel = type.equals(CarType.CONVENTIONAL.toString()) || type.equals(CarType.PLUGIN_HYBRID.toString()) + || type.equals(CarType.ELECTRIC_REX.toString()); + isElectric = type.equals(CarType.PLUGIN_HYBRID.toString()) || type.equals(CarType.ELECTRIC_REX.toString()) + || type.equals(CarType.ELECTRIC.toString()); + isHybrid = hasFuel && isElectric; + logger.info("DriveTrain {} isElectric {} hasFuel {} Imperial {}", type, isElectric, hasFuel, imperial); } @Override public void handleCommand(ChannelUID channelUID, Command command) { if (command instanceof RefreshType) { String group = channelUID.getGroupId(); + if (CHANNEL_GROUP_LAST_TRIP.equals(group)) { + if (lastTripCache != null) { + updateLastTrip(lastTripCache); + } + } else if (CHANNEL_GROUP_LIFETIME.equals(group)) { + if (allTripsCache != null) { + updateTripStatistics(allTripsCache); + } + } else { + if (vehicleStatusCache != null) { + updateVehicleStatus(vehicleStatusCache); + } + } logger.info("REFRESH {}", group); } else { logger.info("No refresh"); @@ -291,7 +318,9 @@ public void getData() { private void updateTripStatistics(@Nullable String content) { if (content == null) { logger.warn("No Vehicle Values available"); + return; } + allTripsCache = content; AllTrips at = GSON.fromJson(content, AllTrips.class); Community c = at.allTrips; updateState(lifeTimeCumulatedDrivenDistance, QuantityType @@ -309,7 +338,9 @@ private void updateTripStatistics(@Nullable String content) { private void updateLastTrip(@Nullable String content) { if (content == null) { logger.warn("No Vehicle Values available"); + return; } + lastTripCache = content; LastTrip lt = GSON.fromJson(content, LastTrip.class); Trip trip = lt.lastTrip; updateState(tripDistance, @@ -322,54 +353,79 @@ private void updateLastTrip(@Nullable String content) { QuantityType.valueOf(Converter.round(trip.avgRecuperation), SmartHomeUnits.KILOWATT_HOUR)); } - private void updateVehicleStatus(@Nullable String content) { + void updateVehicleStatus(@Nullable String content) { if (content == null) { logger.warn("No Vehicle Values available"); + return; } - if (driveTrain.equals(CarType.ELECTRIC_REX.toString())) { - Status status = GSON.fromJson(content, Status.class); - VehicleStatus vStatus = status.vehicleStatus; - logger.info("Update Milage {} Channel {}", vStatus.mileage, mileage.toString()); - // based on unit of length decide if range shall be reported in km or miles - if (true) { - updateState(mileage, QuantityType.valueOf(vStatus.mileage, MetricPrefix.KILO(SIUnits.METRE))); + vehicleStatusCache = content; + logger.info("Vehicle Status {}", content); + Status status = GSON.fromJson(content, Status.class); + VehicleStatus vStatus = status.vehicleStatus; + logger.info("Update Milage {} Channel {}", vStatus.mileage, mileage.toString()); + // based on unit of length decide if range shall be reported in km or miles + if (!imperial) { + updateState(mileage, QuantityType.valueOf(vStatus.mileage, MetricPrefix.KILO(SIUnits.METRE))); + float totalRange = 0; + if (isElectric) { + totalRange += vStatus.remainingRangeElectric; updateState(remainingRangeElectric, QuantityType.valueOf(vStatus.remainingRangeElectric, MetricPrefix.KILO(SIUnits.METRE))); + logger.info("updated {} {}", remainingRangeElectric, vStatus.remainingRangeElectric); + } else { + logger.info("{} not updated", remainingRangeElectric); + } + if (hasFuel) { + totalRange += vStatus.remainingRangeFuel; updateState(remainingRangeFuel, QuantityType.valueOf(vStatus.remainingRangeFuel, MetricPrefix.KILO(SIUnits.METRE))); - updateState(remainingRange, QuantityType.valueOf( - vStatus.remainingRangeElectric + vStatus.remainingRangeFuel, MetricPrefix.KILO(SIUnits.METRE))); - updateState(rangeRadius, - new DecimalType((vStatus.remainingRangeElectric + vStatus.remainingRangeFuel) * 1000)); + logger.info("updated {} {}", remainingRangeFuel, vStatus.remainingRangeFuel); } else { - updateState(mileage, QuantityType.valueOf(vStatus.mileage, ImperialUnits.MILE)); + logger.info("{} not updated", remainingRangeFuel); + } + if (isHybrid) { + updateState(remainingRangeHybrid, + QuantityType.valueOf(Converter.round(totalRange), MetricPrefix.KILO(SIUnits.METRE))); + } + updateState(rangeRadius, new DecimalType((totalRange) * 1000)); + } else { + updateState(mileage, QuantityType.valueOf(vStatus.mileage, ImperialUnits.MILE)); + float totalRange = 0; + if (isElectric) { + totalRange += vStatus.remainingRangeElectricMls; updateState(remainingRangeElectric, QuantityType.valueOf(vStatus.remainingRangeElectricMls, ImperialUnits.MILE)); + } + if (hasFuel) { + totalRange = vStatus.remainingRangeFuelMls; updateState(remainingRangeFuel, QuantityType.valueOf(vStatus.remainingRangeFuelMls, ImperialUnits.MILE)); - updateState(remainingRange, QuantityType.valueOf( - vStatus.remainingRangeElectricMls + vStatus.remainingRangeFuelMls, ImperialUnits.MILE)); - updateState(rangeRadius, - new DecimalType((vStatus.remainingRangeElectricMls + vStatus.remainingRangeFuelMls) * 1000)); } + if (isHybrid) { + updateState(remainingRangeHybrid, QuantityType.valueOf(Converter.round(totalRange), ImperialUnits.MILE)); + } + updateState(rangeRadius, new DecimalType((totalRange) * 5280)); // Miles to feet + } + if (isElectric) { updateState(remainingSoc, QuantityType.valueOf(vStatus.chargingLevelHv, SmartHomeUnits.PERCENT)); + } + if (hasFuel) { updateState(remainingFuel, QuantityType.valueOf(vStatus.remainingFuel * 100 / vStatus.maxFuel, SmartHomeUnits.PERCENT)); + logger.info("updated {} {}", remainingFuel, vStatus.remainingFuel * 100 / vStatus.maxFuel); + } else { + logger.info("{} not updated", remainingRangeFuel); + } - LocalDateTime datetime = LocalDateTime.parse(vStatus.internalDataTimeUTC, Converter.inputPattern); - updateState(lastUpdate, new StringType(datetime.format(Converter.outputPattern))); + updateState(lastUpdate, new StringType(Converter.getLocalDateTime(vStatus.internalDataTimeUTC))); - Position p = vStatus.position; - updateState(latitude, new DecimalType(p.lat)); - updateState(longitude, new DecimalType(p.lon)); - updateState(latlong, new StringType(p.lat + "," + p.lon)); - updateState(heading, QuantityType.valueOf(p.heading, SmartHomeUnits.DEGREE_ANGLE)); + Position p = vStatus.position; + updateState(latitude, new DecimalType(p.lat)); + updateState(longitude, new DecimalType(p.lon)); + updateState(latlong, new StringType(p.lat + "," + p.lon)); + updateState(heading, QuantityType.valueOf(p.heading, SmartHomeUnits.DEGREE_ANGLE)); - vehicleFingerprint = GSON.toJson(vStatus); - } else { - vehicleFingerprint = content; - logger.warn("No update of for {} which {}", driveTrain, CarType.ELECTRIC_REX.toString()); - } + vehicleFingerprint = GSON.toJson(vStatus); } public void getImage() { @@ -383,18 +439,23 @@ public void getImage() { return; } - Request req = httpClient.newRequest(imageAPI + "?width=" + localConfig.imageSize + "&height=" - + localConfig.imageSize + "&view=" + localConfig.imageViewport); + String localImageUrl = imageAPI + "?width=" + localConfig.imageSize + "&height=" + localConfig.imageSize + + "&view=" + localConfig.imageViewport; + Request req = httpClient.newRequest(localImageUrl); req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); try { ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); - // logger.info("getStatus {}", contentResponse.getStatus()); - // logger.info("getMediaType {}", contentResponse.getMediaType()); - byte[] image = contentResponse.getContent(); - String contentType = HttpUtil.guessContentTypeFromData(image); - logger.info("Image Content Type {} Size {}", contentType, image.length); - updateState(imageChannel, new RawType(image, contentType)); + if (contentResponse.getStatus() != 200) { + logger.info("URL {}", localImageUrl); + logger.info("Status {}", contentResponse.getStatus()); + logger.info("Reason {}", contentResponse.getReason()); + } else { + byte[] image = contentResponse.getContent(); + String contentType = HttpUtil.guessContentTypeFromData(image); + logger.info("Image Content Type {} Size {}", contentType, image.length); + updateState(imageChannel, new RawType(image, contentType)); + } } catch (InterruptedException | TimeoutException | ExecutionException e) { logger.warn("Get Data Exception {}", e.getMessage()); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java index 25cf62262d971..e6f7e04fbcfdf 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java @@ -12,19 +12,36 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.utils; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * The {@link Converter} Data Transfer Object * * @author Bernd Weymann - Initial contribution */ public class Converter { - public final static DateTimeFormatter inputPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); - public final static DateTimeFormatter outputPattern = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); + private final static Logger logger = LoggerFactory.getLogger(Converter.class); + private final static DateTimeFormatter inputPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); + private final static DateTimeFormatter outputPattern = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); public static double round(double value) { double scale = Math.pow(10, 1); return Math.round(value * scale) / scale; } + + public static String getLocalDateTime(String input) { + LocalDateTime ldt = LocalDateTime.parse(input, Converter.inputPattern); + logger.info("Update Local DateTime {}", ldt); + ZonedDateTime zdtUTC = ldt.atZone(ZoneId.of("UTC")); + logger.info("Update UTC DateTime {}", zdtUTC); + ZonedDateTime zdtLZ = zdtUTC.withZoneSameInstant(ZoneId.systemDefault()); + logger.info("Update UTC DateTime {}", zdtLZ); + return zdtLZ.format(Converter.outputPattern); + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/conv-range-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/conv-range-channel-groups.xml index 5f0b7509e4d9a..c15efc5d65cc6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/conv-range-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/conv-range-channel-groups.xml @@ -4,11 +4,11 @@ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - - Provides values for the current Car Status, Electric charging state, remaining Range and more + + Provides Mileage, remaining range and fuel level values - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-groups.xml index 111caf92779e4..b09a63e77b55d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-groups.xml @@ -3,12 +3,12 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - - - Provides range, state of charge and fuel values + + + Provides Mileage, remaining range and charge level values - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-range-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-range-channel-groups.xml index b987b64468f98..7810170baa6ba 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-range-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-range-channel-groups.xml @@ -4,11 +4,11 @@ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - - Provides range, state of charge and fuel values + + Provides Mileage, remaining range and fuel and charge level values - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml index 6be20e3a59921..d97cd4bc73a3f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml @@ -7,9 +7,9 @@ Number:Length - + Number:Length - + Number:Length diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml index 9ade47b0fdaee..842b64afd8e2c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml @@ -13,7 +13,7 @@ Electric Car - + @@ -43,10 +43,9 @@ - + - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml index f20194ede7137..f907fea8ca537 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml @@ -21,6 +21,10 @@ + + BMW_I + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/BevRexVehicleTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusTest.java similarity index 75% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/BevRexVehicleTest.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusTest.java index 6edc85142c32b..fbff22419609c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/BevRexVehicleTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusTest.java @@ -14,22 +14,19 @@ import static org.junit.Assert.assertEquals; -import java.time.LocalDateTime; - import org.eclipse.jdt.annotation.NonNullByDefault; import org.junit.Test; import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; -import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import com.google.gson.Gson; /** - * The {@link BevRexVehicleTest} Test json responses from ConnectedDrive Portal + * The {@link VehicleStatusTest} Test json responses from ConnectedDrive Portal * * @author Bernd Weymann - Initial contribution */ @NonNullByDefault -public class BevRexVehicleTest { +public class VehicleStatusTest { private static final Gson GSON = new Gson(); @Test @@ -40,8 +37,5 @@ public void testtestBEV_REX_Values() { assertEquals("Mileage", 17273.0, vStatus.mileage, 0.1); Position p = vStatus.position; assertEquals("Heading", 219, p.heading); - - LocalDateTime datetime = LocalDateTime.parse(vStatus.internalDataTimeUTC, Converter.inputPattern); - assertEquals("Date", "24.08.2020 15:55", datetime.format(Converter.outputPattern)); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java new file mode 100644 index 0000000000000..d339e8466c7e4 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; + +import java.util.List; + +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.smarthome.core.thing.ChannelUID; +import org.eclipse.smarthome.core.thing.Thing; +import org.eclipse.smarthome.core.thing.ThingUID; +import org.eclipse.smarthome.core.thing.binding.ThingHandlerCallback; +import org.eclipse.smarthome.core.types.State; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CarType; +import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link CarTests} is responsible for handling commands, which are + * sent to one of the channels. + * + * @author Bernd Weymann - Initial contribution + */ +public class CarTests { + private final Logger logger = LoggerFactory.getLogger(ConnectedCarHandler.class); + // ConnectedCarHandler cch = new Co + + @Before + public void setup() { + } + + @Test + public void testF15() { + String content = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); + Thing thing = mock(Thing.class); + when(thing.getUID()).thenReturn(new ThingUID("testbinding", "test")); + HttpClient hc = mock(HttpClient.class); + ConnectedCarHandler cch = new ConnectedCarHandler(thing, hc, CarType.ELECTRIC_REX.toString(), true); + ThingHandlerCallback tc = mock(ThingHandlerCallback.class); + cch.setCallback(tc); + cch.updateVehicleStatus(content); + + ArgumentCaptor channelCaptor = ArgumentCaptor.forClass(ChannelUID.class); + ArgumentCaptor stateCaptor = ArgumentCaptor.forClass(State.class); + ; + + // ArgumentCaptor> channelCaptor; + // ArgumentCaptor> stateCaptor; + + verify(tc, times(12)).stateUpdated(channelCaptor.capture(), stateCaptor.capture()); + List allChannels = channelCaptor.getAllValues(); + List allStates = stateCaptor.getAllValues(); + assertEquals("Results ", 12, allChannels.size()); + for (int i = 0; i < allChannels.size(); i++) { + logger.info("Channel {} {}", allChannels.get(i), allStates.get(i)); + } + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java new file mode 100644 index 0000000000000..fd045979f6de2 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.util; + +import static org.junit.Assert.*; + +import java.util.Locale; + +import org.junit.Test; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Status; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; + +import com.google.gson.Gson; + +/** + * The {@link LocaleTest} is responsible for handling commands, which are + * sent to one of the channels. + * + * @author Bernd Weymann - Initial contribution + */ +public class LocaleTest { + private static final Gson GSON = new Gson(); + + @Test + public void languageTest() { + assertTrue("United Kingdom", ConnectedDriveConstants.MILE_COUNTRIES.contains(Locale.UK.getCountry())); + assertTrue("United States", ConnectedDriveConstants.MILE_COUNTRIES.contains(Locale.US.getCountry())); + assertFalse("France", ConnectedDriveConstants.MILE_COUNTRIES.contains(Locale.FRANCE.getCountry())); + assertFalse("Germany", ConnectedDriveConstants.MILE_COUNTRIES.contains(Locale.GERMAN.getCountry())); + } + + @Test + public void testTimeUTCToLocaleTime() { + String resource1 = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); + Status status = GSON.fromJson(resource1, Status.class); + VehicleStatus vStatus = status.vehicleStatus; + assertEquals("Input DateTime", "2020-08-24T15:55:32", vStatus.internalDataTimeUTC); + assertEquals("Output DateTime", "24.08.2020 17:55", Converter.getLocalDateTime(vStatus.internalDataTimeUTC)); + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F15/status.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F15/status.json new file mode 100644 index 0000000000000..6d55f0bfbbd4c --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F15/status.json @@ -0,0 +1,66 @@ +{ + "vehicleStatus" : { + "doorPassengerFront" : "CLOSED", + "cbsData" : [ { + "cbsState" : "OK", + "cbsRemainingMileage" : 47000, + "cbsDescription" : "Next change due at the latest when the stated distance has been covered.", + "cbsType" : "BRAKE_PADS_FRONT" + }, { + "cbsState" : "OK", + "cbsRemainingMileage" : 46000, + "cbsDescription" : "Next change due at the latest when the stated distance has been covered.", + "cbsType" : "BRAKE_PADS_REAR" + }, { + "cbsDueDate" : "2018-06", + "cbsState" : "OK", + "cbsRemainingMileage" : 12000, + "cbsDescription" : "Next service due when the stated distance has been covered or by the specified date.", + "cbsType" : "OIL" + }, { + "cbsDueDate" : "2021-06", + "cbsState" : "OK", + "cbsRemainingMileage" : 50000, + "cbsDescription" : "Next visual inspection due when the stated distance has been covered or by the stated date.", + "cbsType" : "VEHICLE_CHECK" + }, { + "cbsDueDate" : "2020-04", + "cbsState" : "OK", + "cbsDescription" : "Next change due at the latest by the stated date.", + "cbsType" : "BRAKE_FLUID" + } ], + "windowDriverFront" : "CLOSED", + "DCS_CCH_Ongoing" : false, + "updateReason" : "VEHICLE_SHUTDOWN", + "rearWindow" : "INVALID", + "remainingRangeFuelMls" : 154, + "DCS_CCH_Activation" : "NA", + "singleImmediateCharging" : false, + "positionLight" : "OFF", + "vin" : "F15_VIN", + "doorDriverFront" : "CLOSED", + "mileage" : 1629, + "checkControlMessages" : [ ], + "parkingLight" : "OFF", + "windowDriverRear" : "CLOSED", + "steering" : "LH", + "updateTime" : "2018-03-08T22:21:39-0500", + "remainingFuel" : 30, + "windowPassengerRear" : "CLOSED", + "trunk" : "CLOSED", + "hood" : "CLOSED", + "internalDataTimeUTC" : "2018-03-09T03:21:39", + "windowPassengerFront" : "CLOSED", + "doorLockState" : "UNLOCKED", + "doorPassengerRear" : "CLOSED", + "remainingRangeFuel" : 249, + "doorDriverRear" : "CLOSED", + "sunroof" : "CLOSED", + "position" : { + "heading" : 11, + "lon" : -123.123, + "lat" : 123.123, + "status" : "OK" + } + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F31/status.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F31/status.json new file mode 100644 index 0000000000000..1f6b6d53324aa --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F31/status.json @@ -0,0 +1,14 @@ +{ + "DCS_CCH_Activation": "NA", + "DCS_CCH_Ongoing": false, + "vehicleStatus": { + "position": { + "lat": 12.3456, + "lon": 34.5678, + "status": "OK" + }, + "steering": "RH", + "updateTime": "2018-07-25T16:02:04+0200", + "vin": "F31_VIN" + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F35/status.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F35/status.json new file mode 100644 index 0000000000000..2dd6a25df58a6 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F35/status.json @@ -0,0 +1,12 @@ +{ + "vehicleStatus": { + "DCS_CCH_Activation": "NA", + "DCS_CCH_Ongoing": false, + "position": { + "status": "DRIVER_DISABLED" + }, + "updateTime": "2018-07-16T21:47:46+0000", + "vehicleCountry": "CN", + "vin": "some_vin" + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F45/status.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F45/status.json new file mode 100644 index 0000000000000..3328f50f86e2b --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F45/status.json @@ -0,0 +1,12 @@ +{ + "vehicleStatus": { + "position": { + "lat": 12.3456, + "lon": 34.5678, + "status": "OK" + }, + "steering": "LH", + "updateTime": "2018-04-06T13:56:47+0200", + "vin": "F45_vin" + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F48/status.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F48/status.json new file mode 100644 index 0000000000000..df3772a70e7eb --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F48/status.json @@ -0,0 +1,62 @@ +{ + "vehicleStatus" : { + "doorPassengerFront" : "CLOSED", + "cbsData" : [ { + "cbsDueDate" : "2019-07", + "cbsState" : "OK", + "cbsRemainingMileage" : 9000, + "cbsDescription" : "Next service due when the stated distance has been covered or by the specified date.", + "cbsType" : "OIL" + }, { + "cbsDueDate" : "2021-07", + "cbsState" : "OK", + "cbsRemainingMileage" : 39000, + "cbsDescription" : "Next visual inspection due when the stated distance has been covered or by the stated date.", + "cbsType" : "VEHICLE_CHECK" + }, { + "cbsDueDate" : "2020-07", + "cbsState" : "OK", + "cbsDescription" : "Next change due at the latest by the stated date.", + "cbsType" : "BRAKE_FLUID" + } ], + "windowDriverFront" : "CLOSED", + "DCS_CCH_Ongoing" : false, + "updateReason" : "DOOR_STATE_CHANGED", + "rearWindow" : "INVALID", + "remainingRangeFuelMls" : 366, + "DCS_CCH_Activation" : "NA", + "singleImmediateCharging" : false, + "positionLight" : "OFF", + "vin" : "F48_VIN", + "doorDriverFront" : "CLOSED", + "mileage" : 21529, + "checkControlMessages": [ + { + "ccmDescriptionLong": "You can continue driving. Check tyre pressure when tyres are cold and adjust if necessary. Perform reset after adjustment. See Owner's Handbook for further information.", + "ccmDescriptionShort": "Tyre pressure notification", + "ccmId": 955, + "ccmMileage": 41544 + } + ], + "parkingLight" : "OFF", + "windowDriverRear" : "CLOSED", + "steering" : "LH", + "updateTime" : "2018-03-10T19:35:30+0100", + "remainingFuel" : 39, + "windowPassengerRear" : "CLOSED", + "trunk" : "CLOSED", + "hood" : "CLOSED", + "internalDataTimeUTC" : "2018-03-10T18:35:30", + "windowPassengerFront" : "CLOSED", + "doorLockState" : "SECURED", + "doorPassengerRear" : "CLOSED", + "remainingRangeFuel" : 590, + "doorDriverRear" : "CLOSED", + "position" : { + "heading" : 141, + "lon" : 10.1010101, + "lat" : 50.505050, + "status" : "OK" + } + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/auth_response.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/auth_response.json new file mode 100644 index 0000000000000..556144689ff01 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/auth_response.json @@ -0,0 +1,7 @@ +{ + "access_token": "some_token_string", + "token_type": "Bearer", + "expires_in": 28799, + "refresh_token": "another_token_string", + "scope": "authenticate_user vehicle_data remote_services" +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/flash_delivered.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/flash_delivered.json new file mode 100644 index 0000000000000..f341d84cbe5fb --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/flash_delivered.json @@ -0,0 +1,10 @@ +{ + "executionStatus" : { + "serviceType" : "LIGHT_FLASH", + "eventId" : "424C39333232312237B3E900@bmw.de", + "extendedStatus" : { + "result" : "STATUS_UNKNOWN" + }, + "status" : "DELIVERED" + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/flash_executed.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/flash_executed.json new file mode 100644 index 0000000000000..88d379aaa31cd --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/flash_executed.json @@ -0,0 +1,11 @@ +{ + "executionStatus" : { + "serviceType" : "LIGHT_FLASH", + "eventId" : "424C39333232312237B3E900@bmw.de", + "extendedStatus" : { + "result" : "STATUS_CHANGED", + "ignitionOnStatus" : "false" + }, + "status" : "EXECUTED" + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/flash_initiated.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/flash_initiated.json new file mode 100644 index 0000000000000..392713e47457e --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/flash_initiated.json @@ -0,0 +1,7 @@ +{ + "executionStatus" : { + "serviceType" : "LIGHT_FLASH", + "eventId" : "424C39333232312237B3E900@bmw.de", + "status" : "INITIATED" + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/flash_pending.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/flash_pending.json new file mode 100644 index 0000000000000..c338477fa5365 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/flash_pending.json @@ -0,0 +1,10 @@ +{ + "executionStatus" : { + "serviceType" : "LIGHT_FLASH", + "eventId" : "424C39333232312237B3E900@bmw.de", + "extendedStatus" : { + "result" : "STATUS_UNKNOWN" + }, + "status" : "PENDING" + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/status.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/status.json new file mode 100644 index 0000000000000..fc284ff1c875e --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/status.json @@ -0,0 +1,55 @@ +{ + "vehicleStatus" : { + "doorPassengerFront" : "CLOSED", + "cbsData" : [ { + "cbsDueDate" : "2020-01", + "cbsState" : "OK", + "cbsRemainingMileage" : 25000, + "cbsDescription" : "Next service due when the stated distance has been covered or by the specified date.", + "cbsType" : "OIL" + }, { + "cbsDueDate" : "2022-01", + "cbsState" : "OK", + "cbsRemainingMileage" : 60000, + "cbsDescription" : "Next visual inspection due when the stated distance has been covered or by the stated date.", + "cbsType" : "VEHICLE_CHECK" + }, { + "cbsDueDate" : "2021-01", + "cbsState" : "OK", + "cbsDescription" : "Next change due at the latest by the stated date.", + "cbsType" : "BRAKE_FLUID" + } ], + "windowDriverFront" : "CLOSED", + "DCS_CCH_Ongoing" : false, + "updateReason" : "VEHICLE_SHUTDOWN", + "rearWindow" : "CLOSED", + "remainingRangeFuelMls" : 199, + "DCS_CCH_Activation" : "NA", + "singleImmediateCharging" : false, + "positionLight" : "OFF", + "vin" : "G31_NBTevo_VIN", + "doorDriverFront" : "CLOSED", + "mileage" : 4126, + "checkControlMessages" : [ ], + "parkingLight" : "OFF", + "windowDriverRear" : "CLOSED", + "steering" : "LH", + "updateTime" : "2018-03-10T11:39:41+0100", + "remainingFuel" : 33, + "windowPassengerRear" : "CLOSED", + "trunk" : "CLOSED", + "hood" : "CLOSED", + "internalDataTimeUTC" : "2018-03-10T10:39:41", + "windowPassengerFront" : "CLOSED", + "doorLockState" : "SECURED", + "doorPassengerRear" : "CLOSED", + "remainingRangeFuel" : 321, + "doorDriverRear" : "CLOSED", + "position" : { + "heading" : 174, + "lon" : 10.1010, + "lat" : 50.5050, + "status" : "OK" + } + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/status_position_disabled.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/status_position_disabled.json new file mode 100644 index 0000000000000..94b25704f69a6 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/G31_NBTevo/status_position_disabled.json @@ -0,0 +1,52 @@ +{ + "vehicleStatus" : { + "doorPassengerFront" : "CLOSED", + "cbsData" : [ { + "cbsDueDate" : "2020-01", + "cbsState" : "OK", + "cbsRemainingMileage" : 25000, + "cbsDescription" : "Next service due when the stated distance has been covered or by the specified date.", + "cbsType" : "OIL" + }, { + "cbsDueDate" : "2022-01", + "cbsState" : "OK", + "cbsRemainingMileage" : 60000, + "cbsDescription" : "Next visual inspection due when the stated distance has been covered or by the stated date.", + "cbsType" : "VEHICLE_CHECK" + }, { + "cbsDueDate" : "2021-01", + "cbsState" : "OK", + "cbsDescription" : "Next change due at the latest by the stated date.", + "cbsType" : "BRAKE_FLUID" + } ], + "windowDriverFront" : "CLOSED", + "DCS_CCH_Ongoing" : false, + "updateReason" : "VEHICLE_SHUTDOWN_SECURED", + "rearWindow" : "CLOSED", + "remainingRangeFuelMls" : 187, + "DCS_CCH_Activation" : "NA", + "singleImmediateCharging" : false, + "positionLight" : "OFF", + "vin" : "G31_VIN", + "doorDriverFront" : "CLOSED", + "mileage" : 4134, + "checkControlMessages" : [ ], + "parkingLight" : "OFF", + "windowDriverRear" : "CLOSED", + "steering" : "LH", + "updateTime" : "2018-03-12T08:56:16+0100", + "remainingFuel" : 32, + "windowPassengerRear" : "CLOSED", + "trunk" : "CLOSED", + "hood" : "CLOSED", + "internalDataTimeUTC" : "2018-03-12T07:56:16", + "windowPassengerFront" : "CLOSED", + "doorLockState" : "SECURED", + "doorPassengerRear" : "CLOSED", + "remainingRangeFuel" : 302, + "doorDriverRear" : "CLOSED", + "position" : { + "status" : "DRIVER_DISABLED" + } + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_NOREX/status.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_NOREX/status.json new file mode 100644 index 0000000000000..55b1760efc5f7 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_NOREX/status.json @@ -0,0 +1,61 @@ +{ + "vehicleStatus": { + "doorPassengerFront": "CLOSED", + "cbsData": [ + { + "cbsDueDate": "2018-11", + "cbsState": "OK", + "cbsDescription": "Next change due at the latest by the stated date.", + "cbsType": "BRAKE_FLUID" + }, + { + "cbsDueDate": "2018-11", + "cbsState": "OK", + "cbsDescription": "Next visual inspection due when the stated distance has been covered or by the stated date.", + "cbsType": "VEHICLE_CHECK" + } + ], + "windowDriverFront": "CLOSED", + "DCS_CCH_Ongoing": false, + "updateReason": "VEHICLE_SHUTDOWN_SECURED", + "rearWindow": "INVALID", + "DCS_CCH_Activation": "NA", + "chargingInductivePositioning": "NOT_POSITIONED", + "remainingRangeElectric": 53, + "singleImmediateCharging": false, + "maxRangeElectric": 103, + "chargingConnectionType": "CONDUCTIVE", + "positionLight": "OFF", + "lastChargingEndReason": "END_REQUESTED_BY_DRIVER", + "chargingStatus": "INVALID", + "vin": "I01_NOREX_VIN", + "doorDriverFront": "CLOSED", + "mileage": 16059, + "checkControlMessages": [], + "parkingLight": "OFF", + "windowDriverRear": "CLOSED", + "remainingRangeElectricMls": 32, + "lastChargingEndResult": "SUCCESS", + "steering": "RH", + "updateTime": "2018-03-15T15:44:30+0100", + "remainingFuel": 0, + "windowPassengerRear": "CLOSED", + "trunk": "CLOSED", + "hood": "CLOSED", + "internalDataTimeUTC": "2018-03-15T14:44:30", + "maxRangeElectricMls": 64, + "windowPassengerFront": "CLOSED", + "doorLockState": "SECURED", + "doorPassengerRear": "CLOSED", + "doorDriverRear": "CLOSED", + "sunroof": "CLOSED", + "connectionStatus": "DISCONNECTED", + "chargingLevelHv": 58, + "position": { + "heading": 123, + "lon": 12.3456, + "lat": -65.4321, + "status": "OK" + } + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/status.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/status.json new file mode 100644 index 0000000000000..5b2415b4bdcd1 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/status.json @@ -0,0 +1,61 @@ +{ + "vehicleStatus" : { + "doorPassengerFront" : "CLOSED", + "cbsData" : [ { + "cbsDueDate" : "2018-05", + "cbsState" : "OK", + "cbsDescription" : "Next change due at the latest by the stated date.", + "cbsType" : "BRAKE_FLUID" + }, { + "cbsDueDate" : "2018-05", + "cbsState" : "OK", + "cbsDescription" : "Next visual inspection due when the stated distance has been covered or by the stated date.", + "cbsType" : "VEHICLE_CHECK" + } ], + "windowDriverFront" : "CLOSED", + "DCS_CCH_Ongoing" : false, + "updateReason" : "VEHICLE_SHUTDOWN_SECURED", + "rearWindow" : "INVALID", + "remainingRangeFuelMls" : 65, + "DCS_CCH_Activation" : "NA", + "chargingInductivePositioning" : "NOT_POSITIONED", + "remainingRangeElectric" : 48, + "singleImmediateCharging" : false, + "maxRangeElectric" : 94, + "chargingConnectionType" : "CONDUCTIVE", + "positionLight" : "OFF", + "lastChargingEndReason" : "UNKNOWN", + "chargingStatus" : "CHARGING", + "vin" : "I01_VIN", + "doorDriverFront" : "CLOSED", + "mileage" : 38807, + "chargingTimeRemaining" : 332, + "checkControlMessages" : [ ], + "parkingLight" : "OFF", + "windowDriverRear" : "CLOSED", + "remainingRangeElectricMls" : 30, + "lastChargingEndResult" : "UNKNOWN", + "steering" : "LH", + "updateTime" : "2018-03-12T08:38:57+0100", + "remainingFuel" : 8, + "windowPassengerRear" : "CLOSED", + "trunk" : "CLOSED", + "hood" : "CLOSED", + "internalDataTimeUTC" : "2018-03-12T06:21:01", + "maxRangeElectricMls" : 58, + "maxFuel" : 8, + "windowPassengerFront" : "CLOSED", + "doorLockState" : "SECURED", + "doorPassengerRear" : "CLOSED", + "remainingRangeFuel" : 106, + "doorDriverRear" : "CLOSED", + "connectionStatus" : "CONNECTED", + "chargingLevelHv" : 54, + "position" : { + "heading" : 356, + "lon" : 15.00000, + "lat" : 58.000000, + "status" : "OK" + } + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/vehicles.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/vehicles.json new file mode 100644 index 0000000000000..fe73476204943 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/vehicles.json @@ -0,0 +1,407 @@ +{ + "vehicles" : [ { + "vehicleFinderRestriction" : "NONE", + "doorUnlock" : "ACTIVATED", + "color" : "SOPHISTOGRAU BRILLANTEFFEKT METALLI", + "onlineSearchMode" : "MAP", + "breakdownNumber" : "+4912345678", + "smartSolution" : "NOT_SUPPORTED", + "yearOfConstruction" : 2018, + "driveTrain" : "CONV", + "rangeMap" : "NOT_SUPPORTED", + "vehicleFinder" : "ACTIVATED", + "a4a" : "BLUETOOTH", + "hornBlow" : "ACTIVATED", + "chargeNow" : "NOT_SUPPORTED", + "countryCode" : "V6", + "bodytype" : "G31", + "lightFlash" : "ACTIVATED", + "vin" : "G31_NBTevo_VIN", + "model" : "530i xDrive", + "ipa" : "NOT_SUPPORTED", + "brand" : "BMW", + "climateControl" : "DEPARTURE_TIMER", + "sendPoi" : "ACTIVATED", + "lastDestinations" : "NOT_SUPPORTED", + "doorLock" : "ACTIVATED", + "chargingControl" : "NOT_SUPPORTED", + "onlineSearchProvider" : "GOOGLE", + "steering" : "LH", + "intermodalRouting" : "NOT_AVAILABLE", + "lscType" : "LSC_BASIS", + "hasAlarmSystem" : true, + "statisticsCommunityEnabled" : false, + "climateNow" : "ACTIVATED", + "fuelType" : "PETROL", + "hub" : "HUB_ECE", + "remote360" : "NOT_SUPPORTED", + "hmiVersion" : "ID5", + "climateFunction" : "PARK_HEATING", + "colorCode" : "A90", + "carCloud" : "ACTIVATED", + "statisticsAvailable" : false + }, + { + "vehicleFinderRestriction" : "NONE", + "doorUnlock" : "ACTIVATED", + "color" : "ALPINWEISS III", + "onlineSearchMode" : "MAP", + "breakdownNumber" : "+4989358111111", + "smartSolution" : "NOT_SUPPORTED", + "yearOfConstruction" : 2017, + "driveTrain" : "CONV", + "rangeMap" : "NOT_SUPPORTED", + "vehicleFinder" : "ACTIVATED", + "a4a" : "BLUETOOTH", + "hornBlow" : "ACTIVATED", + "chargeNow" : "NOT_SUPPORTED", + "countryCode" : "V1-NL", + "bodytype" : "F48", + "lightFlash" : "ACTIVATED", + "vin" : "F48_VIN", + "model" : "X1 sDrive18i", + "ipa" : "NOT_SUPPORTED", + "brand" : "BMW", + "climateControl" : "START_TIMER", + "sendPoi" : "ACTIVATED", + "lastDestinations" : "NOT_SUPPORTED", + "doorLock" : "ACTIVATED", + "chargingControl" : "NOT_SUPPORTED", + "onlineSearchProvider" : "GOOGLE", + "steering" : "LH", + "intermodalRouting" : "NOT_AVAILABLE", + "lscType" : "LSC_BASIS", + "hasAlarmSystem" : true, + "statisticsCommunityEnabled" : false, + "climateNow" : "ACTIVATED", + "fuelType" : "PETROL", + "hub" : "HUB_ECE", + "remote360" : "NOT_SUPPORTED", + "hmiVersion" : "ID5", + "dealer" : { + "country" : "NL", + "city" : "city", + "phone" : "phone", + "street" : "street", + "postalCode" : "1234 AB", + "name" : "BMW dealer" + }, + "climateFunction" : "VENTILATION", + "colorCode" : "300", + "carCloud" : "ACTIVATED", + "statisticsAvailable" : false + } + , + { + "vehicleFinderRestriction" : "NONE", + "doorUnlock" : "ACTIVATED", + "color" : "ARRAVANIGRAU/BMW i BLAU", + "onlineSearchMode" : "MAP", + "breakdownNumber" : "+4989358957103", + "smartSolution" : "NOT_SUPPORTED", + "yearOfConstruction" : 2014, + "driveTrain" : "BEV_REX", + "rangeMap" : "RANGE_CIRCLE", + "vehicleFinder" : "ACTIVATED", + "a4a" : "USB_ONLY", + "hornBlow" : "ACTIVATED", + "chargeNow" : "NOT_SUPPORTED", + "licensePlate" : "ABC000", + "countryCode" : "V1-R1-SE", + "bodytype" : "I01", + "lightFlash" : "ACTIVATED", + "vin" : "I01_VIN", + "model" : "i3 (+ REX)", + "ipa" : "NOT_SUPPORTED", + "brand" : "BMW_I", + "climateControl" : "NOT_SUPPORTED", + "sendPoi" : "ACTIVATED", + "lastDestinations" : "SUPPORTED", + "doorLock" : "ACTIVATED", + "chargingControl" : "WEEKLY_PLANNER", + "onlineSearchProvider" : "GOOGLE", + "steering" : "LH", + "intermodalRouting" : "NOT_AVAILABLE", + "supportedChargingModes" : [ "AC_LOW", "AC_HIGH", "DC" ], + "lscType" : "I_LSC_IMM", + "hasAlarmSystem" : false, + "statisticsCommunityEnabled" : false, + "climateNow" : "ACTIVATED", + "hub" : "HUB_ECE", + "remote360" : "NOT_SUPPORTED", + "hmiVersion" : "ID4", + "dealer" : { + "country" : "SE", + "city" : "Solna", + "phone" : "+46 8 7353900", + "street" : "G�rdsv�gen 9-11", + "postalCode" : "169 70", + "name" : "Bavaria Sverige Bil AB/ Solna" + }, + "climateFunction" : "AIRCONDITIONING", + "colorCode" : "B74", + "carCloud" : "NOT_SUPPORTED", + "statisticsAvailable" : true + }, + { + "vehicleFinderRestriction" : "NONE", + "doorUnlock" : "NOT_SUPPORTED", + "color" : "BLACK SAPPHIRE METALLIC", + "onlineSearchMode" : "MAP", + "breakdownNumber" : "+4989358957103", + "smartSolution" : "NOT_SUPPORTED", + "yearOfConstruction" : 2017, + "driveTrain" : "CONV", + "rangeMap" : "NOT_SUPPORTED", + "vehicleFinder" : "ACTIVATED", + "a4a" : "BLUETOOTH", + "hornBlow" : "ACTIVATED", + "chargeNow" : "NOT_SUPPORTED", + "countryCode" : "V2-CA", + "bodytype" : "F15", + "lightFlash" : "ACTIVATED", + "vin" : "F15_VIN", + "model" : "X5 xDrive35i", + "ipa" : "NOT_SUPPORTED", + "brand" : "BMW", + "climateControl" : "DEPARTURE_TIMER", + "sendPoi" : "ACTIVATED", + "lastDestinations" : "NOT_SUPPORTED", + "doorLock" : "ACTIVATED", + "chargingControl" : "NOT_SUPPORTED", + "steering" : "LH", + "intermodalRouting" : "NOT_AVAILABLE", + "lscType" : "LSC_BASIS", + "hasAlarmSystem" : true, + "statisticsCommunityEnabled" : false, + "climateNow" : "ACTIVATED", + "fuelType" : "PETROL", + "hub" : "HUB_US", + "remote360" : "NOT_SUPPORTED", + "hmiVersion" : "ID5", + "dealer" : { + "country" : "CA", + "city" : "Ottawa", + "phone" : "1-866-599-4999", + "street" : "85 Wellington St", + "postalCode" : "K1A 1A1", + "name" : "Parliament of Canada" + }, + "climateFunction" : "VENTILATION", + "colorCode" : "475", + "carCloud" : "NOT_SUPPORTED", + "statisticsAvailable" : false + }, + { + "vehicleFinderRestriction": "NONE", + "doorUnlock": "ACTIVATED", + "color": "SOLARORANGE MET. M. AKZENT FROZEN G", + "onlineSearchMode": "MAP", + "breakdownNumber": "+4989358957103", + "smartSolution": "NOT_SUPPORTED", + "yearOfConstruction": 2014, + "driveTrain": "BEV", + "rangeMap": "RANGE_CIRCLE", + "vehicleFinder": "ACTIVATED", + "a4a": "USB_ONLY", + "hornBlow": "ACTIVATED", + "chargeNow": "NOT_SUPPORTED", + "licensePlate": "HIDDEN", + "countryCode": "B3-ZA", + "bodytype": "I01", + "lightFlash": "ACTIVATED", + "vin": "I01_NOREX_VIN", + "model": "i3", + "ipa": "NOT_SUPPORTED", + "brand": "BMW_I", + "climateControl": "NOT_SUPPORTED", + "sendPoi": "ACTIVATED", + "lastDestinations": "SUPPORTED", + "doorLock": "ACTIVATED", + "chargingControl": "WEEKLY_PLANNER", + "onlineSearchProvider": "GOOGLE", + "steering": "RH", + "intermodalRouting": "NOT_AVAILABLE", + "supportedChargingModes": [ + "AC_LOW", + "AC_HIGH" + ], + "lscType": "I_LSC_IMM", + "hasAlarmSystem": true, + "statisticsCommunityEnabled": true, + "climateNow": "ACTIVATED", + "hub": "HUB_ECE", + "remote360": "NOT_SUPPORTED", + "hmiVersion": "ID4", + "dealer": { + "country": "ZA", + "city": "Midrand", + "phone": "+27 12 522 3000", + "street": "1 Bavaria Avenue", + "postalCode": "1685", + "name": "BMW (South Africa) (Pty) Ltd. ZA" + }, + "climateFunction": "AIRCONDITIONING", + "colorCode": "B78", + "carCloud": "NOT_SUPPORTED", + "statisticsAvailable": true + }, + { + "a4a": "USB_ONLY", + "bodytype": "F45", + "brand": "BMW", + "breakdownNumber": "+4989358957103", + "carCloud": "NOT_SUPPORTED", + "chargeNow": "NOT_SUPPORTED", + "chargingControl": "NOT_SUPPORTED", + "climateControl": "START_TIMER", + "climateFunction": "VENTILATION", + "climateNow": "ACTIVATED", + "color": "MEDITERRANBLAU METALLIC", + "colorCode": "C10", + "countryCode": "V1-ES", + "dealer": { + "city": "Madrid", + "country": "ES", + "name": "BMW Iberica S.A.", + "phone": "+34 913350505", + "postalCode": "28050", + "street": "Avenida de Burgos ,118" + }, + "doorLock": "ACTIVATED", + "doorUnlock": "ACTIVATED", + "driveTrain": "CONV", + "fuelType": "PETROL", + "hasAlarmSystem": false, + "hmiVersion": "ID4", + "hornBlow": "ACTIVATED", + "hub": "HUB_ECE", + "intermodalRouting": "NOT_AVAILABLE", + "ipa": "NOT_SUPPORTED", + "lastDestinations": "NOT_SUPPORTED", + "licensePlate": "some_license_plate", + "lightFlash": "ACTIVATED", + "lscType": "NOT_SUPPORTED", + "model": "225i", + "onlineSearchMode": "MAP", + "onlineSearchProvider": "GOOGLE", + "rangeMap": "NOT_SUPPORTED", + "remote360": "NOT_SUPPORTED", + "sendPoi": "ACTIVATED", + "smartSolution": "NOT_SUPPORTED", + "statisticsAvailable": false, + "statisticsCommunityEnabled": false, + "steering": "LH", + "vehicleFinder": "ACTIVATED", + "vehicleFinderRestriction": "NONE", + "vin": "F45_VIN", + "yearOfConstruction": 2016 + }, + { + "a4a": "USB_ONLY", + "bodytype": "F31", + "brand": "BMW", + "breakdownNumber": "+4989358957103", + "carCloud": "NOT_SUPPORTED", + "chargeNow": "NOT_SUPPORTED", + "chargingControl": "NOT_SUPPORTED", + "climateControl": "START_TIMER", + "climateControlRES": "NOT_SUPPORTED", + "climateFunction": "VENTILATION", + "climateNow": "ACTIVATED", + "climateNowRES": "NOT_SUPPORTED", + "color": "PLATINSILBER METALLIC", + "colorCode": "C08", + "countryCode": "V1-UK", + "dealer": { + "city": "Farnborough", + "country": "GB", + "name": "BMW (UK) Ltd. ICS - DIRECT SUPPLY", + "phone": "+44 1252 920000", + "postalCode": "GU14 0FB", + "street": "Summit ONE" + }, + "doorLock": "ACTIVATED", + "doorUnlock": "ACTIVATED", + "driveTrain": "CONV", + "fuelType": "DIESEL", + "hasAlarmSystem": true, + "hmiVersion": "ID4", + "hornBlow": "NOT_SUPPORTED", + "hub": "HUB_ECE", + "intermodalRouting": "NOT_AVAILABLE", + "ipa": "NOT_SUPPORTED", + "lastDestinations": "NOT_SUPPORTED", + "licensePlate": "some_license_plate", + "lightFlash": "ACTIVATED", + "lscType": "NOT_SUPPORTED", + "model": "320d", + "onlineSearchMode": "MAP", + "onlineSearchProvider": "GOOGLE", + "rangeMap": "NOT_SUPPORTED", + "remote360": "NOT_SUPPORTED", + "remoteSoftwareUpgrade": "NOT_SUPPORTED", + "sendPoi": "ACTIVATED", + "smartSolution": "NOT_SUPPORTED", + "statisticsAvailable": false, + "statisticsCommunityEnabled": false, + "steering": "RH", + "vehicleFinder": "ACTIVATED", + "vehicleFinderRestriction": "NONE", + "vin": "F31_VIN", + "yearOfConstruction": 2015 + }, + { + "a4a": "NOT_SUPPORTED", + "bodytype": "F35", + "brand": "BMW", + "breakdownNumber": "+4989358957103", + "carCloud": "NOT_SUPPORTED", + "chargeNow": "NOT_SUPPORTED", + "chargingControl": "NOT_SUPPORTED", + "climateControl": "NOT_SUPPORTED", + "climateControlRES": "NOT_SUPPORTED", + "climateFunction": "VENTILATION", + "climateNow": "NOT_SUPPORTED", + "climateNowRES": "NOT_SUPPORTED", + "color": "MINERALWEISS METALLIC", + "colorCode": "A96", + "countryCode": "V5-CN", + "dealer": { + "city": "Beijing", + "country": "CN", + "name": "Beijing Baozen Baiwang Automotive Sales Co., Ltd.", + "phone": "+86 10 62826789", + "postalCode": "100094", + "street": "F2 Baiwang Green Valley" + }, + "doorLock": "NOT_SUPPORTED", + "doorUnlock": "NOT_SUPPORTED", + "driveTrain": "CONV", + "fuelType": "PETROL", + "hasAlarmSystem": false, + "hmiVersion": "ID5", + "hornBlow": "NOT_SUPPORTED", + "hub": "HUB_CN", + "intermodalRouting": "NOT_AVAILABLE", + "ipa": "NOT_SUPPORTED", + "lastDestinations": "NOT_SUPPORTED", + "licensePlate": "some_license_plate", + "lightFlash": "NOT_SUPPORTED", + "lscType": "NOT_SUPPORTED", + "model": "328Li", + "onlineSearchMode": "MAP", + "rangeMap": "NOT_SUPPORTED", + "remote360": "NOT_SUPPORTED", + "remoteSoftwareUpgrade": "NOT_SUPPORTED", + "sendPoi": "NOT_SUPPORTED", + "smartSolution": "NOT_SUPPORTED", + "statisticsAvailable": false, + "statisticsCommunityEnabled": false, + "steering": "LH", + "vehicleFinder": "NOT_SUPPORTED", + "vin": "F31_VIN", + "yearOfConstruction": 2015 + } + ] +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status-charging.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status-charging.json new file mode 100644 index 0000000000000..0c9aa95b6586a --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status-charging.json @@ -0,0 +1,77 @@ +{ + "vehicleStatus": { + "vin": "WBY1Z81040V905639", + "mileage": 17307, + "updateReason": "CHARGING_STARTED", + "updateTime": "2020-08-25T15:37:16+0000", + "doorDriverFront": "CLOSED", + "doorDriverRear": "CLOSED", + "doorPassengerFront": "CLOSED", + "doorPassengerRear": "CLOSED", + "windowDriverFront": "CLOSED", + "windowDriverRear": "CLOSED", + "windowPassengerFront": "CLOSED", + "windowPassengerRear": "CLOSED", + "sunroof": "CLOSED", + "trunk": "CLOSED", + "rearWindow": "INVALID", + "hood": "CLOSED", + "doorLockState": "SECURED", + "parkingLight": "OFF", + "positionLight": "ON", + "remainingFuel": 4, + "remainingRangeElectric": 182, + "remainingRangeElectricMls": 113, + "remainingRangeFuel": 69, + "remainingRangeFuelMls": 42, + "maxRangeElectric": 213, + "maxRangeElectricMls": 132, + "maxFuel": 8.5, + "connectionStatus": "CONNECTED", + "chargingStatus": "CHARGING", + "chargingTimeRemaining": 76, + "chargingLevelHv": 86, + "lastChargingEndReason": "UNKNOWN", + "lastChargingEndResult": "UNKNOWN", + "position": { + "lat": 50.55603, + "lon": 8.495625, + "heading": 41, + "status": "OK" + }, + "internalDataTimeUTC": "2020-08-25T12:57:59", + "singleImmediateCharging": false, + "chargingConnectionType": "CONDUCTIVE", + "chargingInductivePositioning": "NOT_POSITIONED", + "vehicleCountry": "DE", + "checkControlMessages": [], + "cbsData": [ + { + "cbsType": "BRAKE_FLUID", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next change due at the latest by the stated date." + }, + { + "cbsType": "VEHICLE_CHECK", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next visual inspection due when the stated distance has been covered or by the stated date." + }, + { + "cbsType": "OIL", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next change due when the stated distance has been covered or by the specified date." + }, + { + "cbsType": "VEHICLE_TUV", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next statutory vehicle inspection due by the stated date." + } + ], + "DCS_CCH_Activation": "NA", + "DCS_CCH_Ongoing": false + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/test3.json b/bundles/org.openhab.binding.bmwconnecteddrive/test3.json new file mode 100644 index 0000000000000..19a5100bbc44b --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/test3.json @@ -0,0 +1,76 @@ +{ + "vehicleStatus": { + "vin": "WBY1Z81040V905639", + "mileage": 17324, + "updateReason": "VEHICLE_SHUTDOWN_SECURED", + "updateTime": "2020-08-26T03:47:24+0000", + "doorDriverFront": "CLOSED", + "doorDriverRear": "CLOSED", + "doorPassengerFront": "CLOSED", + "doorPassengerRear": "CLOSED", + "windowDriverFront": "CLOSED", + "windowDriverRear": "CLOSED", + "windowPassengerFront": "CLOSED", + "windowPassengerRear": "CLOSED", + "sunroof": "CLOSED", + "trunk": "CLOSED", + "rearWindow": "INVALID", + "hood": "CLOSED", + "doorLockState": "SECURED", + "parkingLight": "OFF", + "positionLight": "ON", + "remainingFuel": 4, + "remainingRangeElectric": 179, + "remainingRangeElectricMls": 111, + "remainingRangeFuel": 71, + "remainingRangeFuelMls": 44, + "maxRangeElectric": 219, + "maxRangeElectricMls": 136, + "maxFuel": 8.5, + "connectionStatus": "DISCONNECTED", + "chargingStatus": "INVALID", + "chargingLevelHv": 83, + "lastChargingEndReason": "END_REQUESTED_BY_DRIVER", + "lastChargingEndResult": "SUCCESS", + "position": { + "lat": 50.57332, + "lon": 8.6638365, + "heading": 217, + "status": "OK" + }, + "internalDataTimeUTC": "2020-08-26T03:47:24", + "singleImmediateCharging": false, + "chargingConnectionType": "CONDUCTIVE", + "chargingInductivePositioning": "NOT_POSITIONED", + "vehicleCountry": "DE", + "checkControlMessages": [], + "cbsData": [ + { + "cbsType": "BRAKE_FLUID", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next change due at the latest by the stated date." + }, + { + "cbsType": "VEHICLE_CHECK", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next visual inspection due when the stated distance has been covered or by the stated date." + }, + { + "cbsType": "OIL", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next change due when the stated distance has been covered or by the specified date." + }, + { + "cbsType": "VEHICLE_TUV", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next statutory vehicle inspection due by the stated date." + } + ], + "DCS_CCH_Activation": "NA", + "DCS_CCH_Ongoing": false + } +} \ No newline at end of file From abf426524edcdffedc2c5aa909a593d39bc46ed9 Mon Sep 17 00:00:00 2001 From: Bernd Date: Thu, 27 Aug 2020 01:21:40 +0200 Subject: [PATCH 009/176] added vehicle status Signed-off-by: Bernd (cherry picked from commit 5358e666065610f539081c4097cb79edf3af8c16) Signed-off-by: Bernd --- .../internal/ConnectedDriveConstants.java | 14 +++- .../discovery/ConnectedCarDiscovery.java | 1 - .../internal/dto/status/CBSMessage.java | 10 +-- .../internal/dto/status/Doors.java | 27 ++++++ .../internal/dto/status/Windows.java | 27 ++++++ .../handler/ConnectedCarChannelHandler.java | 22 +++-- .../internal/handler/ConnectedCarHandler.java | 84 ++++++++++++++++++- .../internal/utils/Converter.java | 6 +- .../thing/elv-status-channel-groups.xml | 18 ++++ .../ESH-INF/thing/status-channel-groups.xml | 17 ++++ .../ESH-INF/thing/status-channel-types.xml | 30 +++++++ .../resources/ESH-INF/thing/thing-bev.xml | 1 + .../resources/ESH-INF/thing/thing-bev_rex.xml | 5 +- .../resources/ESH-INF/thing/thing-conv.xml | 1 + .../resources/ESH-INF/thing/thing-phev.xml | 1 + .../internal/handler/CarTests.java | 30 ++++++- .../internal/util/LocaleTest.java | 10 +++ 17 files changed, 276 insertions(+), 28 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Doors.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Windows.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/elv-status-channel-groups.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-groups.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-types.xml diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 922effab4627d..6d8f37505b395 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -95,6 +95,7 @@ public String toString() { // Group definitions public static final String CHANNEL_GROUP_PROPERTIES = "properties"; + public static final String CHANNEL_GROUP_STATUS = "status"; public static final String CHANNEL_GROUP_RANGE = "range"; public static final String CHANNEL_GROUP_LIFETIME = "lifetime"; public static final String CHANNEL_GROUP_LAST_TRIP = "last-trip"; @@ -120,9 +121,13 @@ public String toString() { public static final String PROPERTIES_NOT_SUPPORTED_SERVICES = "not-supported-services"; public static final String PROPERTIES_CHARGING_MODES = "charging-modes"; - public static final String IMAGE = "rendered"; - public static final String IMAGE_SIZE = "size"; - public static final String IMAGE_VIEW_DIRECTION = "view-direction"; + // Status + public static final String DOORS = "doors"; + public static final String WINDOWS = "windows"; + public static final String LOCK = "lock"; + public static final String SERVICE = "service"; + public static final String CHECK_CONTROL = "check-control"; + public static final String CHARGING_STATUS = "charging-status"; // Range public static final String MILEAGE = "mileage"; @@ -149,4 +154,7 @@ public String toString() { public static final String LATLONG = "latlong"; public static final String HEADING = "heading"; public static final String RANGE_RADIUS = "range-radius"; + + // Image + public static final String IMAGE = "rendered"; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java index 9e6c9deda26e6..adb8be794410b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java @@ -101,7 +101,6 @@ public void scan(ConnectedDriveUserInfo cdui) { public String getObject(Object obj, String compare) { StringBuffer buf = new StringBuffer(); for (Field field : obj.getClass().getDeclaredFields()) { - // field.setAccessible(true); // if you want to modify private fields try { if (field.get(obj).equals(compare)) { buf.append(field.getName()); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java index ff74d248a399a..b473968d785c0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java @@ -18,10 +18,8 @@ * @author Bernd Weymann - Initial contribution */ public class CBSMessage { - public String description; // ": "Nächster Wechsel spätestens zum angegebenen Termin.", - public String text; // ": "Bremsflüssigkeit", - public int id; // ": 3, - public String status; // ": "OK", - public String messageType; // : "CBS", - public String date; // 2021-11" + public String cbsType;// ": "BRAKE_FLUID", + public String cbsState;// ": "OK", + public String cbsDueDate;// ": "2021-11", + public String cbsDescription;// ": "Next change due at the latest by the stated date." } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Doors.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Doors.java new file mode 100644 index 0000000000000..c4872adaf4417 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Doors.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.status; + +/** + * The {@link Doors} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class Doors { + public String doorDriverFront;// ": "CLOSED", + public String doorDriverRear;// ": "CLOSED", + public String doorPassengerFront;// ": "CLOSED", + public String doorPassengerRear;// ": "CLOSED", + public String trunk;// ": "CLOSED", + public String hood;// ": "CLOSED", +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Windows.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Windows.java new file mode 100644 index 0000000000000..8cc3cfc958353 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Windows.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.status; + +/** + * The {@link Windows} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class Windows { + public String windowDriverFront;// ": "CLOSED", + public String windowDriverRear;// ": "CLOSED", + public String windowPassengerFront;// ": "CLOSED", + public String windowPassengerRear;// ": "CLOSED", + public String sunroof;// ": "CLOSED", + public String rearWindow;// ": "INVALID", +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java index d48d49fea0faf..4b53f9ba0b5b4 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java @@ -47,7 +47,15 @@ public class ConnectedCarChannelHandler extends BaseThingHandler { protected ChannelUID notSupportedServicesChannel; protected ChannelUID chargingModesChannel; - // Vehcile channels + // Vahicle Status Channels + protected ChannelUID doors; + protected ChannelUID windows; + protected ChannelUID lock; + protected ChannelUID service; + protected ChannelUID checkControl; + protected ChannelUID chargingStatus; + + // Range channels protected ChannelUID mileage; protected ChannelUID remainingRangeHybrid; protected ChannelUID remainingRangeElectric; @@ -76,8 +84,6 @@ public class ConnectedCarChannelHandler extends BaseThingHandler { protected ChannelUID rangeRadius; protected ChannelUID imageChannel; - protected ChannelUID imageSizeChannel; - protected ChannelUID imageViewDirectionChannel; public ConnectedCarChannelHandler(Thing thing) { super(thing); @@ -106,6 +112,14 @@ public ConnectedCarChannelHandler(Thing thing) { PROPERTIES_NOT_SUPPORTED_SERVICES); chargingModesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_CHARGING_MODES); + // Vehicle Status channels + doors = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, DOORS); + windows = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, WINDOWS); + lock = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, LOCK); + service = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, SERVICE); + checkControl = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, CHECK_CONTROL); + chargingStatus = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, CHARGING_STATUS); + // range Channels mileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, MILEAGE); remainingRangeHybrid = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_RANGE_HYBRID); @@ -136,8 +150,6 @@ public ConnectedCarChannelHandler(Thing thing) { rangeRadius = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, RANGE_RADIUS); imageChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CAR_IMAGE, IMAGE); - imageSizeChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CAR_IMAGE, IMAGE_VIEW_DIRECTION); - imageViewDirectionChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CAR_IMAGE, IMAGE_SIZE); } @Override diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java index 0133546c946b0..11a0b062620c4 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java @@ -15,6 +15,9 @@ import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; import static org.openhab.binding.bmwconnecteddrive.internal.handler.HTTPConstants.CONTENT_TYPE_JSON; +import java.lang.reflect.Field; +import java.time.LocalDate; +import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -50,9 +53,13 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.Community; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTrip; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.Trip; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.CBSMessage; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.CCMMessage; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Doors; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Position; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Status; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Windows; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -124,7 +131,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { } } else { if (vehicleStatusCache != null) { - updateVehicleStatus(vehicleStatusCache); + updateRangeValues(vehicleStatusCache); } } logger.info("REFRESH {}", group); @@ -284,6 +291,7 @@ public void getData() { } String vehicleStatusData = getJSON(vehicleAPI); updateVehicleStatus(vehicleStatusData); + updateRangeValues(vehicleStatusData); String lastTripData = getJSON(lastTripAPI); updateLastTrip(lastTripData); String allTripData = getJSON(allTripsAPI); @@ -358,11 +366,78 @@ void updateVehicleStatus(@Nullable String content) { logger.warn("No Vehicle Values available"); return; } - vehicleStatusCache = content; logger.info("Vehicle Status {}", content); + vehicleStatusCache = content; + Status status = GSON.fromJson(content, Status.class); + VehicleStatus vStatus = status.vehicleStatus; + + updateState(lock, StringType.valueOf(vStatus.doorLockState)); + updateState(chargingStatus, StringType.valueOf(vStatus.chargingStatus)); + + Doors doorState = GSON.fromJson(GSON.toJson(vStatus), Doors.class); + updateState(doors, StringType.valueOf(checkClosed(doorState))); + Windows windowState = GSON.fromJson(GSON.toJson(vStatus), Windows.class); + updateState(windows, StringType.valueOf(checkClosed(windowState))); + updateState(checkControl, StringType.valueOf(getCheckControl(vStatus.checkControlMessages))); + updateState(service, StringType.valueOf(getNextService(vStatus.cbsData))); + } + + private @Nullable String getNextService(List cbsData) { + if (cbsData.isEmpty()) { + return "No Service Requests"; + } else { + LocalDate serviceDate = null; + String service = null; + for (int i = 0; i < cbsData.size(); i++) { + CBSMessage entry = cbsData.get(i); + LocalDate d = LocalDate.parse(entry.cbsDueDate + "-01", Converter.serviceDateInputPattern); + if (serviceDate == null) { + serviceDate = d; + service = entry.cbsType; + } else { + if (d.isBefore(serviceDate)) { + serviceDate = d; + } + } + } + if (serviceDate != null) { + return serviceDate.format(Converter.serviceDateOutputPattern) + ":" + service; + } else { + return "Unknown"; + } + } + } + + private @Nullable String getCheckControl(List checkControlMessages) { + if (checkControlMessages.isEmpty()) { + return "Ok"; + } else { + return checkControlMessages.get(0).ccmDescriptionShort; + } + } + + String checkClosed(Object dto) { + for (Field field : dto.getClass().getDeclaredFields()) { + try { + if (field.get(dto).equals("OPEN")) { + // report the first door which is still open + return field.getName() + " open"; + } + } catch (IllegalArgumentException | IllegalAccessException e) { + logger.warn("Fields for {} Object not accesible", dto); + return "Unknown"; + } + } + return "Closed"; + } + + void updateRangeValues(@Nullable String content) { + if (content == null) { + logger.warn("No Vehicle Values available"); + return; + } Status status = GSON.fromJson(content, Status.class); VehicleStatus vStatus = status.vehicleStatus; - logger.info("Update Milage {} Channel {}", vStatus.mileage, mileage.toString()); // based on unit of length decide if range shall be reported in km or miles if (!imperial) { updateState(mileage, QuantityType.valueOf(vStatus.mileage, MetricPrefix.KILO(SIUnits.METRE))); @@ -402,7 +477,8 @@ void updateVehicleStatus(@Nullable String content) { QuantityType.valueOf(vStatus.remainingRangeFuelMls, ImperialUnits.MILE)); } if (isHybrid) { - updateState(remainingRangeHybrid, QuantityType.valueOf(Converter.round(totalRange), ImperialUnits.MILE)); + updateState(remainingRangeHybrid, + QuantityType.valueOf(Converter.round(totalRange), ImperialUnits.MILE)); } updateState(rangeRadius, new DecimalType((totalRange) * 5280)); // Miles to feet } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java index e6f7e04fbcfdf..f502896c575dd 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java @@ -26,6 +26,9 @@ * @author Bernd Weymann - Initial contribution */ public class Converter { + public final static DateTimeFormatter serviceDateInputPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + public final static DateTimeFormatter serviceDateOutputPattern = DateTimeFormatter.ofPattern("MMM yyyy"); + private final static Logger logger = LoggerFactory.getLogger(Converter.class); private final static DateTimeFormatter inputPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); private final static DateTimeFormatter outputPattern = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); @@ -37,11 +40,8 @@ public static double round(double value) { public static String getLocalDateTime(String input) { LocalDateTime ldt = LocalDateTime.parse(input, Converter.inputPattern); - logger.info("Update Local DateTime {}", ldt); ZonedDateTime zdtUTC = ldt.atZone(ZoneId.of("UTC")); - logger.info("Update UTC DateTime {}", zdtUTC); ZonedDateTime zdtLZ = zdtUTC.withZoneSameInstant(ZoneId.systemDefault()); - logger.info("Update UTC DateTime {}", zdtLZ); return zdtLZ.format(Converter.outputPattern); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/elv-status-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/elv-status-channel-groups.xml new file mode 100644 index 0000000000000..52fa76db148c1 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/elv-status-channel-groups.xml @@ -0,0 +1,18 @@ + + + + + Provides Status of Doors, Lock State, Service and Check Control Messages + + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-groups.xml new file mode 100644 index 0000000000000..c9565c0fcc43d --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-groups.xml @@ -0,0 +1,17 @@ + + + + + Provides Status of Doors, Lock State, Service and Check Control Messages + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-types.xml new file mode 100644 index 0000000000000..572baa30057a5 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-types.xml @@ -0,0 +1,30 @@ + + + + String + + + + String + + + + String + + + + String + + + + String + + + + String + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml index 842b64afd8e2c..505b5cc6218f3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml @@ -13,6 +13,7 @@ Electric Car + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml index f907fea8ca537..e18674d4efe6c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml @@ -13,6 +13,7 @@ Electric Car with Range Extender + @@ -21,10 +22,6 @@ - - BMW_I - - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml index a0db79c87443e..f86b36b339ac3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml @@ -13,6 +13,7 @@ Conventional Fuel Car + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml index cac3d4fd2a0b2..67c760b7dec57 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml @@ -13,6 +13,7 @@ Conventional Fuel Car with supporting Electric Engine + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java index d339e8466c7e4..0bb883afb6fa1 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java @@ -46,7 +46,7 @@ public void setup() { } @Test - public void testF15() { + public void testi3Rex() { String content = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); Thing thing = mock(Thing.class); when(thing.getUID()).thenReturn(new ThingUID("testbinding", "test")); @@ -54,7 +54,7 @@ public void testF15() { ConnectedCarHandler cch = new ConnectedCarHandler(thing, hc, CarType.ELECTRIC_REX.toString(), true); ThingHandlerCallback tc = mock(ThingHandlerCallback.class); cch.setCallback(tc); - cch.updateVehicleStatus(content); + cch.updateRangeValues(content); ArgumentCaptor channelCaptor = ArgumentCaptor.forClass(ChannelUID.class); ArgumentCaptor stateCaptor = ArgumentCaptor.forClass(State.class); @@ -66,7 +66,33 @@ public void testF15() { verify(tc, times(12)).stateUpdated(channelCaptor.capture(), stateCaptor.capture()); List allChannels = channelCaptor.getAllValues(); List allStates = stateCaptor.getAllValues(); + for (int i = 0; i < allChannels.size(); i++) { + logger.info("Channel {} {}", allChannels.get(i), allStates.get(i)); + } assertEquals("Results ", 12, allChannels.size()); + } + + @Test + public void testi3RexStatus() { + String content = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); + Thing thing = mock(Thing.class); + when(thing.getUID()).thenReturn(new ThingUID("testbinding", "test")); + HttpClient hc = mock(HttpClient.class); + ConnectedCarHandler cch = new ConnectedCarHandler(thing, hc, CarType.ELECTRIC_REX.toString(), true); + ThingHandlerCallback tc = mock(ThingHandlerCallback.class); + cch.setCallback(tc); + cch.updateVehicleStatus(content); + + ArgumentCaptor channelCaptor = ArgumentCaptor.forClass(ChannelUID.class); + ArgumentCaptor stateCaptor = ArgumentCaptor.forClass(State.class); + ; + + // ArgumentCaptor> channelCaptor; + // ArgumentCaptor> stateCaptor; + + verify(tc, times(6)).stateUpdated(channelCaptor.capture(), stateCaptor.capture()); + List allChannels = channelCaptor.getAllValues(); + List allStates = stateCaptor.getAllValues(); for (int i = 0; i < allChannels.size(); i++) { logger.info("Channel {} {}", allChannels.get(i), allStates.get(i)); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java index fd045979f6de2..76e2f7ec00f8d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java @@ -14,6 +14,7 @@ import static org.junit.Assert.*; +import java.time.LocalDate; import java.util.Locale; import org.junit.Test; @@ -49,4 +50,13 @@ public void testTimeUTCToLocaleTime() { assertEquals("Input DateTime", "2020-08-24T15:55:32", vStatus.internalDataTimeUTC); assertEquals("Output DateTime", "24.08.2020 17:55", Converter.getLocalDateTime(vStatus.internalDataTimeUTC)); } + + @Test + public void testServiceDatePattern() { + String pattern = "2021-11-01"; + LocalDate ldt = LocalDate.parse(pattern, Converter.serviceDateInputPattern); + assertEquals("Parsed Date", "2021-11-01", ldt.toString()); + System.out.println(); + assertEquals("Parsed Date", "Nov 2021", ldt.format(Converter.serviceDateOutputPattern)); + } } From e43651bb92a5d3e1cd836a6031c3ba09c0e97e4a Mon Sep 17 00:00:00 2001 From: Bernd Date: Thu, 27 Aug 2020 01:46:35 +0200 Subject: [PATCH 010/176] added vehicle status Signed-off-by: Bernd (cherry picked from commit 059edbcc1d75331d0262df9b235e7fd659e43e95) Signed-off-by: Bernd --- .../internal/handler/ConnectedCarHandler.java | 13 +++++----- .../internal/utils/Converter.java | 25 +++++++++++++------ 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java index 11a0b062620c4..41c4883d963ec 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java @@ -371,15 +371,16 @@ void updateVehicleStatus(@Nullable String content) { Status status = GSON.fromJson(content, Status.class); VehicleStatus vStatus = status.vehicleStatus; - updateState(lock, StringType.valueOf(vStatus.doorLockState)); - updateState(chargingStatus, StringType.valueOf(vStatus.chargingStatus)); - + updateState(lock, StringType.valueOf(Converter.toTitleCase(vStatus.doorLockState))); Doors doorState = GSON.fromJson(GSON.toJson(vStatus), Doors.class); updateState(doors, StringType.valueOf(checkClosed(doorState))); Windows windowState = GSON.fromJson(GSON.toJson(vStatus), Windows.class); updateState(windows, StringType.valueOf(checkClosed(windowState))); updateState(checkControl, StringType.valueOf(getCheckControl(vStatus.checkControlMessages))); updateState(service, StringType.valueOf(getNextService(vStatus.cbsData))); + if (isElectric) { + updateState(chargingStatus, StringType.valueOf(Converter.toTitleCase(vStatus.chargingStatus))); + } } private @Nullable String getNextService(List cbsData) { @@ -401,7 +402,7 @@ void updateVehicleStatus(@Nullable String content) { } } if (serviceDate != null) { - return serviceDate.format(Converter.serviceDateOutputPattern) + ":" + service; + return serviceDate.format(Converter.serviceDateOutputPattern) + " " + Converter.toTitleCase(service); } else { return "Unknown"; } @@ -412,7 +413,7 @@ void updateVehicleStatus(@Nullable String content) { if (checkControlMessages.isEmpty()) { return "Ok"; } else { - return checkControlMessages.get(0).ccmDescriptionShort; + return Converter.toTitleCase(checkControlMessages.get(0).ccmDescriptionShort); } } @@ -421,7 +422,7 @@ String checkClosed(Object dto) { try { if (field.get(dto).equals("OPEN")) { // report the first door which is still open - return field.getName() + " open"; + return Converter.toTitleCase(field.getName() + " Open"); } } catch (IllegalArgumentException | IllegalAccessException e) { logger.warn("Fields for {} Object not accesible", dto); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java index f502896c575dd..c8d77a4b479cd 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java @@ -17,21 +17,20 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** * The {@link Converter} Data Transfer Object * * @author Bernd Weymann - Initial contribution */ public class Converter { - public final static DateTimeFormatter serviceDateInputPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - public final static DateTimeFormatter serviceDateOutputPattern = DateTimeFormatter.ofPattern("MMM yyyy"); + public static final DateTimeFormatter serviceDateInputPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + public static final DateTimeFormatter serviceDateOutputPattern = DateTimeFormatter.ofPattern("MMM yyyy"); + + public static final String SPACE = " "; + public static final String UNDERLINE = "_"; - private final static Logger logger = LoggerFactory.getLogger(Converter.class); - private final static DateTimeFormatter inputPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); - private final static DateTimeFormatter outputPattern = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); + private static final DateTimeFormatter inputPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); + private static final DateTimeFormatter outputPattern = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); public static double round(double value) { double scale = Math.pow(10, 1); @@ -44,4 +43,14 @@ public static String getLocalDateTime(String input) { ZonedDateTime zdtLZ = zdtUTC.withZoneSameInstant(ZoneId.systemDefault()); return zdtLZ.format(Converter.outputPattern); } + + public static String toTitleCase(String input) { + String lower = input.replaceAll(UNDERLINE, SPACE).toLowerCase(); + String[] arr = lower.split(SPACE); + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < arr.length; i++) { + sb.append(Character.toUpperCase(arr[i].charAt(0))).append(arr[i].substring(1)).append(" "); + } + return sb.toString().trim(); + } } From 2b019228836ffb7a8e63d64bc8b3de278fcc5311 Mon Sep 17 00:00:00 2001 From: Bernd Date: Thu, 27 Aug 2020 17:43:01 +0200 Subject: [PATCH 011/176] add remote services Signed-off-by: Bernd (cherry picked from commit 93803e3565e573765631cbee7b01dea7e8b18989) Signed-off-by: Bernd --- .../obsolete/test.json | 0 .../internal/ConnectedDriveConstants.java | 12 +- .../internal/dto/remote/ExecutionStatus.java | 28 +++ .../dto/remote/ExecutionStatusContainer.java | 22 ++ .../internal/dto/statistics/AllTrips.java | 11 +- .../dto/statistics/AllTripsContainer.java | 22 ++ .../internal/dto/statistics/Community.java | 31 --- .../internal/dto/statistics/LastTrip.java | 16 +- .../dto/statistics/LastTripContainer.java | 22 ++ .../internal/dto/statistics/Trip.java | 36 ---- ...tatus.java => VehicleStatusContainer.java} | 4 +- .../handler/ConnectedCarChannelHandler.java | 18 ++ .../internal/handler/ConnectedCarHandler.java | 136 ++++++------ .../handler/RemoteServiceHandler.java | 193 ++++++++++++++++++ .../thing/remote-service-channel-groups.xml | 17 ++ .../thing/remote-service-channel-types.xml | 30 +++ .../ESH-INF/thing/status-channel-groups.xml | 18 +- .../ESH-INF/thing/status-channel-types.xml | 38 ++-- .../resources/ESH-INF/thing/thing-bev.xml | 10 + .../resources/ESH-INF/thing/thing-bev_rex.xml | 10 + .../resources/ESH-INF/thing/thing-conv.xml | 10 + .../resources/ESH-INF/thing/thing-phev.xml | 10 + .../thing/troubleshoot-channel-groups.xml | 4 +- .../internal/dto/remote/RemoteStatusTest.java | 37 ++++ .../internal/dto/statistics/LastTripTest.java | 4 +- .../dto/status/VehicleStatusTest.java | 2 +- .../internal/util/LocaleTest.java | 4 +- .../webapi/remote-services/delivered.json | 10 + .../webapi/remote-services/executed.json | 12 ++ .../webapi/remote-services/pending.json | 10 + 30 files changed, 605 insertions(+), 172 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/obsolete/test.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatus.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatusContainer.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/AllTripsContainer.java delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/Community.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripContainer.java delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/Trip.java rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/{Status.java => VehicleStatusContainer.java} (85%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/remote-service-channel-groups.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/remote-service-channel-types.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/RemoteStatusTest.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/remote-services/delivered.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/remote-services/executed.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/remote-services/pending.json diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/test.json b/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/test.json new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 6d8f37505b395..fe9797c770bc1 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -93,7 +93,7 @@ public String toString() { public static final String DISCOVERY_FINGERPRINT = "discovery-fingerprint"; public static final String CARDATA_FINGERPRINT = "cardata-fingerprint"; - // Group definitions + // Thing Group definitions public static final String CHANNEL_GROUP_PROPERTIES = "properties"; public static final String CHANNEL_GROUP_STATUS = "status"; public static final String CHANNEL_GROUP_RANGE = "range"; @@ -102,6 +102,7 @@ public String toString() { public static final String CHANNEL_GROUP_CAR_STATUS = "status"; public static final String CHANNEL_GROUP_LOCATION = "location"; public static final String CHANNEL_GROUP_CAR_IMAGE = "image"; + public static final String CHANNEL_GROUP_REMOTE = "remote"; public static final String PROPERTIES_BRAND = "brand"; public static final String PROPERTIES_MODEL = "model"; @@ -157,4 +158,13 @@ public String toString() { // Image public static final String IMAGE = "rendered"; + + // Remote Services + public static final String REMOTE_SERVICE_LIGHT_FLASH = "light"; + public static final String REMOTE_SERVICE_VEHICLE_FINDER = "finder"; + public static final String REMOTE_SERVICE_DOOR_LOCK = "lock"; + public static final String REMOTE_SERVICE_DOOR_UNLOCK = "unlock"; + public static final String REMOTE_SERVICE_HORN = "horn"; + public static final String REMOTE_SERVICE_AIR_CONDITIONING = "climate"; + public static final String REMOTE_STATE = "state"; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatus.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatus.java new file mode 100644 index 0000000000000..40247857a9521 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatus.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.remote; + +/** + * The {@link ExecutionStatus} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class ExecutionStatus { + public String serviceType;// ": "DOOR_UNLOCK", + public String status;// ": "EXECUTED", + public String eventId;// ": "5639303536333926DA7B9400@bmw.de", + // public String extendedStatus;// ": { + // public String newDoorStatus;// ": "INVALID", + // public String oldDoorStatus;// ": "INVALID", + // public String result;// ": "STATUS_NOT_CHANGED" +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatusContainer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatusContainer.java new file mode 100644 index 0000000000000..02136c320c801 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatusContainer.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.remote; + +/** + * The {@link ExecutionStatusContainer} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class ExecutionStatusContainer { + public ExecutionStatus executionStatus; +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/AllTrips.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/AllTrips.java index 46baa6ba99664..3cb1ed332d909 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/AllTrips.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/AllTrips.java @@ -18,5 +18,14 @@ * @author Bernd Weymann - Initial contribution */ public class AllTrips { - public Community allTrips; + public CommunityPowerEntry avgElectricConsumption; + public CommunityPowerEntry avgRecuperation; + public CommunityChargeCycleEntry chargecycleRange; + public CommunityEletricDistanceEntry totalElectricDistance; + public CommunityPowerEntry avgCombinedConsumption; + public float savedCO2;// ":461.083," + public float savedCO2greenEnergy;// ":2712.255," + public float totalSavedFuel;// ":0," + public String resetDate;// ":"2020-08-24T14:40:40+0000"," + public int batterySizeMax;// ":33200 } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/AllTripsContainer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/AllTripsContainer.java new file mode 100644 index 0000000000000..0df724542e3a1 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/AllTripsContainer.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.statistics; + +/** + * The {@link AllTripsContainer} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class AllTripsContainer { + public AllTrips allTrips; +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/Community.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/Community.java deleted file mode 100644 index 9c9d6e1510800..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/Community.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.statistics; - -/** - * The {@link Community} Data Transfer Object - * - * @author Bernd Weymann - Initial contribution - */ -public class Community { - public CommunityPowerEntry avgElectricConsumption; - public CommunityPowerEntry avgRecuperation; - public CommunityChargeCycleEntry chargecycleRange; - public CommunityEletricDistanceEntry totalElectricDistance; - public CommunityPowerEntry avgCombinedConsumption; - public float savedCO2;// ":461.083," - public float savedCO2greenEnergy;// ":2712.255," - public float totalSavedFuel;// ":0," - public String resetDate;// ":"2020-08-24T14:40:40+0000"," - public int batterySizeMax;// ":33200 -} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTrip.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTrip.java index 26969685f839c..23f8a58158d33 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTrip.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTrip.java @@ -18,5 +18,19 @@ * @author Bernd Weymann - Initial contribution */ public class LastTrip { - public Trip lastTrip; + public float efficiencyValue;// ": 0.98, + public float totalDistance;// ": 2, + public float electricDistance;// ": 2, + public float avgElectricConsumption;// ": 7, + public float avgRecuperation;// ": 6, + public float drivingModeValue;// ": 0.87, + public float accelerationValue;// ": 0.99, + public float anticipationValue;// ": 0.99, + public float totalConsumptionValue;// ": 1.25, + public float auxiliaryConsumptionValue;// ": 0.78, + public float avgCombinedConsumption;// ": 0, + public float electricDistanceRatio;// ": 100, + public float savedFuel;// ": 0, + public String date;// ": "2020-08-24T17:55:00+0000", + public float duration;// ": 5 } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripContainer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripContainer.java new file mode 100644 index 0000000000000..c17f774fb42d3 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripContainer.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.statistics; + +/** + * The {@link LastTripContainer} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class LastTripContainer { + public LastTrip lastTrip; +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/Trip.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/Trip.java deleted file mode 100644 index ddba08abc38bc..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/Trip.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.statistics; - -/** - * The {@link Trip} Data Transfer Object - * - * @author Bernd Weymann - Initial contribution - */ -public class Trip { - public float efficiencyValue;// ": 0.98, - public float totalDistance;// ": 2, - public float electricDistance;// ": 2, - public float avgElectricConsumption;// ": 7, - public float avgRecuperation;// ": 6, - public float drivingModeValue;// ": 0.87, - public float accelerationValue;// ": 0.99, - public float anticipationValue;// ": 0.99, - public float totalConsumptionValue;// ": 1.25, - public float auxiliaryConsumptionValue;// ": 0.78, - public float avgCombinedConsumption;// ": 0, - public float electricDistanceRatio;// ": 100, - public float savedFuel;// ": 0, - public String date;// ": "2020-08-24T17:55:00+0000", - public float duration;// ": 5 -} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Status.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusContainer.java similarity index 85% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Status.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusContainer.java index 2297ee88f21c6..26d943d48aaab 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Status.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusContainer.java @@ -13,10 +13,10 @@ package org.openhab.binding.bmwconnecteddrive.internal.dto.status; /** - * The {@link Status} Data Transfer Object + * The {@link VehicleStatusContainer} Data Transfer Object * * @author Bernd Weymann - Initial contribution */ -public class Status { +public class VehicleStatusContainer { public VehicleStatus vehicleStatus; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java index 4b53f9ba0b5b4..fcf451c9f5ede 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java @@ -83,8 +83,18 @@ public class ConnectedCarChannelHandler extends BaseThingHandler { protected ChannelUID heading; protected ChannelUID rangeRadius; + // Image protected ChannelUID imageChannel; + // Remote Services + protected ChannelUID remoteLightChannel; + protected ChannelUID remoteFinderChannel; + protected ChannelUID remoteLockChannel; + protected ChannelUID remoteUnlockChannel; + protected ChannelUID remoteHornChannel; + protected ChannelUID remoteClimateChannel; + protected ChannelUID remoteStateChannel; + public ConnectedCarChannelHandler(Thing thing) { super(thing); @@ -150,6 +160,14 @@ public ConnectedCarChannelHandler(Thing thing) { rangeRadius = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, RANGE_RADIUS); imageChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CAR_IMAGE, IMAGE); + + remoteLightChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_LIGHT_FLASH); + remoteFinderChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_VEHICLE_FINDER); + remoteLockChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_DOOR_LOCK); + remoteUnlockChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_DOOR_UNLOCK); + remoteHornChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_HORN); + remoteClimateChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_AIR_CONDITIONING); + remoteStateChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_STATE); } @Override diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java index 41c4883d963ec..87bc1718e767c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java @@ -19,6 +19,7 @@ import java.time.LocalDate; import java.util.List; import java.util.concurrent.ExecutionException; +import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -50,15 +51,15 @@ import org.openhab.binding.bmwconnecteddrive.internal.ConnectedCarConfiguration; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CarType; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTrips; -import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.Community; +import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTripsContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTrip; -import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.Trip; +import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTripContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.CBSMessage; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.CCMMessage; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Doors; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Position; -import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Status; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Windows; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.slf4j.Logger; @@ -75,11 +76,18 @@ @NonNullByDefault public class ConnectedCarHandler extends ConnectedCarChannelHandler { private final Logger logger = LoggerFactory.getLogger(ConnectedCarHandler.class); - private final static Gson GSON = new Gson(); + + final static Gson GSON = new Gson(); + Token token = new Token(); + @Nullable + String serviceExecutionAPI; + @Nullable + String serviceExecutionStateAPI; private String driveTrain; private HttpClient httpClient; - private Token token = new Token(); + protected RemoteServiceHandler remoteService; + private boolean imperial = false; private boolean hasFuel = false; private boolean isElectric = false; @@ -99,6 +107,7 @@ public class ConnectedCarHandler extends ConnectedCarChannelHandler { private @Nullable String allTripsAPI; private @Nullable String chargeAPI; private @Nullable String destinationAPI; + private @Nullable String rangeMapAPI; private @Nullable String vehicleStatusCache; private @Nullable String lastTripCache; @@ -106,6 +115,7 @@ public class ConnectedCarHandler extends ConnectedCarChannelHandler { public ConnectedCarHandler(Thing thing, HttpClient hc, String type, boolean imperial) { super(thing); + remoteService = new RemoteServiceHandler(this, hc); httpClient = hc; driveTrain = type; this.imperial = imperial; @@ -134,10 +144,39 @@ public void handleCommand(ChannelUID channelUID, Command command) { updateRangeValues(vehicleStatusCache); } } - logger.info("REFRESH {}", group); + // logger.info("REFRESH {}", group); } else { logger.info("No refresh"); } + if (CHANNEL_GROUP_REMOTE.equals(channelUID.getGroupId())) { + logger.info("Remote Command {}", CHANNEL_GROUP_REMOTE); + if (command instanceof OnOffType) { + if (command.equals(OnOffType.ON)) { + switch (channelUID.getIdWithoutGroup()) { + case REMOTE_SERVICE_LIGHT_FLASH: + remoteService.execute(RemoteServiceHandler.RemoteService.LIGHT_FLASH); + break; + case REMOTE_SERVICE_AIR_CONDITIONING: + remoteService.execute(RemoteServiceHandler.RemoteService.AIR_CONDITIONING); + break; + case REMOTE_SERVICE_DOOR_LOCK: + remoteService.execute(RemoteServiceHandler.RemoteService.DOOR_LOCK); + break; + case REMOTE_SERVICE_DOOR_UNLOCK: + remoteService.execute(RemoteServiceHandler.RemoteService.DOOR_UNLOCK); + break; + case REMOTE_SERVICE_HORN: + remoteService.execute(RemoteServiceHandler.RemoteService.HORN); + break; + case REMOTE_SERVICE_VEHICLE_FINDER: + remoteService.execute(RemoteServiceHandler.RemoteService.VEHICLE_FINDER); + break; + } + } + } + } else { + logger.info("Not a Remote Command {}", channelUID.getGroupId()); + } if (channelUID.getIdWithoutGroup().equals(CARDATA_FINGERPRINT)) { logger.info("Trigger CarData Fingerprint"); if (command instanceof OnOffType) { @@ -197,36 +236,13 @@ public void initialize() { chargeAPI = baseUrl + "/chargingprofile"; destinationAPI = baseUrl + "/destinations"; imageAPI = baseUrl + "/image"; - // allAPIs.forEach(entry -> { - // Request req = httpClient.newRequest(entry); - // req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); - // req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); - // try { - // ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); - // logger.info("Status {}", contentResponse.getStatus()); - // logger.info("Reason {}", contentResponse.getReason()); - // logger.info("{}", entry); - // logger.info("{}", contentResponse.getContentAsString()); - // } catch (InterruptedException | TimeoutException | ExecutionException e) { - // logger.warn("Get Data Exception {}", e.getMessage()); - // } - // }); - - /** - * REMOTE_SERVICE_STATUS_URL = VEHICLE_VIN_URL + - * '/serviceExecutionStatus?serviceType={service_type}' - * REMOTE_SERVICE_URL = VEHICLE_VIN_URL + "/executeService" - * VEHICLE_IMAGE_URL = VEHICLE_VIN_URL + "/image?width={width}&height={height}&view={view}" - * VEHICLE_POI_URL = VEHICLE_VIN_URL + '/sendpoi' - */ - - // String baseUrl = "https://" + bridgeHandler.getRegionServer(); - // statusAPI = baseUrl + "/webapi/v1/user/vehicles/" + config.vin + "/status"; - // lastTripAPI = baseUrl + "/webapi/v1/user/vehicles/" + config.vin + "/statistics/lastTrip"; - // /webapi/v1/user/vehicles/:VIN/chargingprofile - // /webapi/v1/user/vehicles/:VIN/destinations - // /webapi/v1/user/vehicles/:VIN/statistics/allTrips - // /webapi/v1/user/vehicles/:VIN/rangemap + + serviceExecutionAPI = baseUrl + "/executeService"; + serviceExecutionStateAPI = baseUrl + "/serviceExecutionStatus?serviceType="; + + // currently delivers response 500 - Internal Server Error + // rangeMapAPI = baseUrl + "/rangemap"; + } else { logger.warn("Brdige Handler null"); } @@ -241,31 +257,6 @@ public void initialize() { } } - /** - * old APIS - * - * String baseUrl = "https://" + bridgeHandler.getRegionServer() + "/api/vehicle"; - * // https://b2vapi.bmwgroup.com/api/vehicle/dynamic/v1/ - * // from bimmer_connect project - * // r = requests.get(self.vehicleApi+'/dynamic/v1/'+self.bmwVin+'?offset=-60', - * vehicleAPI = baseUrl + "/dynamic/v1/" + config.vin + "?offset=-60"; - * // r = requests.post(self.vehicleApi+'/myinfo/v1', data=json.dumps(values), - * sendMessageAPI = baseUrl + "/myinfo/v1"; - * // r = requests.get(self.vehicleApi+'/navigation/v1/'+self.bmwVin, - * // headers=headers,allow_redirects=True) - * navigationAPI = baseUrl + "/navigation/v1/" + config.vin; - * // r = requests.get(self.vehicleApi+'/efficiency/v1/'+self.bmwVin, - * // headers=headers,allow_redirects=True) - * efficiencyAPI = baseUrl + "/efficiency/v1/" + config.vin; - * // r = requests.post(self.vehicleApi+'/remoteservices/v1/'+self.bmwVin+'/'+command, - * remoteControlAPI = baseUrl + "/remoteservices/v1/" + config.vin; - * // r = requests.get(self.vehicleApi+'/remoteservices/v1/'+self.bmwVin+'/state/execution', - * remoteExecutionAPI = baseUrl + "/remoteservices/v1/" + config.vin + "/state/execution"; - * imageAPI = "https://" + bridgeHandler.getRegionServer() + "/webapi/v1/user/vehicles/" - * + config.vin + "/image?width=400&height=400&view=REARBIRDSEYE"; - * - */ - private void startSchedule(int interval) { ScheduledFuture localRefreshJob = refreshJob; if (localRefreshJob != null) { @@ -296,6 +287,7 @@ public void getData() { updateLastTrip(lastTripData); String allTripData = getJSON(allTripsAPI); updateTripStatistics(allTripData); + String rangemapData = getJSON(rangeMapAPI); String chargeData = getJSON(chargeAPI); String destinationData = getJSON(destinationAPI); } @@ -329,8 +321,8 @@ private void updateTripStatistics(@Nullable String content) { return; } allTripsCache = content; - AllTrips at = GSON.fromJson(content, AllTrips.class); - Community c = at.allTrips; + AllTripsContainer at = GSON.fromJson(content, AllTripsContainer.class); + AllTrips c = at.allTrips; updateState(lifeTimeCumulatedDrivenDistance, QuantityType .valueOf(Converter.round(c.totalElectricDistance.userTotal), MetricPrefix.KILO(SIUnits.METRE))); updateState(lifeTimeSingleLongestDistance, @@ -349,8 +341,8 @@ private void updateLastTrip(@Nullable String content) { return; } lastTripCache = content; - LastTrip lt = GSON.fromJson(content, LastTrip.class); - Trip trip = lt.lastTrip; + LastTripContainer lt = GSON.fromJson(content, LastTripContainer.class); + LastTrip trip = lt.lastTrip; updateState(tripDistance, QuantityType.valueOf(Converter.round(trip.totalDistance), MetricPrefix.KILO(SIUnits.METRE))); // updateState(tripDistanceSinceCharging, @@ -368,7 +360,7 @@ void updateVehicleStatus(@Nullable String content) { } logger.info("Vehicle Status {}", content); vehicleStatusCache = content; - Status status = GSON.fromJson(content, Status.class); + VehicleStatusContainer status = GSON.fromJson(content, VehicleStatusContainer.class); VehicleStatus vStatus = status.vehicleStatus; updateState(lock, StringType.valueOf(Converter.toTitleCase(vStatus.doorLockState))); @@ -402,7 +394,7 @@ void updateVehicleStatus(@Nullable String content) { } } if (serviceDate != null) { - return serviceDate.format(Converter.serviceDateOutputPattern) + " " + Converter.toTitleCase(service); + return serviceDate.format(Converter.serviceDateOutputPattern) + " - " + Converter.toTitleCase(service); } else { return "Unknown"; } @@ -437,7 +429,7 @@ void updateRangeValues(@Nullable String content) { logger.warn("No Vehicle Values available"); return; } - Status status = GSON.fromJson(content, Status.class); + VehicleStatusContainer status = GSON.fromJson(content, VehicleStatusContainer.class); VehicleStatus vStatus = status.vehicleStatus; // based on unit of length decide if range shall be reported in km or miles if (!imperial) { @@ -548,4 +540,12 @@ public synchronized boolean tokenUpdate() { } return true; } + + public ScheduledExecutorService getScheduler() { + return scheduler; + } + + public void updateRemoteExecutionStatus(String status) { + updateState(remoteStateChannel, StringType.valueOf(status)); + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java new file mode 100644 index 0000000000000..00d2c77ab8667 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -0,0 +1,193 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import static org.openhab.binding.bmwconnecteddrive.internal.handler.HTTPConstants.*; + +import java.nio.charset.Charset; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +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.client.util.StringContentProvider; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.util.MultiMap; +import org.eclipse.jetty.util.UrlEncoded; +import org.openhab.binding.bmwconnecteddrive.internal.dto.remote.ExecutionStatus; +import org.openhab.binding.bmwconnecteddrive.internal.dto.remote.ExecutionStatusContainer; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link RemoteServiceHandler} handles executions of remote services to your car + * + * @see https://github.com/bimmerconnected/bimmer_connected/blob/master/bimmer_connected/remote_services.py + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class RemoteServiceHandler { + private final Logger logger = LoggerFactory.getLogger(RemoteServiceHandler.class); + + // after 60 retries the state update will give up + private int counter = 0; + private final int giveUpCounter = 120; + + public enum ExecutionState { + READY("READY"), + INITIATED("INITIATED"), + PENDING("PENDING"), + DELIVERED("DELIVERED"), + EXECUTED("EXECUTED"); + + private final String state; + + ExecutionState(String s) { + state = s; + } + + @Override + public String toString() { + return state; + } + } + + public enum RemoteService { + LIGHT_FLASH("LIGHT_FLASH"), + VEHICLE_FINDER("VEHICLE_FINDER"), + DOOR_LOCK("DOOR_LOCK"), + DOOR_UNLOCK("DOOR_UNLOCK"), + HORN("HORN_BLOW"), + AIR_CONDITIONING("CLIMATE_NOW"); + + private final String service; + + RemoteService(String s) { + service = s; + } + + @Override + public String toString() { + return service; + } + } + + private ConnectedCarHandler handler; + private HttpClient httpClient; + private @Nullable String serviceExecuting; + + public RemoteServiceHandler(ConnectedCarHandler connectedCarHandler, HttpClient hc) { + handler = connectedCarHandler; + httpClient = hc; + } + + boolean execute(RemoteService service) { + synchronized (this) { + if (serviceExecuting != null) { + return false; + } + serviceExecuting = service.toString(); + } + if (handler.tokenUpdate()) { + MultiMap dataMap = new MultiMap(); + dataMap.add("serviceType", service.toString()); + String urlEncodedData = UrlEncoded.encode(dataMap, Charset.defaultCharset(), false); + + Request req = httpClient.POST(handler.serviceExecutionAPI); + req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); + req.header("Content-Length", urlEncodedData.length() + ""); + req.header(HttpHeader.AUTHORIZATION, handler.token.getBearerToken()); + req.content(new StringContentProvider(urlEncodedData)); + // logger.info("URL encoded data {}", urlEncodedData); + // logger.info("Data size {} ", urlEncodedData.length()); + + try { + ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); + if (contentResponse.getStatus() != 200) { + logger.info("URL {}", handler.serviceExecutionAPI); + logger.info("Status {}", contentResponse.getStatus()); + logger.info("Reason {}", contentResponse.getReason()); + reset(); + return false; + } else { + logger.info("Executed {}, Response {}", service.toString(), contentResponse.getContentAsString()); + handler.getScheduler().schedule(this::getState, 1, TimeUnit.SECONDS); + return true; + } + } catch (InterruptedException | TimeoutException | ExecutionException e) { + logger.warn("Execute Service Exception {}", e.getMessage()); + reset(); + return false; + } + } else { + reset(); + return false; + } + } + + public void getState() { + if (serviceExecuting == null) { + logger.warn("No Service executed to get state"); + return; + } + if (counter >= giveUpCounter) { + logger.warn("Giving up updating state for {} after {} times", serviceExecuting, giveUpCounter); + } + counter++; + Request req = httpClient.newRequest(handler.serviceExecutionStateAPI + serviceExecuting); + req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); + req.header(HttpHeader.AUTHORIZATION, handler.token.getBearerToken()); + + try { + ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); + if (contentResponse.getStatus() != 200) { + logger.info("URL {}", handler.serviceExecutionStateAPI); + logger.info("Status {}", contentResponse.getStatus()); + logger.info("Reason {}", contentResponse.getReason()); + } else { + String state = contentResponse.getContentAsString(); + logger.info("Executed {}, Response {}", serviceExecuting.toString(), state); + ExecutionStatusContainer esc = ConnectedCarHandler.GSON.fromJson(state, ExecutionStatusContainer.class); + ExecutionStatus execStatus = esc.executionStatus; + + if (!ExecutionState.EXECUTED.toString().equals(execStatus.status)) { + logger.info("Continue state observing"); + handler.updateRemoteExecutionStatus( + Converter.toTitleCase(serviceExecuting + " " + execStatus.status)); + handler.getScheduler().schedule(this::getState, 1, TimeUnit.SECONDS); + } else { + logger.info("Execution finished"); + reset(); + // immediately refresh data + handler.getData(); + } + } + } catch (InterruptedException | TimeoutException | ExecutionException e) { + logger.warn("Execute Service Exception {}", e.getMessage()); + reset(); + } + } + + private void reset() { + synchronized (this) { + serviceExecuting = null; + counter = 0; + } + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/remote-service-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/remote-service-channel-groups.xml new file mode 100644 index 0000000000000..c9565c0fcc43d --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/remote-service-channel-groups.xml @@ -0,0 +1,17 @@ + + + + + Provides Status of Doors, Lock State, Service and Check Control Messages + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/remote-service-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/remote-service-channel-types.xml new file mode 100644 index 0000000000000..572baa30057a5 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/remote-service-channel-types.xml @@ -0,0 +1,30 @@ + + + + String + + + + String + + + + String + + + + String + + + + String + + + + String + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-groups.xml index c9565c0fcc43d..c2596de44800a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-groups.xml @@ -3,15 +3,17 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - - - Provides Status of Doors, Lock State, Service and Check Control Messages + + + Services can be executed via BMW Server like Door lock/unlock, Air Conditioning and more - - - - - + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-types.xml index 572baa30057a5..294dffb158144 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-types.xml @@ -3,28 +3,32 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - - String - + + Switch + - - String - + + Switch + - - String - + + Switch + - - String - + + Switch + - - String - + + Switch + + + + Switch + - + String - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml index 505b5cc6218f3..a2c19d1f1781e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml @@ -18,6 +18,7 @@ + @@ -32,6 +33,15 @@ Data Refresh Rate for your Car values 5 + + + Units are selected via auto-detection but you can overrule + + + + + + Car Image size for width and length diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml index e18674d4efe6c..f45bf1ce3030e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml @@ -18,6 +18,7 @@ + @@ -32,6 +33,15 @@ Data Refresh Rate for your Car values 5 + + + Units are selected via auto-detection but you can overrule + + + + + + Car Image size for width and length diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml index f86b36b339ac3..9cd6a23418b32 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml @@ -16,6 +16,7 @@ + @@ -30,6 +31,15 @@ Data Refresh Rate for your Car values 5 + + + Units are selected via auto-detection but you can overrule + + + + + + Car Image size for width and length diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml index 67c760b7dec57..1af7978667151 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml @@ -18,6 +18,7 @@ + @@ -32,6 +33,15 @@ Data Refresh Rate for your Car values 5 + + + Units are selected via auto-detection but you can overrule + + + + + + Car Image size for width and length diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-groups.xml index a127e58b1754a..7dea5bbb210c8 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-groups.xml @@ -4,8 +4,8 @@ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - - EV Consumption Values and Distances over Lifetime + + Generating Debug Data if a Problem Report shall be raised diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/RemoteStatusTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/RemoteStatusTest.java new file mode 100644 index 0000000000000..5af63d6a47453 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/RemoteStatusTest.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.remote; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.junit.Test; +import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; + +import com.google.gson.Gson; + +/** + * The {@link RemoteStatusTest} Test json responses from ConnectedDrive Portal + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class RemoteStatusTest { + private static final Gson GSON = new Gson(); + + @Test + public void testStatus() { + String resource1 = FileReader.readFileInString("src/test/resources/webapi/remote-services/pending.json"); + ExecutionStatusContainer esc = GSON.fromJson(resource1, ExecutionStatusContainer.class); + ExecutionStatus execStatus = esc.executionStatus; + System.out.println(execStatus.status); + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripTest.java index 3c5374ee63c3f..6cfd4b5ef9f3a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripTest.java @@ -32,8 +32,8 @@ public class LastTripTest { @Test public void testUserInfo() { String content = FileReader.readFileInString("src/test/resources/webapi/last-trip.json"); - LastTrip lt = GSON.fromJson(content, LastTrip.class); - Trip trip = lt.lastTrip; + LastTripContainer lt = GSON.fromJson(content, LastTripContainer.class); + LastTrip trip = lt.lastTrip; assertNotNull(trip); System.out.println(trip.totalDistance); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusTest.java index fbff22419609c..af4e64b0359d7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusTest.java @@ -32,7 +32,7 @@ public class VehicleStatusTest { @Test public void testtestBEV_REX_Values() { String resource1 = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); - Status status = GSON.fromJson(resource1, Status.class); + VehicleStatusContainer status = GSON.fromJson(resource1, VehicleStatusContainer.class); VehicleStatus vStatus = status.vehicleStatus; assertEquals("Mileage", 17273.0, vStatus.mileage, 0.1); Position p = vStatus.position; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java index 76e2f7ec00f8d..922873cfd57c8 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java @@ -19,7 +19,7 @@ import org.junit.Test; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants; -import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Status; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; @@ -45,7 +45,7 @@ public void languageTest() { @Test public void testTimeUTCToLocaleTime() { String resource1 = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); - Status status = GSON.fromJson(resource1, Status.class); + VehicleStatusContainer status = GSON.fromJson(resource1, VehicleStatusContainer.class); VehicleStatus vStatus = status.vehicleStatus; assertEquals("Input DateTime", "2020-08-24T15:55:32", vStatus.internalDataTimeUTC); assertEquals("Output DateTime", "24.08.2020 17:55", Converter.getLocalDateTime(vStatus.internalDataTimeUTC)); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/remote-services/delivered.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/remote-services/delivered.json new file mode 100644 index 0000000000000..cfc5300fc0deb --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/remote-services/delivered.json @@ -0,0 +1,10 @@ +{ + "executionStatus": { + "serviceType": "DOOR_UNLOCK", + "status": "DELIVERED", + "eventId": "5639303536333926DA7B9400@bmw.de", + "extendedStatus": { + "result": "STATUS_UNKNOWN" + } + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/remote-services/executed.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/remote-services/executed.json new file mode 100644 index 0000000000000..0cd2101428176 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/remote-services/executed.json @@ -0,0 +1,12 @@ +{ + "executionStatus": { + "serviceType": "DOOR_UNLOCK", + "status": "EXECUTED", + "eventId": "5639303536333926DA7B9400@bmw.de", + "extendedStatus": { + "newDoorStatus": "INVALID", + "oldDoorStatus": "INVALID", + "result": "STATUS_NOT_CHANGED" + } + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/remote-services/pending.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/remote-services/pending.json new file mode 100644 index 0000000000000..1a46f7146b578 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/remote-services/pending.json @@ -0,0 +1,10 @@ +{ + "executionStatus": { + "serviceType": "DOOR_UNLOCK", + "status": "PENDING", + "eventId": "5639303536333926DA7B9400@bmw.de", + "extendedStatus": { + "result": "STATUS_UNKNOWN" + } + } +} From f509bc40c8056dbba4013e5b9c5741cb460d0a9c Mon Sep 17 00:00:00 2001 From: Bernd Date: Fri, 28 Aug 2020 09:49:03 +0200 Subject: [PATCH 012/176] reduce logging Signed-off-by: Bernd (cherry picked from commit 9d3bd24bb893363a0c2b81149322228e7b6d35ce) Signed-off-by: Bernd --- .../org.openhab.binding.bmwconnecteddrive/.classpath | 6 ++++++ .../internal/handler/ConnectedCarHandler.java | 11 +++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/.classpath b/bundles/org.openhab.binding.bmwconnecteddrive/.classpath index a5d95095ccaaf..1a0c5608f3440 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/.classpath +++ b/bundles/org.openhab.binding.bmwconnecteddrive/.classpath @@ -28,5 +28,11 @@ + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java index 87bc1718e767c..17240ff8a4bf8 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java @@ -139,14 +139,9 @@ public void handleCommand(ChannelUID channelUID, Command command) { if (allTripsCache != null) { updateTripStatistics(allTripsCache); } - } else { - if (vehicleStatusCache != null) { + } else if (vehicleStatusCache != null) { updateRangeValues(vehicleStatusCache); - } } - // logger.info("REFRESH {}", group); - } else { - logger.info("No refresh"); } if (CHANNEL_GROUP_REMOTE.equals(channelUID.getGroupId())) { logger.info("Remote Command {}", CHANNEL_GROUP_REMOTE); @@ -174,8 +169,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { } } } - } else { - logger.info("Not a Remote Command {}", channelUID.getGroupId()); } if (channelUID.getIdWithoutGroup().equals(CARDATA_FINGERPRINT)) { logger.info("Trigger CarData Fingerprint"); @@ -288,7 +281,9 @@ public void getData() { String allTripData = getJSON(allTripsAPI); updateTripStatistics(allTripData); String rangemapData = getJSON(rangeMapAPI); + logger.info("RangeMap {}",rangemapData); String chargeData = getJSON(chargeAPI); + logger.info("Chatge Data {}",chargeData); String destinationData = getJSON(destinationAPI); } From 00e0239ccc85a976e3364fd31faba7004b358f6f Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 1 Sep 2020 01:30:42 +0200 Subject: [PATCH 013/176] Asnyc Jetty Client API Signed-off-by: Bernd (cherry picked from commit ea6a7e759907e9e7dc92375f53eb0d176a5638b7) Signed-off-by: Bernd --- .../README.md | 164 +++- .../doc/bmw-connected.png | Bin 0 -> 75918 bytes .../internal/ConnectedCarConfiguration.java | 8 + .../internal/ConnectedDriveConstants.java | 11 +- .../discovery/ConnectedCarDiscovery.java | 17 +- .../internal/dto/Vehicle.java | 7 +- .../dto/remote/ExecutionStatusContainer.java | 2 +- .../internal/dto/status/CBSMessage.java | 1 + .../internal/dto/status/Position.java | 5 + .../internal/dto/status/VehicleStatus.java | 121 ++- .../handler/ByteResponseCallback.java | 29 + .../handler/ConnectedCarChannelHandler.java | 83 +- .../internal/handler/ConnectedCarHandler.java | 738 ++++++++++-------- .../handler/ConnectedDriveBridgeHandler.java | 192 ++--- .../internal/handler/ConnectedDriveProxy.java | 259 ++++++ .../handler/RemoteServiceHandler.java | 54 +- .../internal/handler/ResponseCallback.java | 25 + .../handler/StringResponseCallback.java | 29 + .../{handler => utils}/BimmerConstants.java | 2 +- .../internal/utils/Converter.java | 61 +- .../{handler => utils}/HTTPConstants.java | 3 +- .../resources/ESH-INF/binding/binding.xml | 2 +- .../resources/ESH-INF/thing/thing-bev.xml | 4 +- .../resources/ESH-INF/thing/thing-bev_rex.xml | 6 +- .../resources/ESH-INF/thing/thing-conv.xml | 6 +- .../resources/ESH-INF/thing/thing-phev.xml | 6 +- .../internal/discovery/DiscoveryTest.java | 67 ++ .../internal/dto/ConnectedDriveTest.java | 4 +- .../internal/dto/remote/RemoteStatusTest.java | 5 +- .../internal/dto/statistics/LastTripTest.java | 4 +- .../internal/dto/status/StatusWrapper.java | 247 ++++++ .../dto/status/VehicleStatusTest.java | 5 +- .../internal/handler/AuthTest.java | 10 +- .../internal/handler/CarTests.java | 295 ++++++- .../internal/handler/ErrorResponseTest.java | 105 +++ .../internal/util/LocaleTest.java | 16 +- 36 files changed, 1922 insertions(+), 671 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/doc/bmw-connected.png create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ByteResponseCallback.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ResponseCallback.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/StringResponseCallback.java rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/{handler => utils}/BimmerConstants.java (97%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/{handler => utils}/HTTPConstants.java (92%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/StatusWrapper.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ErrorResponseTest.java diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index bd703e1caccc3..6a0d587f38767 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -1,66 +1,160 @@ # BMWConnectedDrive Binding -_Give some details about what this binding is meant for - a protocol, system, specific device._ + -_If possible, provide some resources like pictures, a YouTube video, etc. to give an impression of what can be done with this binding. You can place such resources into a `doc` folder next to this README.md._ +The Binding connects your BMW Vehicales which are registered in your _Garage_ in your BMW ConnectedDrive Portal. ## Supported Things -_Please describe the different supported things / devices within this section._ -_Which different types are supported, which models were tested etc.?_ -_Note that it is planned to generate some part of this based on the XML files within ```src/main/resources/ESH-INF/thing``` of your binding._ +### Bridge + +The Bridge etsablishes the Connection between BMW ConnectedDrive Portal and opanHAB. + +| Name | Bridge Type ID | Description | +|----------------------------|----------------|------------------------------------------------------------| +| BMW ConnectedDrive Account | account | Access to BMW ConnectedDrive Portal for a specific user | + + +### Things + +Four different Vehcile Types are provided. They differ in the supported Channel Groups & Channels. +While Conventional Fuel Vehicles have no "Charging Profile" Electric Vehicles don't provide a _fuel range_. +For Hybrid Vehicles _fuel range_ and _electric range_ is provided and in addition a _combined range_ + +| Name | Thing Type ID | Supported Channel Groups | +|-------------------------------------|---------------|------------------------------------------------------------| +| BMW Electric Vehicle | BEV | status, range, last-trip, all-trips, charge-profile, image, troubeshoot | +| BMW Electric Vehicle with REX | BEV_REX | status, range, last-trip, all-trips, charge-profile, image, troubeshoot | +| BMW Plug-In-Hybrid Electric Vehicle | PHEV | status, range, last-trip, all-trips, image, troubeshoot | +| BMW Conventional Vehicle | CONV | status, range, last-trip, all-trips, image, troubeshoot | ## Discovery -_Describe the available auto-discovery features here. Mention for what it works and what needs to be kept in mind when using it._ +Auto Discovery is starting after you created the Bridge towards BMW ConnectedDrive Portal. +A list of your registered Vehicles is queried and all found Vehicles are added in Inbox. +As Unique Identifier the _Vehicle Identification Number_ (VIN) is used. +So if you already predefined a Thing in *.things configuration with the same VIN the Discovery won't highlight it again. +Please note for Auto Detected Vehicles there are many Properties for the Vehicle added like Color, Model Type, responsible Dealer and more. -## TroubleShooting +## Configuration -### Discovery +### Bridge -### Car Data +| Parameter | Type | Description | +|-----------------|---------|-------------------------------------------------------------------------| +| userName | text | BMW Connected Drive Username | +| password | text | BMW Connected Drive Password | +| region | text | Select your Region in order to connect to the appropriate BMW Server. Select from Drop Down list _North America_, _China_ or _Rest of World_. | -### Update Timestamp +### Things -Check your Locale Time Settings of your Raspi / PC +All Things are needing the same Configuration Data -## Binding Configuration +| Parameter | Type | Description | +|-----------------|---------|-------------------------------------------------------------------------| +| vin | text | Vehicle Identification Number (VIN) | +| refreshInterval | integer | Refresh Interval in Minutes | +| units | text | Unit Selection. Either AUTODETECT (UK & US) or directly set the desired Units Metric or Imperial | +| imageSize | integer | Image Picture Size< | +| imageViewport | text | Image Viewport - FRONT, REAR, SIDE, DASHBOARD, DRIVERDOOR | -_If your binding requires or supports general configuration settings, please create a folder ```cfg``` and place the configuration file ```.cfg``` inside it. In this section, you should link to this file and provide some information about the options. The file could e.g. look like:_ +## Channels -``` -# Configuration for the Philips Hue Binding -# -# Default secret key for the pairing of the Philips Hue Bridge. -# It has to be between 10-40 (alphanumeric) characters -# This may be changed by the user for security reasons. -secret=openHABSecret -``` +There are many Channels available for each Vehilce. For better overview they are clustered in different Channel Groups. -_Note that it is planned to generate some part of this based on the information that is available within ```src/main/resources/ESH-INF/binding``` of your binding._ +### Channel Group _Status_ -_If your binding does not offer any generic configurations, you can remove this section completely._ +| Channel Label | Channel Group ID | Channel ID | Type | Description | +|-----------------------|------------------|---------------------|--------|---------------------------------------------------| +| Modbus-ID | status | modbus-id | String | Modbus ID / Magic Byte of E3DC | -## Thing Configuration -_Describe what is needed to manually configure a thing, either through the (Paper) UI or via a thing-file. This should be mainly about its mandatory and optional configuration parameters. A short example entry for a thing file can help!_ +### Channel Group _Range Data_ -_Note that it is planned to generate some part of this based on the XML files within ```src/main/resources/ESH-INF/thing``` of your binding._ +| Channel Label | Channel Group ID | Channel ID | Type | Description | +|-----------------------|------------------|---------------------|--------|---------------------------------------------------| +| Modbus-ID | range | modbus-id | String | Modbus ID / Magic Byte of E3DC | -## Channels +### Channel Group _Last Trip_ + +| Channel Label | Channel Group ID | Channel ID | Type | Description | +|-----------------------|------------------|---------------------|--------|---------------------------------------------------| +| Modbus-ID | status | modbus-id | String | Modbus ID / Magic Byte of E3DC | + + +### Channel Group _Lifetime Statistics_ + +| Channel Label | Channel Group ID | Channel ID | Type | Description | +|-----------------------|------------------|---------------------|--------|---------------------------------------------------| +| Modbus-ID | range | modbus-id | String | Modbus ID / Magic Byte of E3DC | + +### Channel Group _Vehicle Location_ + +| Channel Label | Channel Group ID | Channel ID | Type | Description | +|-----------------------|------------------|---------------------|--------|---------------------------------------------------| +| Modbus-ID | status | modbus-id | String | Modbus ID / Magic Byte of E3DC | + + +### Channel Group _Remote Services_ + +| Channel Label | Channel Group ID | Channel ID | Type | Description | +|-----------------------|------------------|---------------------|--------|---------------------------------------------------| +| Modbus-ID | range | modbus-id | String | Modbus ID / Magic Byte of E3DC | + +### Channel Group _Image_ -_Here you should provide information about available channel types, what their meaning is and how they can be used._ +| Channel Label | Channel Group ID | Channel ID | Type | Description | +|-----------------------|------------------|---------------------|--------|---------------------------------------------------| +| Modbus-ID | status | modbus-id | String | Modbus ID / Magic Byte of E3DC | -_Note that it is planned to generate some part of this based on the XML files within ```src/main/resources/ESH-INF/thing``` of your binding._ -| channel | type | description | -|----------|--------|------------------------------| -| control | Switch | This is the control channel | +### Channel Group _Troubleshooting_ + +| Channel Label | Channel Group ID | Channel ID | Type | Description | +|-----------------------|------------------|---------------------|--------|---------------------------------------------------| +| Modbus-ID | range | modbus-id | String | Modbus ID / Magic Byte of E3DC | + +## TroubleShooting + +In order to to identify issues the TroubleShooting Channels are providing Analysis Informations + +### Discovery + +If your Vehicle isn't discovered correctly perform the following steps + +* Check if your Vehicle is attached correctly in ConnectedDrive. Only if it's attached to your ConnectedDrive Account it's possible to detect it. +* In the below example sitemap the Switch _Log Discovery Fingerprint_ can be executed. + +### Car Data + +### Update Timestamp + +There's a timestamp showing the last update of your Vehicle. If this isn't shown correctly please check the date settings. +In case of Raspberry Pi execute _raspi-cinfig_, select _Localization Options_, the _Change Time Zone_ +Select your _Geaographical Area_ and afterwards the correct City. +One restart of openHAB service with _systemctl restart openhab2_ is necessary in order to see the corrected Time Settings. ## Full Example -_Provide a full usage example based on textual configuration files (*.things, *.items, *.sitemap)._ +### Things + +### Items + +### Sitemap + +## Going further + +You're now able to receive your Vehicle Data in openHAB. Continue the work and combine this data with other Powerful openHAB Bindings and Widgets. + +### OpenstreetMap Widget + +### OpenWeatherMap Binding and Widget + +Especially Electric Vehicles which maybe are charged with your Local Photovoltaic System the Weather forecast and corresponding Cloudiness is interesting. +Use the OpenWeatherMap Binding and existing [Widget Solutions[(https://community.openhab.org/t/openweathermap-widget-for-habpanel/65027) to check this data in addition to your Vehicles State of Charge. -## Any custom content here! +## Credits -_Feel free to add additional sections for whatever you think should also be mentioned about your binding!_ +This work is based on the work of [Bimmer Connected](https://github.com/bimmerconnected/bimmer_connected). +Also a [manual installation based on python](https://community.openhab.org/t/script-to-access-the-bmw-connecteddrive-portal-via-oh/37345) was already available for openHAB. +This Binding is basically a port to openHAB based on these concept works! diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/doc/bmw-connected.png b/bundles/org.openhab.binding.bmwconnecteddrive/doc/bmw-connected.png new file mode 100644 index 0000000000000000000000000000000000000000..b5e399db7200a5d7bc97e981b53db09a74cdf258 GIT binary patch literal 75918 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�R#W%}g7G!^h^a^8icy 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%0ATi4cjQ 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 Eg4OzIQ~&?~ literal 0 HcmV?d00001 diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java index caafedeebaf63..894618d275960 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java @@ -31,6 +31,14 @@ public class ConnectedCarConfiguration { */ public int refreshInterval = 15; + /** + * Either Auto Detect Miles units (UK & US) or select Format directly + * + * + * + */ + public String units = "AUTODETECT"; + /** * image size - width & length (square) */ diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index fe9797c770bc1..cd90210665ab7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -29,6 +29,13 @@ public class ConnectedDriveConstants { private static final String BINDING_ID = "bmwconnecteddrive"; + public static final String ANONYMOUS = "ANONYMOUS"; + + // Units + public static final String UNITS_AUTODETECT = "AUTODETECT"; + public static final String UNITS_IMPERIAL = "IMPERIAL"; + public static final String UNITS_METRIC = "METRIC"; + // See constants from bimmer-connected // https://github.com/bimmerconnected/bimmer_connected/blob/master/bimmer_connected/vehicle.py public enum CarType { @@ -94,7 +101,6 @@ public String toString() { public static final String CARDATA_FINGERPRINT = "cardata-fingerprint"; // Thing Group definitions - public static final String CHANNEL_GROUP_PROPERTIES = "properties"; public static final String CHANNEL_GROUP_STATUS = "status"; public static final String CHANNEL_GROUP_RANGE = "range"; public static final String CHANNEL_GROUP_LIFETIME = "lifetime"; @@ -103,6 +109,9 @@ public String toString() { public static final String CHANNEL_GROUP_LOCATION = "location"; public static final String CHANNEL_GROUP_CAR_IMAGE = "image"; public static final String CHANNEL_GROUP_REMOTE = "remote"; + public static final String CHANNEL_GROUP_CHARGE_PROFILE = "charge-profile"; + public static final String CHANNEL_GROUP_RANGE_MAP = "range-map"; + public static final String CHANNEL_GROUP_TROUBLESHOOT = "troubleshoot"; public static final String PROPERTIES_BRAND = "brand"; public static final String PROPERTIES_MODEL = "model"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java index adb8be794410b..21a90c1fea0d0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java @@ -45,7 +45,6 @@ public class ConnectedCarDiscovery extends AbstractDiscoveryService { public ConnectedCarDiscovery(ConnectedDriveBridgeHandler bh) { super(SUPPORTED_THING_SET, DISCOVERY_TIMEOUT, false); bridgeHandler = bh; - logger.info("Created ConnectedCarDiscovery"); } @Override @@ -73,10 +72,12 @@ public void scan(ConnectedDriveUserInfo cdui) { properties.put("yearOfConstruction", vehicle.yearOfConstruction); properties.put("bodytype", vehicle.bodytype); properties.put("statisticsCommunityEnabled", vehicle.color); - properties.put("dealerName", vehicle.dealer.name); - properties.put("dealerAddress", vehicle.dealer.street + " " + vehicle.dealer.country + " " - + vehicle.dealer.postalCode + " " + vehicle.dealer.city); - properties.put("dealerPhone", vehicle.dealer.phone); + if (vehicle.dealer != null) { + properties.put("dealerName", vehicle.dealer.name); + properties.put("dealerAddress", vehicle.dealer.street + " " + vehicle.dealer.country + " " + + vehicle.dealer.postalCode + " " + vehicle.dealer.city); + properties.put("dealerPhone", vehicle.dealer.phone); + } properties.put("breakdownNumber", vehicle.breakdownNumber); StringBuffer chargingModes = new StringBuffer(); if (vehicle.supportedChargingModes != null) { @@ -102,8 +103,10 @@ public String getObject(Object obj, String compare) { StringBuffer buf = new StringBuffer(); for (Field field : obj.getClass().getDeclaredFields()) { try { - if (field.get(obj).equals(compare)) { - buf.append(field.getName()); + if (field.get(obj) != null) { + if (field.get(obj).equals(compare)) { + buf.append(field.getName()); + } } } catch (IllegalArgumentException e) { logger.warn("Field {} not found {}", compare, e.getMessage()); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Vehicle.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Vehicle.java index 4411888fa54e5..ec0642e3b27be 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Vehicle.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Vehicle.java @@ -21,9 +21,10 @@ * @author Bernd Weymann - Initial contribution */ public class Vehicle { - public final static String ACTIVATED = "ACTIVATED"; - public final static String SUPPORTED = "SUPPORTED"; - public final static String NOT_SUPPORTED = "NOT_SUPPORTED"; + public static final String ACTIVATED = "ACTIVATED"; + public static final String SUPPORTED = "SUPPORTED"; + public static final String NOT_SUPPORTED = "NOT_SUPPORTED"; + public String vin; public String model; public String driveTrain; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatusContainer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatusContainer.java index 02136c320c801..8f44924e1913d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatusContainer.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatusContainer.java @@ -19,4 +19,4 @@ */ public class ExecutionStatusContainer { public ExecutionStatus executionStatus; -} \ No newline at end of file +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java index b473968d785c0..8e8f710fb45aa 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java @@ -22,4 +22,5 @@ public class CBSMessage { public String cbsState;// ": "OK", public String cbsDueDate;// ": "2021-11", public String cbsDescription;// ": "Next change due at the latest by the stated date." + public int cbsRemainingMileage; // 46000 } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java index 8cc55ed87e864..c23398eab3a18 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java @@ -22,4 +22,9 @@ public class Position { public float lon;// ": 8.495669, public int heading;// ": 219, public String status;// ": "OK" + + @Override + public String toString() { + return new StringBuffer(Float.toString(lat)).append(",").append(Float.toString(lon)).toString(); + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java index 1ba071fee5696..8086b2eaaf264 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java @@ -12,14 +12,30 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.dto.status; +import java.lang.reflect.Field; +import java.time.LocalDate; import java.util.List; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; + +import com.google.gson.annotations.SerializedName; + /** * The {@link VehicleStatus} Data Transfer Object * * @author Bernd Weymann - Initial contribution */ public class VehicleStatus { + public static final String OK = "Ok"; + public static final String OPEN = "OPEN"; + public static final String INVALID = "INVALID"; + public static final String CLOSED = "CLOSED"; + public static final String UNKNOWN = "UNKOWN"; + public static final String NO_SERVICE_REQUEST = "No Service Requests"; + public static final String APPENDIX_DAY = "-01"; // needed to complete Service Date + public static final String MILES_SHORT = "mi"; + public static final String KM_SHORT = "km"; + public int mileage;// ": 17273, public float remainingFuel;// ": 4, public float remainingRangeElectric;// ": 148, @@ -58,8 +74,109 @@ public class VehicleStatus { public String chargingConnectionType;// ": "CONDUCTIVE", public String chargingInductivePositioning;// ": "NOT_POSITIONED", public String vehicleCountry;// ": "DE","+" - public String DCS_CCH_Activation;// ": "NA", - public boolean DCS_CCH_Ongoing;// ":false + @SerializedName("DCS_CCH_Activation") + public String dcsCchActivation;// ": "NA", + @SerializedName("DCS_CCH_Ongoing") + public boolean dcsCchOngoing;// ":false public List checkControlMessages;// ":[], public List cbsData; + + /** + * Get Next Service for Date and / or Mileage + * + * @param imperial + * @return + */ + public String getNextService(boolean imperial) { + if (cbsData == null) { + return Converter.toTitleCase(UNKNOWN); + } + if (cbsData.isEmpty()) { + return NO_SERVICE_REQUEST; + } else { + int serviceMileage = Integer.MAX_VALUE; + LocalDate serviceDate = LocalDate.now().plusYears(100); + String service = null; + + for (int i = 0; i < cbsData.size(); i++) { + CBSMessage entry = cbsData.get(i); + String serviceDescription = Converter.toTitleCase(entry.cbsType); + if (entry.cbsRemainingMileage != 0 && entry.cbsDueDate != null) { + LocalDate d = LocalDate.parse(entry.cbsDueDate + APPENDIX_DAY, + Converter.SERVICE_DATE_INPUT_PATTERN); + if ((entry.cbsRemainingMileage < serviceMileage) || (d.isBefore(serviceDate))) { + serviceDate = d; + serviceMileage = entry.cbsRemainingMileage; + service = new StringBuffer(serviceDate.format(Converter.SERVICE_DATE_OUTPUT_PATTERN)) + .append(" or in ").append(serviceMileage).append(" ").append(getUnit(imperial)) + .append(" - ").append(serviceDescription).toString(); + } + } else if (entry.cbsRemainingMileage != 0) { + if (entry.cbsRemainingMileage < serviceMileage) { + serviceMileage = entry.cbsRemainingMileage; + service = new StringBuffer("In ").append(serviceMileage).append(" ").append(getUnit(imperial)) + .append(" - ").append(serviceDescription).toString(); + } + } else if (entry.cbsDueDate != null) { + LocalDate d = LocalDate.parse(entry.cbsDueDate + APPENDIX_DAY, + Converter.SERVICE_DATE_INPUT_PATTERN); + if (d.isBefore(serviceDate)) { + serviceDate = d; + service = new StringBuffer(serviceDate.format(Converter.SERVICE_DATE_OUTPUT_PATTERN)) + .append(" - ").append(serviceDescription).toString(); + } + } + } + if (service != null) { + return service; + } else { + return "Unknown"; + } + } + } + + private Object getUnit(boolean imperial) { + if (imperial) { + return MILES_SHORT; + } else { + return KM_SHORT; + } + } + + public String getCheckControl() { + if (checkControlMessages == null) { + return Converter.toTitleCase(UNKNOWN); + } + if (checkControlMessages.isEmpty()) { + return OK; + } else { + return Converter.toTitleCase(checkControlMessages.get(0).ccmDescriptionShort); + } + } + + public static String checkClosed(Object dto) { + boolean validDoorFound = false; + for (Field field : dto.getClass().getDeclaredFields()) { + try { + if (field.get(dto) != null) { + if (field.get(dto).equals(OPEN)) { + // report the first door which is still open + return Converter + .toTitleCase(new StringBuffer(field.getName()).append(" ").append(OPEN).toString()); + // Ignore INVALID fields == Door not present } else if (field.get(dto).equals(INVALID)) { + } else if (field.get(dto).equals(CLOSED)) { + validDoorFound = true; + } + } + } catch (IllegalArgumentException | IllegalAccessException e) { + return Converter.toTitleCase(UNKNOWN); + } + } + if (validDoorFound) { + return Converter.toTitleCase(CLOSED); + } else { + return Converter.toTitleCase(UNKNOWN); + } + } + } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ByteResponseCallback.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ByteResponseCallback.java new file mode 100644 index 0000000000000..454be8d312fcc --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ByteResponseCallback.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import java.util.Optional; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link ByteResponseCallback} Interface for all Callbacks from async REST API results + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public interface ByteResponseCallback extends ResponseCallback { + + public void onResponse(Optional result); + +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java index fcf451c9f5ede..f3ca2bef7d79c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java @@ -29,23 +29,23 @@ @NonNullByDefault public class ConnectedCarChannelHandler extends BaseThingHandler { // Property Channels - protected ChannelUID brandChannel; - protected ChannelUID modelChannel; - protected ChannelUID drivetrainChannel; - protected ChannelUID bodyChannel; - protected ChannelUID colorChannel; - protected ChannelUID constructionYearChannel; - protected ChannelUID communityStatisticsChannel; - protected ChannelUID alarmChannel; - protected ChannelUID dealerNameChannel; - protected ChannelUID dealerAddressChannel; - protected ChannelUID dealerPhoneChannel; - protected ChannelUID breakdownPhoneChannel; - protected ChannelUID activatedServicesChannel; - protected ChannelUID deactivatedServicesChannel; - protected ChannelUID supportedServicesChannel; - protected ChannelUID notSupportedServicesChannel; - protected ChannelUID chargingModesChannel; + // protected ChannelUID brandChannel; + // protected ChannelUID modelChannel; + // protected ChannelUID drivetrainChannel; + // protected ChannelUID bodyChannel; + // protected ChannelUID colorChannel; + // protected ChannelUID constructionYearChannel; + // protected ChannelUID communityStatisticsChannel; + // protected ChannelUID alarmChannel; + // protected ChannelUID dealerNameChannel; + // protected ChannelUID dealerAddressChannel; + // protected ChannelUID dealerPhoneChannel; + // protected ChannelUID breakdownPhoneChannel; + // protected ChannelUID activatedServicesChannel; + // protected ChannelUID deactivatedServicesChannel; + // protected ChannelUID supportedServicesChannel; + // protected ChannelUID notSupportedServicesChannel; + // protected ChannelUID chargingModesChannel; // Vahicle Status Channels protected ChannelUID doors; @@ -95,32 +95,35 @@ public class ConnectedCarChannelHandler extends BaseThingHandler { protected ChannelUID remoteClimateChannel; protected ChannelUID remoteStateChannel; + // Troubleshooting + protected ChannelUID carDataFingerprint; + public ConnectedCarChannelHandler(Thing thing) { super(thing); // create properties channels - brandChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_BRAND); - modelChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_MODEL); - drivetrainChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_DRIVETRAIN); - bodyChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_BODYTYPE); - colorChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_COLOR); - constructionYearChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, - PROPERTIES_CONSTRUCTION_YEAR); - communityStatisticsChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_COMMUNITY); - alarmChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_ALARM); - dealerNameChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_DEALER_NAME); - dealerAddressChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_DEALER_ADDRESS); - dealerPhoneChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_DEALER_PHONE); - breakdownPhoneChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_BREAKDOWN_PHONE); - activatedServicesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, - PROPERTIES_ACTIVATED_SERVICES); - deactivatedServicesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, - PROPERTIES_DEACTIVATED_SERVICES); - supportedServicesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, - PROPERTIES_SUPPORTED_SERVICES); - notSupportedServicesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, - PROPERTIES_NOT_SUPPORTED_SERVICES); - chargingModesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_CHARGING_MODES); + // brandChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_BRAND); + // modelChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_MODEL); + // drivetrainChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_DRIVETRAIN); + // bodyChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_BODYTYPE); + // colorChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_COLOR); + // constructionYearChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, + // PROPERTIES_CONSTRUCTION_YEAR); + // communityStatisticsChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_COMMUNITY); + // alarmChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_ALARM); + // dealerNameChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_DEALER_NAME); + // dealerAddressChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_DEALER_ADDRESS); + // dealerPhoneChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_DEALER_PHONE); + // breakdownPhoneChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_BREAKDOWN_PHONE); + // activatedServicesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, + // PROPERTIES_ACTIVATED_SERVICES); + // deactivatedServicesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, + // PROPERTIES_DEACTIVATED_SERVICES); + // supportedServicesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, + // PROPERTIES_SUPPORTED_SERVICES); + // notSupportedServicesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, + // PROPERTIES_NOT_SUPPORTED_SERVICES); + // chargingModesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_CHARGING_MODES); // Vehicle Status channels doors = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, DOORS); @@ -168,6 +171,8 @@ public ConnectedCarChannelHandler(Thing thing) { remoteHornChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_HORN); remoteClimateChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_AIR_CONDITIONING); remoteStateChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_STATE); + + carDataFingerprint = new ChannelUID(thing.getUID(), CHANNEL_GROUP_TROUBLESHOOT, CARDATA_FINGERPRINT); } @Override diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java index 17240ff8a4bf8..29103ad8ce1b8 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java @@ -13,23 +13,16 @@ package org.openhab.binding.bmwconnecteddrive.internal.handler; import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; -import static org.openhab.binding.bmwconnecteddrive.internal.handler.HTTPConstants.CONTENT_TYPE_JSON; -import java.lang.reflect.Field; -import java.time.LocalDate; -import java.util.List; -import java.util.concurrent.ExecutionException; +import java.time.LocalDateTime; +import java.util.Optional; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; 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.util.MultiMap; import org.eclipse.smarthome.core.library.types.DecimalType; import org.eclipse.smarthome.core.library.types.OnOffType; import org.eclipse.smarthome.core.library.types.QuantityType; @@ -54,13 +47,13 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTripsContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTrip; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTripContainer; -import org.openhab.binding.bmwconnecteddrive.internal.dto.status.CBSMessage; -import org.openhab.binding.bmwconnecteddrive.internal.dto.status.CCMMessage; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Doors; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Position; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Windows; +import org.openhab.binding.bmwconnecteddrive.internal.handler.RemoteServiceHandler.ExecutionState; +import org.openhab.binding.bmwconnecteddrive.internal.handler.RemoteServiceHandler.RemoteService; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -77,47 +70,37 @@ public class ConnectedCarHandler extends ConnectedCarChannelHandler { private final Logger logger = LoggerFactory.getLogger(ConnectedCarHandler.class); - final static Gson GSON = new Gson(); - Token token = new Token(); - @Nullable - String serviceExecutionAPI; - @Nullable - String serviceExecutionStateAPI; + static final Gson GSON = new Gson(); - private String driveTrain; - private HttpClient httpClient; - protected RemoteServiceHandler remoteService; + private Optional proxy = Optional.empty(); + private Optional remote = Optional.empty(); + private Optional configuration = Optional.empty(); private boolean imperial = false; private boolean hasFuel = false; private boolean isElectric = false; private boolean isHybrid = false; - private @Nullable ConnectedCarConfiguration configuration; - private @Nullable ConnectedDriveBridgeHandler bridgeHandler; - protected @Nullable ScheduledFuture refreshJob; + private Position currentPosition = new Position(); - private @Nullable String vehicleFingerprint; - private @Nullable String efficiencyFingerprint; + StringResponseCallback vehicleStatusCallback = new VehicleStatusCallback(); + StringResponseCallback lastTripCallback = new LastTripCallback(); + StringResponseCallback allTripsCallback = new AllTripsCallback(); + StringResponseCallback chargeProfileCallback = new ChargeProfilesCallback(); + StringResponseCallback rangeMapCallback = new RangeMapCallback(); + ByteResponseCallback imageCallback = new ImageCallback(); - // Connected Drive APIs - private @Nullable String vehicleAPI; - private @Nullable String imageAPI; - private @Nullable String lastTripAPI; - private @Nullable String allTripsAPI; - private @Nullable String chargeAPI; - private @Nullable String destinationAPI; - private @Nullable String rangeMapAPI; + private Optional vehicleStatusCache = Optional.empty(); + private Optional lastTripCache = Optional.empty(); + private Optional allTripsCache = Optional.empty(); + private Optional chargeProfileCache = Optional.empty(); + private Optional rangeMapCache = Optional.empty(); - private @Nullable String vehicleStatusCache; - private @Nullable String lastTripCache; - private @Nullable String allTripsCache; + private Optional bridgeHandler = Optional.empty(); + protected Optional> refreshJob = Optional.empty(); public ConnectedCarHandler(Thing thing, HttpClient hc, String type, boolean imperial) { super(thing); - remoteService = new RemoteServiceHandler(this, hc); - httpClient = hc; - driveTrain = type; this.imperial = imperial; hasFuel = type.equals(CarType.CONVENTIONAL.toString()) || type.equals(CarType.PLUGIN_HYBRID.toString()) || type.equals(CarType.ELECTRIC_REX.toString()); @@ -129,63 +112,117 @@ public ConnectedCarHandler(Thing thing, HttpClient hc, String type, boolean impe @Override public void handleCommand(ChannelUID channelUID, Command command) { + String group = channelUID.getGroupId(); + + // Refresh of Channels with cached values if (command instanceof RefreshType) { - String group = channelUID.getGroupId(); if (CHANNEL_GROUP_LAST_TRIP.equals(group)) { - if (lastTripCache != null) { - updateLastTrip(lastTripCache); - } + lastTripCallback.onResponse(lastTripCache); } else if (CHANNEL_GROUP_LIFETIME.equals(group)) { - if (allTripsCache != null) { - updateTripStatistics(allTripsCache); - } - } else if (vehicleStatusCache != null) { - updateRangeValues(vehicleStatusCache); + allTripsCallback.onResponse(allTripsCache); + } else if (CHANNEL_GROUP_LAST_TRIP.equals(group)) { + lastTripCallback.onResponse(lastTripCache); + } else if (CHANNEL_GROUP_LAST_TRIP.equals(group)) { + lastTripCallback.onResponse(lastTripCache); + } else if (CHANNEL_GROUP_STATUS.equals(group)) { + vehicleStatusCallback.onResponse(vehicleStatusCache); + } else if (CHANNEL_GROUP_CHARGE_PROFILE.equals(group)) { + vehicleStatusCallback.onResponse(chargeProfileCache); + } else if (CHANNEL_GROUP_RANGE_MAP.equals(group)) { + vehicleStatusCallback.onResponse(rangeMapCache); } - } - if (CHANNEL_GROUP_REMOTE.equals(channelUID.getGroupId())) { - logger.info("Remote Command {}", CHANNEL_GROUP_REMOTE); - if (command instanceof OnOffType) { - if (command.equals(OnOffType.ON)) { - switch (channelUID.getIdWithoutGroup()) { - case REMOTE_SERVICE_LIGHT_FLASH: - remoteService.execute(RemoteServiceHandler.RemoteService.LIGHT_FLASH); - break; - case REMOTE_SERVICE_AIR_CONDITIONING: - remoteService.execute(RemoteServiceHandler.RemoteService.AIR_CONDITIONING); - break; - case REMOTE_SERVICE_DOOR_LOCK: - remoteService.execute(RemoteServiceHandler.RemoteService.DOOR_LOCK); - break; - case REMOTE_SERVICE_DOOR_UNLOCK: - remoteService.execute(RemoteServiceHandler.RemoteService.DOOR_UNLOCK); - break; - case REMOTE_SERVICE_HORN: - remoteService.execute(RemoteServiceHandler.RemoteService.HORN); - break; - case REMOTE_SERVICE_VEHICLE_FINDER: - remoteService.execute(RemoteServiceHandler.RemoteService.VEHICLE_FINDER); - break; + } else { + // Executing Remote Services + if (CHANNEL_GROUP_REMOTE.equals(channelUID.getGroupId())) { + logger.info("Remote Command {}", CHANNEL_GROUP_REMOTE); + if (command instanceof OnOffType) { + if (command.equals(OnOffType.ON)) { + if (remote.isPresent()) { + switch (channelUID.getIdWithoutGroup()) { + case REMOTE_SERVICE_LIGHT_FLASH: + updateState(remoteLightChannel, + OnOffType.from(remote.get().execute(RemoteService.LIGHT_FLASH))); + break; + case REMOTE_SERVICE_AIR_CONDITIONING: + updateState(remoteClimateChannel, + OnOffType.from(remote.get().execute(RemoteService.AIR_CONDITIONING))); + break; + case REMOTE_SERVICE_DOOR_LOCK: + updateState(remoteLockChannel, + OnOffType.from(remote.get().execute(RemoteService.DOOR_LOCK))); + break; + case REMOTE_SERVICE_DOOR_UNLOCK: + updateState(remoteUnlockChannel, + OnOffType.from(remote.get().execute(RemoteService.DOOR_UNLOCK))); + break; + case REMOTE_SERVICE_HORN: + updateState(remoteHornChannel, + OnOffType.from(remote.get().execute(RemoteService.HORN))); + break; + case REMOTE_SERVICE_VEHICLE_FINDER: + updateState(remoteFinderChannel, + OnOffType.from(remote.get().execute(RemoteService.VEHICLE_FINDER))); + break; + } + } + updateState(carDataFingerprint, OnOffType.OFF); } } } - } - if (channelUID.getIdWithoutGroup().equals(CARDATA_FINGERPRINT)) { - logger.info("Trigger CarData Fingerprint"); - if (command instanceof OnOffType) { - if (command.equals(OnOffType.ON)) { - if (vehicleFingerprint != null) { + + // Log Troubleshoot data + if (channelUID.getIdWithoutGroup().equals(CARDATA_FINGERPRINT)) { + logger.info("Trigger CarData Fingerprint"); + if (command instanceof OnOffType) { + if (command.equals(OnOffType.ON)) { logger.warn("BMW ConnectedDrive Binding - Car Data Troubleshoot fingerprint - BEGIN"); - logger.warn("{}", vehicleFingerprint); - logger.warn("{}", efficiencyFingerprint); + if (vehicleStatusCache.isPresent()) { + logger.warn("### Vehicle Status ###"); + // Anonymous data for VIN and Position + VehicleStatusContainer container = GSON.fromJson(vehicleStatusCache.get(), + VehicleStatusContainer.class); + VehicleStatus status = container.vehicleStatus; + status.vin = ANONYMOUS; + if (status.position != null) { + status.position.lat = -1; + status.position.lon = -1; + status.position.heading = -1; + logger.warn("{}", GSON.toJson(container)); + } + } else { + logger.warn("### Vehicle Status Empty ###"); + } + if (lastTripCache.isPresent()) { + logger.warn("### Last Trip ###"); + logger.warn("{}", lastTripCache.get()); + } else { + logger.warn("### Last Trip Empty ###"); + } + if (allTripsCache.isPresent()) { + logger.warn("### All Trips ###"); + logger.warn("{}", allTripsCache.get()); + } else { + logger.warn("### All Trips Empty ###"); + } + if (isElectric) { + if (chargeProfileCache.isPresent()) { + logger.warn("### Charge Profile ###"); + logger.warn("{}", chargeProfileCache.get()); + } else { + logger.warn("### Charge Profile Empty ###"); + } + } + if (rangeMapCache.isPresent()) { + logger.warn("### Range Map ###"); + logger.warn("{}", rangeMapCache.get()); + } else { + logger.warn("### Range Map Empty ###"); + } logger.warn("BMW ConnectedDrive Binding - Car Data Troubleshoot fingerprint - END"); - } else { - logger.warn( - "BMW ConnectedDrive Binding - No Car Data Troubleshoot fingerprint available. Please check for valid username and password Settings for proper connection towards ConnectDrive"); } + // Switch back to off immediately + updateState(channelUID, OnOffType.OFF); } - // Switch back to off immediately - updateState(channelUID, OnOffType.OFF); } } } @@ -212,335 +249,344 @@ public void handleCommand(ChannelUID channelUID, Command command) { @Override public void initialize() { updateStatus(ThingStatus.UNKNOWN); - ConnectedCarConfiguration config = getConfigAs(ConnectedCarConfiguration.class); - configuration = config; - if (config != null) { + configuration = Optional.of(getConfigAs(ConnectedCarConfiguration.class)); + if (configuration.isPresent()) { scheduler.execute(() -> { Bridge bridge = getBridge(); if (bridge != null) { BridgeHandler handler = bridge.getHandler(); if (handler != null) { - bridgeHandler = ((ConnectedDriveBridgeHandler) handler); - String baseUrl = "https://" + bridgeHandler.getRegionServer() + "/webapi/v1/user/vehicles/" - + config.vin; - vehicleAPI = baseUrl + "/status"; - lastTripAPI = baseUrl + "/statistics/lastTrip"; - allTripsAPI = baseUrl + "/statistics/allTrips"; - chargeAPI = baseUrl + "/chargingprofile"; - destinationAPI = baseUrl + "/destinations"; - imageAPI = baseUrl + "/image"; - - serviceExecutionAPI = baseUrl + "/executeService"; - serviceExecutionStateAPI = baseUrl + "/serviceExecutionStatus?serviceType="; - - // currently delivers response 500 - Internal Server Error - // rangeMapAPI = baseUrl + "/rangemap"; - + bridgeHandler = Optional.of(((ConnectedDriveBridgeHandler) handler)); + proxy = bridgeHandler.get().getProxy(); + if (proxy.isPresent()) { + remote = Optional.of(proxy.get().getRemoteServiceHandler(this)); + } } else { logger.warn("Brdige Handler null"); } } else { logger.warn("Bridge null"); } - getImage(); - startSchedule(config.refreshInterval); + + // Switch all Remote Service Channels Off + switchRemoteServicesOff(); + updateState(carDataFingerprint, OnOffType.OFF); + + // get Car Image one time at the beginning + proxy.get().requestImage(configuration.get(), imageCallback); + + // check imperial setting is different to AutoDetect + if (!UNITS_AUTODETECT.equals(configuration.get().units)) { + imperial = UNITS_IMPERIAL.equals(configuration.get().units); + } + + // start update schedule + startSchedule(configuration.get().refreshInterval); }); } else { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR); } } + private void switchRemoteServicesOff() { + updateState(remoteLightChannel, OnOffType.from(false)); + updateState(remoteFinderChannel, OnOffType.from(false)); + updateState(remoteLockChannel, OnOffType.from(false)); + updateState(remoteUnlockChannel, OnOffType.from(false)); + updateState(remoteHornChannel, OnOffType.from(false)); + updateState(remoteClimateChannel, OnOffType.from(false)); + updateState(remoteStateChannel, OnOffType.from(false)); + } + private void startSchedule(int interval) { - ScheduledFuture localRefreshJob = refreshJob; - if (localRefreshJob != null) { - if (localRefreshJob.isCancelled()) { - refreshJob = scheduler.scheduleWithFixedDelay(this::getData, 0, interval, TimeUnit.MINUTES); + if (refreshJob.isPresent()) { + if (refreshJob.get().isCancelled()) { + Optional.of(scheduler.scheduleWithFixedDelay(this::getData, 0, interval, TimeUnit.MINUTES)); } // else - scheduler is already running! } else { - refreshJob = scheduler.scheduleWithFixedDelay(this::getData, 0, interval, TimeUnit.MINUTES); + Optional.of(scheduler.scheduleWithFixedDelay(this::getData, 0, interval, TimeUnit.MINUTES)); } } @Override public void dispose() { - ScheduledFuture localRefreshJob = refreshJob; - if (localRefreshJob != null) { - localRefreshJob.cancel(true); + if (refreshJob.isPresent()) { + refreshJob.get().cancel(true); } } public void getData() { - if (!tokenUpdate()) { - return; + if (proxy.isPresent() && configuration.isPresent()) { + proxy.get().requestVehcileStatus(configuration.get(), vehicleStatusCallback); + if (isElectric) { + proxy.get().requestLastTrip(configuration.get(), lastTripCallback); + proxy.get().requestAllTrips(configuration.get(), allTripsCallback); + proxy.get().requestChargingProfile(configuration.get(), chargeProfileCallback); + } + } else { + logger.warn("ConnectedDrive Proxy isn't present"); } - String vehicleStatusData = getJSON(vehicleAPI); - updateVehicleStatus(vehicleStatusData); - updateRangeValues(vehicleStatusData); - String lastTripData = getJSON(lastTripAPI); - updateLastTrip(lastTripData); - String allTripData = getJSON(allTripsAPI); - updateTripStatistics(allTripData); - String rangemapData = getJSON(rangeMapAPI); - logger.info("RangeMap {}",rangemapData); - String chargeData = getJSON(chargeAPI); - logger.info("Chatge Data {}",chargeData); - String destinationData = getJSON(destinationAPI); } - public @Nullable String getJSON(@Nullable String url) { - if (url == null) { - return null; - } - Request req = httpClient.newRequest(url); - req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); - req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); - try { - ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); - if (contentResponse.getStatus() != 200) { - logger.info("URL {}", url); - logger.info("Status {}", contentResponse.getStatus()); - logger.info("Reason {}", contentResponse.getReason()); - } else { - updateStatus(ThingStatus.ONLINE); - return contentResponse.getContentAsString(); + void requestRangeMap(Position p) { + // format_string = '%Y-%m-%dT%H:%M:%S' + // timestamp = datetime.datetime.now().strftime(format_string) + // params = { + // 'deviceTime': timestamp, + // 'dlat': self._vehicle.observer_latitude, + // 'dlon': self._vehicle.observer_longitude, + // } + double diff = Converter.measure(p.lat, p.lon, currentPosition.lat, currentPosition.lon); + if (diff > 1000) { + logger.info("Difference between old {} and new Position {} = {}", currentPosition.toString(), p.toString(), + diff); + LocalDateTime ldt = LocalDateTime.now(); + MultiMap dataMap = new MultiMap(); + dataMap.add("deviceTime", ldt.format(Converter.DATE_INPUT_PATTERN)); + dataMap.add("dlat", Float.toString(p.lat)); + dataMap.add("dlon", Float.toString(p.lon)); + if (configuration.isPresent()) { + proxy.get().requestRangeMap(configuration.get(), dataMap, rangeMapCallback); } - } catch (InterruptedException | TimeoutException | ExecutionException e) { - logger.warn("Get Data Exception {}", e.getMessage()); } - return null; + currentPosition = p; } - private void updateTripStatistics(@Nullable String content) { - if (content == null) { - logger.warn("No Vehicle Values available"); - return; + public void updateRemoteExecutionStatus(String service, String status) { + updateState(remoteStateChannel, StringType + .valueOf(Converter.toTitleCase(new StringBuffer(service).append(" ").append(status).toString()))); + if (ExecutionState.EXECUTED.toString().equals(status)) { + switchRemoteServicesOff(); } - allTripsCache = content; - AllTripsContainer at = GSON.fromJson(content, AllTripsContainer.class); - AllTrips c = at.allTrips; - updateState(lifeTimeCumulatedDrivenDistance, QuantityType - .valueOf(Converter.round(c.totalElectricDistance.userTotal), MetricPrefix.KILO(SIUnits.METRE))); - updateState(lifeTimeSingleLongestDistance, - QuantityType.valueOf(Converter.round(c.chargecycleRange.userHigh), MetricPrefix.KILO(SIUnits.METRE))); - updateState(lifeTimeAverageConsumption, QuantityType - .valueOf(Converter.round(c.avgElectricConsumption.userAverage), SmartHomeUnits.KILOWATT_HOUR)); - updateState(lifeTimeAverageRecuperation, - QuantityType.valueOf(Converter.round(c.avgRecuperation.userAverage), SmartHomeUnits.KILOWATT_HOUR)); - updateState(tripDistanceSinceCharging, QuantityType - .valueOf(Converter.round(c.chargecycleRange.userCurrentChargeCycle), MetricPrefix.KILO(SIUnits.METRE))); } - private void updateLastTrip(@Nullable String content) { - if (content == null) { - logger.warn("No Vehicle Values available"); - return; - } - lastTripCache = content; - LastTripContainer lt = GSON.fromJson(content, LastTripContainer.class); - LastTrip trip = lt.lastTrip; - updateState(tripDistance, - QuantityType.valueOf(Converter.round(trip.totalDistance), MetricPrefix.KILO(SIUnits.METRE))); - // updateState(tripDistanceSinceCharging, - // QuantityType.valueOf(entry.lastTrip, MetricPrefix.KILO(SIUnits.METRE))); - updateState(tripAvgConsumption, - QuantityType.valueOf(Converter.round(trip.avgElectricConsumption), SmartHomeUnits.KILOWATT_HOUR)); - updateState(tripAvgRecuperation, - QuantityType.valueOf(Converter.round(trip.avgRecuperation), SmartHomeUnits.KILOWATT_HOUR)); + public Optional getConfiguration() { + return configuration; + } + + public ScheduledExecutorService getScheduler() { + return scheduler; } - void updateVehicleStatus(@Nullable String content) { - if (content == null) { - logger.warn("No Vehicle Values available"); - return; + /** + * Callbacks for ConnectedDrive Portal + * + * @author bernd + * + */ + + @NonNullByDefault + public class ChargeProfilesCallback implements StringResponseCallback { + @Override + public void onResponse(Optional content) { + chargeProfileCache = content; } - logger.info("Vehicle Status {}", content); - vehicleStatusCache = content; - VehicleStatusContainer status = GSON.fromJson(content, VehicleStatusContainer.class); - VehicleStatus vStatus = status.vehicleStatus; - - updateState(lock, StringType.valueOf(Converter.toTitleCase(vStatus.doorLockState))); - Doors doorState = GSON.fromJson(GSON.toJson(vStatus), Doors.class); - updateState(doors, StringType.valueOf(checkClosed(doorState))); - Windows windowState = GSON.fromJson(GSON.toJson(vStatus), Windows.class); - updateState(windows, StringType.valueOf(checkClosed(windowState))); - updateState(checkControl, StringType.valueOf(getCheckControl(vStatus.checkControlMessages))); - updateState(service, StringType.valueOf(getNextService(vStatus.cbsData))); - if (isElectric) { - updateState(chargingStatus, StringType.valueOf(Converter.toTitleCase(vStatus.chargingStatus))); + + @Override + public void onError(String reason) { + logger.debug("Unable to retrieve Charging Profile: {}", reason); } } - private @Nullable String getNextService(List cbsData) { - if (cbsData.isEmpty()) { - return "No Service Requests"; - } else { - LocalDate serviceDate = null; - String service = null; - for (int i = 0; i < cbsData.size(); i++) { - CBSMessage entry = cbsData.get(i); - LocalDate d = LocalDate.parse(entry.cbsDueDate + "-01", Converter.serviceDateInputPattern); - if (serviceDate == null) { - serviceDate = d; - service = entry.cbsType; - } else { - if (d.isBefore(serviceDate)) { - serviceDate = d; - } - } - } - if (serviceDate != null) { - return serviceDate.format(Converter.serviceDateOutputPattern) + " - " + Converter.toTitleCase(service); - } else { - return "Unknown"; - } + @NonNullByDefault + public class RangeMapCallback implements StringResponseCallback { + @Override + public void onResponse(Optional content) { + rangeMapCache = content; } - } - private @Nullable String getCheckControl(List checkControlMessages) { - if (checkControlMessages.isEmpty()) { - return "Ok"; - } else { - return Converter.toTitleCase(checkControlMessages.get(0).ccmDescriptionShort); + @Override + public void onError(String reason) { + logger.debug("Unable to retrieve RangeMap: {}", reason); } } - String checkClosed(Object dto) { - for (Field field : dto.getClass().getDeclaredFields()) { - try { - if (field.get(dto).equals("OPEN")) { - // report the first door which is still open - return Converter.toTitleCase(field.getName() + " Open"); - } - } catch (IllegalArgumentException | IllegalAccessException e) { - logger.warn("Fields for {} Object not accesible", dto); - return "Unknown"; + @NonNullByDefault + public class ImageCallback implements ByteResponseCallback { + @Override + public void onResponse(Optional content) { + if (content.isPresent()) { + // byte[] image = content.get().getBytes(); + logger.info("Content {} {} {} {}", content.get()[0], content.get()[1], content.get()[2], + content.get()[3]); + String contentType = HttpUtil.guessContentTypeFromData(content.get()); + logger.info("Image Content Type {} Size {}", contentType, content.get().length); + updateState(imageChannel, new RawType(content.get(), contentType)); } } - return "Closed"; - } - void updateRangeValues(@Nullable String content) { - if (content == null) { - logger.warn("No Vehicle Values available"); - return; + @Override + public void onError(String reason) { + logger.debug("Unable to retrieve Image: {}", reason); } - VehicleStatusContainer status = GSON.fromJson(content, VehicleStatusContainer.class); - VehicleStatus vStatus = status.vehicleStatus; - // based on unit of length decide if range shall be reported in km or miles - if (!imperial) { - updateState(mileage, QuantityType.valueOf(vStatus.mileage, MetricPrefix.KILO(SIUnits.METRE))); - float totalRange = 0; - if (isElectric) { - totalRange += vStatus.remainingRangeElectric; - updateState(remainingRangeElectric, - QuantityType.valueOf(vStatus.remainingRangeElectric, MetricPrefix.KILO(SIUnits.METRE))); - logger.info("updated {} {}", remainingRangeElectric, vStatus.remainingRangeElectric); - } else { - logger.info("{} not updated", remainingRangeElectric); - } - if (hasFuel) { - totalRange += vStatus.remainingRangeFuel; - updateState(remainingRangeFuel, - QuantityType.valueOf(vStatus.remainingRangeFuel, MetricPrefix.KILO(SIUnits.METRE))); - logger.info("updated {} {}", remainingRangeFuel, vStatus.remainingRangeFuel); - } else { - logger.info("{} not updated", remainingRangeFuel); - } - if (isHybrid) { - updateState(remainingRangeHybrid, - QuantityType.valueOf(Converter.round(totalRange), MetricPrefix.KILO(SIUnits.METRE))); - } - updateState(rangeRadius, new DecimalType((totalRange) * 1000)); - } else { - updateState(mileage, QuantityType.valueOf(vStatus.mileage, ImperialUnits.MILE)); - float totalRange = 0; - if (isElectric) { - totalRange += vStatus.remainingRangeElectricMls; - updateState(remainingRangeElectric, - QuantityType.valueOf(vStatus.remainingRangeElectricMls, ImperialUnits.MILE)); - } - if (hasFuel) { - totalRange = vStatus.remainingRangeFuelMls; - updateState(remainingRangeFuel, - QuantityType.valueOf(vStatus.remainingRangeFuelMls, ImperialUnits.MILE)); - } - if (isHybrid) { - updateState(remainingRangeHybrid, - QuantityType.valueOf(Converter.round(totalRange), ImperialUnits.MILE)); + } + + @NonNullByDefault + public class AllTripsCallback implements StringResponseCallback { + @Override + public void onResponse(Optional content) { + if (content.isPresent()) { + allTripsCache = content; + AllTripsContainer at = GSON.fromJson(content.get(), AllTripsContainer.class); + AllTrips c = at.allTrips; + if (c == null) { + return; + } + updateState(lifeTimeCumulatedDrivenDistance, QuantityType + .valueOf(Converter.round(c.totalElectricDistance.userTotal), MetricPrefix.KILO(SIUnits.METRE))); + updateState(lifeTimeSingleLongestDistance, QuantityType + .valueOf(Converter.round(c.chargecycleRange.userHigh), MetricPrefix.KILO(SIUnits.METRE))); + updateState(lifeTimeAverageConsumption, QuantityType + .valueOf(Converter.round(c.avgElectricConsumption.userAverage), SmartHomeUnits.KILOWATT_HOUR)); + updateState(lifeTimeAverageRecuperation, QuantityType + .valueOf(Converter.round(c.avgRecuperation.userAverage), SmartHomeUnits.KILOWATT_HOUR)); + updateState(tripDistanceSinceCharging, QuantityType.valueOf( + Converter.round(c.chargecycleRange.userCurrentChargeCycle), MetricPrefix.KILO(SIUnits.METRE))); } - updateState(rangeRadius, new DecimalType((totalRange) * 5280)); // Miles to feet - } - if (isElectric) { - updateState(remainingSoc, QuantityType.valueOf(vStatus.chargingLevelHv, SmartHomeUnits.PERCENT)); - } - if (hasFuel) { - updateState(remainingFuel, - QuantityType.valueOf(vStatus.remainingFuel * 100 / vStatus.maxFuel, SmartHomeUnits.PERCENT)); - logger.info("updated {} {}", remainingFuel, vStatus.remainingFuel * 100 / vStatus.maxFuel); - } else { - logger.info("{} not updated", remainingRangeFuel); } - updateState(lastUpdate, new StringType(Converter.getLocalDateTime(vStatus.internalDataTimeUTC))); - - Position p = vStatus.position; - updateState(latitude, new DecimalType(p.lat)); - updateState(longitude, new DecimalType(p.lon)); - updateState(latlong, new StringType(p.lat + "," + p.lon)); - updateState(heading, QuantityType.valueOf(p.heading, SmartHomeUnits.DEGREE_ANGLE)); + @Override + public void onError(String reason) { + logger.debug("Unable to retrieve All Trips: {}", reason); + } - vehicleFingerprint = GSON.toJson(vStatus); } - public void getImage() { - if (!tokenUpdate()) { - logger.warn("Car image Authorization failed"); - return; + @NonNullByDefault + public class LastTripCallback implements StringResponseCallback { + @Override + public void onResponse(Optional content) { + if (content.isPresent()) { + lastTripCache = content; + LastTripContainer lt = GSON.fromJson(content.get(), LastTripContainer.class); + LastTrip trip = lt.lastTrip; + if (trip == null) { + return; + } + updateState(tripDistance, + QuantityType.valueOf(Converter.round(trip.totalDistance), MetricPrefix.KILO(SIUnits.METRE))); + // updateState(tripDistanceSinceCharging, + // QuantityType.valueOf(entry.lastTrip, MetricPrefix.KILO(SIUnits.METRE))); + updateState(tripAvgConsumption, QuantityType.valueOf(Converter.round(trip.avgElectricConsumption), + SmartHomeUnits.KILOWATT_HOUR)); + updateState(tripAvgRecuperation, + QuantityType.valueOf(Converter.round(trip.avgRecuperation), SmartHomeUnits.KILOWATT_HOUR)); + } } - ConnectedCarConfiguration localConfig = configuration; - if (localConfig == null) { - logger.warn("Car image cannot be retrieved without config data"); - return; + + @Override + public void onError(String reason) { + logger.debug("Unable to retrieve Last Trip: {}", reason); } + } - String localImageUrl = imageAPI + "?width=" + localConfig.imageSize + "&height=" + localConfig.imageSize - + "&view=" + localConfig.imageViewport; - Request req = httpClient.newRequest(localImageUrl); - req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); - req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); - try { - ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); - if (contentResponse.getStatus() != 200) { - logger.info("URL {}", localImageUrl); - logger.info("Status {}", contentResponse.getStatus()); - logger.info("Reason {}", contentResponse.getReason()); - } else { - byte[] image = contentResponse.getContent(); - String contentType = HttpUtil.guessContentTypeFromData(image); - logger.info("Image Content Type {} Size {}", contentType, image.length); - updateState(imageChannel, new RawType(image, contentType)); + /** + * The VehicleStatus is supported by all Car Types so it's used to reflect the Thing Status + */ + @NonNullByDefault + public class VehicleStatusCallback implements StringResponseCallback { + private ThingStatus thingStatus = ThingStatus.UNKNOWN; + + private void setThingStatus(ThingStatus status, ThingStatusDetail detail, String reason) { + if (thingStatus != status) { + // STatus is supported by all cars so callback is used to report ONLINE state + updateStatus(status, detail, reason); } - } catch (InterruptedException | TimeoutException | ExecutionException e) { - logger.warn("Get Data Exception {}", e.getMessage()); } - } - public synchronized boolean tokenUpdate() { - if (token.isExpired() || !token.isValid()) { - token = bridgeHandler.getToken(); - if (token.isExpired() || !token.isValid()) { - logger.info("Token update failed!"); - return false; + @Override + public void onResponse(Optional content) { + if (content.isPresent()) { + vehicleStatusCache = content; + logger.info("Content: {}", content.get()); + VehicleStatusContainer status = GSON.fromJson(content.get(), VehicleStatusContainer.class); + VehicleStatus vStatus = status.vehicleStatus; + if (vStatus == null) { + return; + } + updateState(lock, StringType.valueOf(Converter.toTitleCase(vStatus.doorLockState))); + Doors doorState = GSON.fromJson(GSON.toJson(vStatus), Doors.class); + updateState(doors, StringType.valueOf(VehicleStatus.checkClosed(doorState))); + Windows windowState = GSON.fromJson(GSON.toJson(vStatus), Windows.class); + updateState(windows, StringType.valueOf(VehicleStatus.checkClosed(windowState))); + updateState(checkControl, StringType.valueOf(vStatus.getCheckControl())); + updateState(service, StringType.valueOf(vStatus.getNextService(imperial))); + if (isElectric) { + updateState(chargingStatus, StringType.valueOf(Converter.toTitleCase(vStatus.chargingStatus))); + } + + // Range values + // based on unit of length decide if range shall be reported in km or miles + if (!imperial) { + updateState(mileage, QuantityType.valueOf(vStatus.mileage, MetricPrefix.KILO(SIUnits.METRE))); + float totalRange = 0; + if (isElectric) { + totalRange += vStatus.remainingRangeElectric; + updateState(remainingRangeElectric, + QuantityType.valueOf(vStatus.remainingRangeElectric, MetricPrefix.KILO(SIUnits.METRE))); + logger.info("updated {} {}", remainingRangeElectric, vStatus.remainingRangeElectric); + } else { + logger.info("{} not updated", remainingRangeElectric); + } + if (hasFuel) { + totalRange += vStatus.remainingRangeFuel; + updateState(remainingRangeFuel, + QuantityType.valueOf(vStatus.remainingRangeFuel, MetricPrefix.KILO(SIUnits.METRE))); + logger.info("updated {} {}", remainingRangeFuel, vStatus.remainingRangeFuel); + } else { + logger.info("{} not updated", remainingRangeFuel); + } + if (isHybrid) { + updateState(remainingRangeHybrid, + QuantityType.valueOf(Converter.round(totalRange), MetricPrefix.KILO(SIUnits.METRE))); + } + updateState(rangeRadius, new DecimalType((totalRange) * 1000)); + } else { + updateState(mileage, QuantityType.valueOf(vStatus.mileage, ImperialUnits.MILE)); + float totalRange = 0; + if (isElectric) { + totalRange += vStatus.remainingRangeElectricMls; + updateState(remainingRangeElectric, + QuantityType.valueOf(vStatus.remainingRangeElectricMls, ImperialUnits.MILE)); + } + if (hasFuel) { + totalRange += vStatus.remainingRangeFuelMls; + updateState(remainingRangeFuel, + QuantityType.valueOf(vStatus.remainingRangeFuelMls, ImperialUnits.MILE)); + } + if (isHybrid) { + updateState(remainingRangeHybrid, + QuantityType.valueOf(Converter.round(totalRange), ImperialUnits.MILE)); + } + updateState(rangeRadius, new DecimalType((totalRange) * Converter.MILES_TO_FEET_FACTOR)); + } + if (isElectric) { + updateState(remainingSoc, QuantityType.valueOf(vStatus.chargingLevelHv, SmartHomeUnits.PERCENT)); + } + if (hasFuel) { + updateState(remainingFuel, QuantityType.valueOf(vStatus.remainingFuel, SmartHomeUnits.LITRE)); + } + // last update Time + if (vStatus.internalDataTimeUTC != null) { + updateState(lastUpdate, new StringType(Converter.getLocalDateTime(vStatus.internalDataTimeUTC))); + } else { + updateState(lastUpdate, new StringType(Converter.getZonedDateTime(vStatus.updateTime))); + } + + Position p = vStatus.position; + updateState(latitude, new DecimalType(p.lat)); + updateState(longitude, new DecimalType(p.lon)); + updateState(latlong, StringType.valueOf(p.toString())); + updateState(heading, QuantityType.valueOf(p.heading, SmartHomeUnits.DEGREE_ANGLE)); + requestRangeMap(p); } } - return true; - } - public ScheduledExecutorService getScheduler() { - return scheduler; - } + @Override + public void onError(String reason) { + logger.debug("Unable to retrieve Vehicle Status {}", reason); + setThingStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, reason); + } - public void updateRemoteExecutionStatus(String status) { - updateState(remoteStateChannel, StringType.valueOf(status)); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java index a8910ccb924c6..efc282b433963 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java @@ -13,27 +13,13 @@ package org.openhab.binding.bmwconnecteddrive.internal.handler; import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; -import static org.openhab.binding.bmwconnecteddrive.internal.handler.HTTPConstants.*; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; import java.util.Hashtable; -import java.util.concurrent.ExecutionException; +import java.util.Optional; import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; 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.client.util.StringContentProvider; -import org.eclipse.jetty.http.HttpField; -import org.eclipse.jetty.http.HttpFields; -import org.eclipse.jetty.http.HttpHeader; -import org.eclipse.jetty.util.MultiMap; -import org.eclipse.jetty.util.UrlEncoded; import org.eclipse.smarthome.config.discovery.DiscoveryService; import org.eclipse.smarthome.core.library.types.OnOffType; import org.eclipse.smarthome.core.thing.Bridge; @@ -45,6 +31,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConfiguration; import org.openhab.binding.bmwconnecteddrive.internal.discovery.ConnectedCarDiscovery; import org.openhab.binding.bmwconnecteddrive.internal.dto.ConnectedDriveUserInfo; +import org.openhab.binding.bmwconnecteddrive.internal.dto.Dealer; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.slf4j.Logger; @@ -59,18 +46,20 @@ * @author Bernd Weymann - Initial contribution */ @NonNullByDefault -public class ConnectedDriveBridgeHandler extends BaseBridgeHandler { +public class ConnectedDriveBridgeHandler extends BaseBridgeHandler implements StringResponseCallback { private final Logger logger = LoggerFactory.getLogger(ConnectedDriveBridgeHandler.class); private static final Gson GSON = new Gson(); private HttpClient httpClient; - private Token token = new Token(); private BundleContext bundleContext; private ServiceRegistration discoveryServiceRegstration; private ConnectedCarDiscovery discoveryService; - private @Nullable ConnectedDriveConfiguration configuration; - private @Nullable ScheduledFuture refreshJob; - private @Nullable String troubleshootFingerprint; - private @Nullable String authUri; + private Optional proxy = Optional.empty(); + private Optional configuration = Optional.empty(); + private Optional> refreshJob = Optional.empty(); + private Optional troubleshootFingerprint = Optional.empty(); + + private ChannelUID discoveryTrigger; + private ChannelUID discoveryfingerPrint; public ConnectedDriveBridgeHandler(Bridge bridge, HttpClient hc, BundleContext bc) { super(bridge); @@ -79,6 +68,8 @@ public ConnectedDriveBridgeHandler(Bridge bridge, HttpClient hc, BundleContext b discoveryService = new ConnectedCarDiscovery(this); discoveryServiceRegstration = bundleContext.registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<>()); + discoveryTrigger = new ChannelUID(thing.getUID(), DISCOVERY_TRIGGER); + discoveryfingerPrint = new ChannelUID(thing.getUID(), DISCOVERY_FINGERPRINT); } @Override @@ -86,9 +77,9 @@ public void handleCommand(ChannelUID channelUID, Command command) { if (channelUID.getIdWithoutGroup().equals(DISCOVERY_FINGERPRINT)) { if (command instanceof OnOffType) { if (command.equals(OnOffType.ON)) { - if (troubleshootFingerprint != null) { + if (troubleshootFingerprint.isPresent()) { logger.warn("BMW ConnectedDrive Binding - Discovery Troubleshoot fingerprint - BEGIN"); - logger.warn("{}", troubleshootFingerprint); + logger.warn("{}", troubleshootFingerprint.get()); logger.warn("BMW ConnectedDrive Binding - Discovery Troubleshoot fingerprint - END"); } else { logger.warn( @@ -96,18 +87,19 @@ public void handleCommand(ChannelUID channelUID, Command command) { } } // Switch back to off immediately - updateState(channelUID, OnOffType.OFF); + updateState(discoveryfingerPrint, OnOffType.OFF); } } else if (channelUID.getIdWithoutGroup().equals(DISCOVERY_TRIGGER)) { if (command instanceof OnOffType) { if (command.equals(OnOffType.ON)) { // trigger discovery again - helpful after the user performed some changes in the ConnectedDrive - // Portal and - // wants to refresh the changes - scheduler.schedule(this::getPortalData, 0, TimeUnit.SECONDS); + // Portal and wants to get the changes + if (proxy.isPresent()) { + proxy.get().requestVehicles(this); + } } // Switch back to off immediately - updateState(channelUID, OnOffType.OFF); + updateState(discoveryTrigger, OnOffType.OFF); } } } @@ -115,139 +107,67 @@ public void handleCommand(ChannelUID channelUID, Command command) { @Override public void initialize() { updateStatus(ThingStatus.UNKNOWN); - configuration = getConfigAs(ConnectedDriveConfiguration.class); - if (configuration != null) { - // generate URI for Authorization - // https://customer.bmwgroup.com/one/app/oauth.js - StringBuffer uri = new StringBuffer(); - uri.append("https://customer.bmwgroup.com"); - if (BimmerConstants.SERVER_NORTH_AMERICA.equals(configuration.region)) { - uri.append("/gcdm/usa/oauth/authenticate"); - } else { - uri.append("/gcdm/oauth/authenticate"); + configuration = Optional.of(getConfigAs(ConnectedDriveConfiguration.class)); + if (configuration.isPresent()) { + proxy = Optional.of(new ConnectedDriveProxy(httpClient, configuration.get())); + if (proxy.isPresent()) { + proxy.get().requestVehicles(this); } - authUri = uri.toString(); - - scheduler.schedule(this::getPortalData, 0, TimeUnit.SECONDS); } else { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR); } + updateState(discoveryTrigger, OnOffType.OFF); + updateState(discoveryfingerPrint, OnOffType.OFF); } @Override public void dispose() { - ScheduledFuture localRefreshJob = refreshJob; - if (localRefreshJob != null) { - localRefreshJob.cancel(true); + if (refreshJob.isPresent()) { + refreshJob.get().cancel(true); } } - public void getPortalData() { - getToken(); - String webAPIUrl = "https://" + BimmerConstants.SERVER_MAP.get(configuration.region) - + "/webapi/v1/user/vehicles/"; - logger.info("Request {}", webAPIUrl); - Request req = httpClient.newRequest(webAPIUrl); - req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); - req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); - try { - ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); - logger.info("Status {}", contentResponse.getStatus()); - logger.info("Reason {}", contentResponse.getReason()); - logger.info("Info {}", contentResponse.getContentAsString()); - - ConnectedDriveUserInfo userInfo = GSON.fromJson(contentResponse.getContentAsString(), - ConnectedDriveUserInfo.class); + /** + * There's only the Vehicles response available + */ + @Override + public void onResponse(Optional response) { + if (response.isPresent()) { + ConnectedDriveUserInfo userInfo = GSON.fromJson(response.get(), ConnectedDriveUserInfo.class); discoveryService.scan(userInfo); updateStatus(ThingStatus.ONLINE); if (userInfo.getVehicles() != null) { if (userInfo.getVehicles().isEmpty()) { - troubleshootFingerprint = "No Cars found in your ConnectedDrive Account"; + troubleshootFingerprint = Optional.of("No Cars found in your ConnectedDrive Account"); } else { userInfo.getVehicles().forEach(entry -> { - entry.vin = "xxx"; + entry.vin = ANONYMOUS; + entry.breakdownNumber = ANONYMOUS; + if (entry.dealer != null) { + Dealer d = entry.dealer; + d.city = ANONYMOUS; + d.country = ANONYMOUS; + d.name = ANONYMOUS; + d.phone = ANONYMOUS; + d.postalCode = ANONYMOUS; + d.street = ANONYMOUS; + } }); - troubleshootFingerprint = GSON.toJson(userInfo); + troubleshootFingerprint = Optional.of(GSON.toJson(userInfo)); } } - } catch (InterruptedException | TimeoutException | ExecutionException e) { - logger.warn("Get Data Exception {}", e.getMessage()); - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, - "Error during BMW ConnectedDrive Authorization " + e.getMessage()); - } - } - - public String getRegionServer() { - return BimmerConstants.SERVER_MAP.get(configuration.region); - } - - public Token getToken() { - if (token.isExpired() || !token.isValid()) { - token = getNewToken(); + } else { + logger.info("No Vehciles found"); } - return token; } - /** - * Authorize at BMW Connected Drive Portal and re - * - * @return - */ - public Token getNewToken() { - httpClient.setFollowRedirects(false); - Request req = httpClient.POST(authUri); - - req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); - req.header(HttpHeader.CONNECTION, KEEP_ALIVE); - req.header(HttpHeader.HOST, BimmerConstants.SERVER_MAP.get(configuration.region)); - req.header(HttpHeader.AUTHORIZATION, BimmerConstants.AUTHORIZATION_VALUE); - req.header(CREDENTIALS, BimmerConstants.CREDENTIAL_VALUES); - - MultiMap dataMap = new MultiMap(); - dataMap.add(CLIENT_ID, BimmerConstants.CLIENT_ID_VALUE); - dataMap.add(RESPONSE_TYPE, TOKEN); - dataMap.add(REDIRECT_URI, BimmerConstants.REDIRECT_URI_VALUE); - dataMap.add(SCOPE, BimmerConstants.SCOPE_VALUES); - dataMap.add(USERNAME, configuration.userName); - dataMap.add(PASSWORD, configuration.password); - String urlEncodedData = UrlEncoded.encode(dataMap, Charset.defaultCharset(), false); - - // logger.info("URL encoded data {}", urlEncodedData); - // logger.info("Data size {} ", urlEncodedData.length()); - req.header("Content-Length", urlEncodedData.length() + ""); - req.content(new StringContentProvider(urlEncodedData)); - try { - ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); - logger.info("Status {} ", contentResponse.getStatus()); - // logger.info("Reason {} ", contentResponse.getReason()); - // logger.info("Encoding {} ", contentResponse.getEncoding()); - // logger.info("Content length {} ", contentResponse.getContent().length); - // logger.info("Media Type {} ", contentResponse.getMediaType()); - HttpFields fields = contentResponse.getHeaders(); - HttpField field = fields.getField(HttpHeader.LOCATION); - return getTokenFromUrl(field.getValue()); - } catch (InterruptedException | ExecutionException | TimeoutException e) { - logger.warn("Auth Exception: {}", e.getMessage()); - } - return new Token(); + @Override + public void onError(String reason) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, reason); } - public Token getTokenFromUrl(String encodedUrl) { - MultiMap tokenMap = new MultiMap(); - UrlEncoded.decodeTo(encodedUrl, tokenMap, StandardCharsets.US_ASCII); - final Token token = new Token(); - tokenMap.forEach((key, value) -> { - logger.info("Key {} Value {}", key, value); - if (key.endsWith(ACCESS_TOKEN)) { - token.setToken(value.get(0).toString()); - } else if (key.equals(EXPIRES_IN)) { - logger.info("Expires {}", value.get(0).toString()); - token.setExpiration(Integer.parseInt(value.get(0).toString())); - } else if (key.equals(TOKEN_TYPE)) { - token.setType(value.get(0).toString()); - } - }); - return token; + public Optional getProxy() { + return proxy; } public void close() { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java new file mode 100644 index 0000000000000..7bfcaac0bbe5e --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -0,0 +1,259 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import static org.openhab.binding.bmwconnecteddrive.internal.utils.HTTPConstants.*; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.client.util.BufferingResponseListener; +import org.eclipse.jetty.client.util.StringContentProvider; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.util.MultiMap; +import org.eclipse.jetty.util.UrlEncoded; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedCarConfiguration; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConfiguration; +import org.openhab.binding.bmwconnecteddrive.internal.utils.BimmerConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link ConnectedDriveProxy} This class holds the important constants for the BMW Connected Drive Authorization. + * They + * are taken from the Bimmercode from github {@link https://github.com/bimmerconnected/bimmer_connected} + * File defining these constants + * {@link https://github.com/bimmerconnected/bimmer_connected/blob/master/bimmer_connected/account.py} + * https://customer.bmwgroup.com/one/app/oauth.js + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class ConnectedDriveProxy { + private final Logger logger = LoggerFactory.getLogger(ConnectedDriveProxy.class); + private static final int TIMEOUT_SEC = 10; + private HttpClient http; + private String authUri; + private ConnectedDriveConfiguration configuration; + private Token token = new Token(); + + // Connected Drive APIs + // Base URL without VIN + String baseUrl; + // APIs to be attached after VIN insertion + String vehicleStatusAPI = "/status"; + String lastTripAPI = "/statistics/lastTrip"; + String allTripsAPI = "/statistics/allTrips"; + String chargeAPI = "/chargingprofile"; + String destinationAPI = "/destinations"; + String imageAPI = "/image"; + String rangeMapAPI = "/rangemap"; + + String serviceExecutionAPI = "/executeService"; + String serviceExecutionStateAPI = "/serviceExecutionStatus?serviceType="; + + public ConnectedDriveProxy(HttpClient hc, ConnectedDriveConfiguration config) { + http = hc; + configuration = config; + // generate URI for Authorization + // https://customer.bmwgroup.com/one/app/oauth.js + StringBuffer uri = new StringBuffer(); + uri.append("https://customer.bmwgroup.com"); + if (BimmerConstants.SERVER_NORTH_AMERICA.equals(configuration.region)) { + uri.append("/gcdm/usa/oauth/authenticate"); + } else { + uri.append("/gcdm/oauth/authenticate"); + } + authUri = uri.toString(); + baseUrl = "https://" + getRegionServer() + "/webapi/v1/user/vehicles/"; + } + + public void request(String url, Optional> params, ResponseCallback callback) { + if (tokenUpdate()) { + final StringBuffer completeUrl = new StringBuffer(url); + if (params.isPresent()) { + String urlEncodedData = UrlEncoded.encode(params.get(), Charset.defaultCharset(), false); + completeUrl.append("?").append(urlEncodedData); + // req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); + // req.header(CONTENT_LENGTH, Integer.toString(urlEncodedData.length())); + // req.content(new StringContentProvider(urlEncodedData)); + // logger.info("URL has parameters {}", urlEncodedData); + // logger.info("Complete URL {}", completeUrl.toString()); + } + Request req = http.newRequest(completeUrl.toString()); + req.header(HttpHeader.CONNECTION, KEEP_ALIVE); + req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); + req.timeout(TIMEOUT_SEC, TimeUnit.SECONDS).send(new BufferingResponseListener() { + @NonNullByDefault({}) + @Override + public void onComplete(org.eclipse.jetty.client.api.Result result) { + if (result.getResponse().getStatus() != 200) { + logger.warn("Call URL {}", url.toString()); + logger.warn("Return Status {}", result.getResponse().getStatus()); + logger.warn("Reason {}", result.getResponse().getReason()); + callback.onError(result.getResponse().getReason()); + } else { + logger.warn("Call URL {} success", url.toString()); + if (callback instanceof StringResponseCallback) { + ((StringResponseCallback) callback).onResponse(Optional.of(getContentAsString())); + } else { + ((ByteResponseCallback) callback).onResponse(Optional.of(getContent())); + } + } + } + }); + } + } + + public void requestVehicles(StringResponseCallback callback) { + request(baseUrl, Optional.empty(), callback); + } + + public void requestVehcileStatus(ConnectedCarConfiguration config, StringResponseCallback callback) { + request(new StringBuffer(baseUrl).append(config.vin).append(vehicleStatusAPI).toString(), Optional.empty(), + callback); + } + + public void requestLastTrip(ConnectedCarConfiguration config, StringResponseCallback callback) { + request(new StringBuffer(baseUrl).append(config.vin).append(lastTripAPI).toString(), Optional.empty(), + callback); + } + + public void requestAllTrips(ConnectedCarConfiguration config, StringResponseCallback callback) { + request(new StringBuffer(baseUrl).append(config.vin).append(allTripsAPI).toString(), Optional.empty(), + callback); + } + + public void requestChargingProfile(ConnectedCarConfiguration config, StringResponseCallback callback) { + request(new StringBuffer(baseUrl).append(config.vin).append(chargeAPI).toString(), Optional.empty(), callback); + } + + public void requestDestinations(ConnectedCarConfiguration config, StringResponseCallback callback) { + request(new StringBuffer(baseUrl).append(config.vin).append(destinationAPI).toString(), Optional.empty(), + callback); + } + + public void requestRangeMap(ConnectedCarConfiguration config, MultiMap params, + StringResponseCallback callback) { + request(new StringBuffer(baseUrl).append(config.vin).append(rangeMapAPI).toString(), Optional.of(params), + callback); + } + + public void requestImage(ConnectedCarConfiguration config, ByteResponseCallback callback) { + // String localImageUrl = baseUrl + config.vin + imageAPI + "?width=" + config.imageSize + "&height=" + // + config.imageSize + "&view=" + config.imageViewport; + + // https://b2vapi.bmwgroup.com/webapi/v1/user/vehicles/WBY1Z81040V905639/image view=SIDE&width=2048&height=2048 + // https://b2vapi.bmwgroup.com/webapi/v1/user/vehicles/WBY1Z81040V905639/image?view=SIDE&width=2048&height=2048 + + String localImageUrl = new StringBuffer(baseUrl).append(config.vin).append(imageAPI).toString(); + MultiMap dataMap = new MultiMap(); + dataMap.add("width", Integer.toString(config.imageSize)); + dataMap.add("height", Integer.toString(config.imageSize)); + dataMap.add("view", config.imageViewport); + request(localImageUrl, Optional.of(dataMap), callback); + } + + private String getRegionServer() { + return BimmerConstants.SERVER_MAP.get(configuration.region); + } + + RemoteServiceHandler getRemoteServiceHandler(ConnectedCarHandler carHandler) { + return new RemoteServiceHandler(carHandler, this, http); + } + + // Token handling + + public synchronized boolean tokenUpdate() { + if (token.isExpired() || !token.isValid()) { + token = getToken(); + if (token.isExpired() || !token.isValid()) { + logger.info("Token update failed!"); + return false; + } + } + return true; + } + + public Token getToken() { + if (token.isExpired() || !token.isValid()) { + token = getNewToken(); + } + return token; + } + + /** + * Authorize at BMW Connected Drive Portal and re + * + * @return + */ + public Token getNewToken() { + http.setFollowRedirects(false); + Request req = http.POST(authUri); + + req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); + req.header(HttpHeader.CONNECTION, KEEP_ALIVE); + req.header(HttpHeader.HOST, BimmerConstants.SERVER_MAP.get(configuration.region)); + req.header(HttpHeader.AUTHORIZATION, BimmerConstants.AUTHORIZATION_VALUE); + req.header(CREDENTIALS, BimmerConstants.CREDENTIAL_VALUES); + + MultiMap dataMap = new MultiMap(); + dataMap.add(CLIENT_ID, BimmerConstants.CLIENT_ID_VALUE); + dataMap.add(RESPONSE_TYPE, TOKEN); + dataMap.add(REDIRECT_URI, BimmerConstants.REDIRECT_URI_VALUE); + dataMap.add(SCOPE, BimmerConstants.SCOPE_VALUES); + dataMap.add(USERNAME, configuration.userName); + dataMap.add(PASSWORD, configuration.password); + String urlEncodedData = UrlEncoded.encode(dataMap, Charset.defaultCharset(), false); + req.header(CONTENT_LENGTH, Integer.toString(urlEncodedData.length())); + req.content(new StringContentProvider(urlEncodedData)); + try { + ContentResponse contentResponse = req.timeout(TIMEOUT_SEC, TimeUnit.SECONDS).send(); + logger.info("Status {} ", contentResponse.getStatus()); + HttpFields fields = contentResponse.getHeaders(); + HttpField field = fields.getField(HttpHeader.LOCATION); + return getTokenFromUrl(field.getValue()); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + logger.warn("Auth Exception: {}", e.getMessage()); + } + return new Token(); + } + + public Token getTokenFromUrl(String encodedUrl) { + MultiMap tokenMap = new MultiMap(); + UrlEncoded.decodeTo(encodedUrl, tokenMap, StandardCharsets.US_ASCII); + final Token token = new Token(); + tokenMap.forEach((key, value) -> { + logger.info("Key {} Value {}", key, value); + if (key.endsWith(ACCESS_TOKEN)) { + token.setToken(value.get(0).toString()); + } else if (key.equals(EXPIRES_IN)) { + logger.info("Expires {}", value.get(0).toString()); + token.setExpiration(Integer.parseInt(value.get(0).toString())); + } else if (key.equals(TOKEN_TYPE)) { + token.setType(value.get(0).toString()); + } + }); + return token; + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java index 00d2c77ab8667..a051eb660f900 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -12,15 +12,15 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.handler; -import static org.openhab.binding.bmwconnecteddrive.internal.handler.HTTPConstants.*; +import static org.openhab.binding.bmwconnecteddrive.internal.utils.HTTPConstants.*; import java.nio.charset.Charset; +import java.util.Optional; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; 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; @@ -30,7 +30,6 @@ import org.eclipse.jetty.util.UrlEncoded; import org.openhab.binding.bmwconnecteddrive.internal.dto.remote.ExecutionStatus; import org.openhab.binding.bmwconnecteddrive.internal.dto.remote.ExecutionStatusContainer; -import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,6 +47,7 @@ public class RemoteServiceHandler { // after 60 retries the state update will give up private int counter = 0; private final int giveUpCounter = 120; + private static final int TIMEOUT_SEC = 10; public enum ExecutionState { READY("READY"), @@ -88,39 +88,54 @@ public String toString() { } } + private ConnectedDriveProxy proxy; private ConnectedCarHandler handler; private HttpClient httpClient; - private @Nullable String serviceExecuting; + private Optional serviceExecuting = Optional.empty(); - public RemoteServiceHandler(ConnectedCarHandler connectedCarHandler, HttpClient hc) { + private String serviceExecutionAPI; + private String serviceExecutionStateAPI; + + public RemoteServiceHandler(ConnectedCarHandler connectedCarHandler, ConnectedDriveProxy connectedDriveProxy, + HttpClient hc) { handler = connectedCarHandler; + proxy = connectedDriveProxy; httpClient = hc; + if (handler.getConfiguration().isPresent()) { + serviceExecutionAPI = proxy.baseUrl + handler.getConfiguration().get().vin + proxy.serviceExecutionAPI; + serviceExecutionStateAPI = proxy.baseUrl + handler.getConfiguration().get().vin + + proxy.serviceExecutionStateAPI; + } else { + serviceExecutionAPI = ""; + serviceExecutionStateAPI = ""; + logger.warn("No configuration for CarHandler available"); + } } boolean execute(RemoteService service) { synchronized (this) { - if (serviceExecuting != null) { + if (serviceExecuting.isPresent()) { return false; } - serviceExecuting = service.toString(); + serviceExecuting = Optional.of(service.toString()); } - if (handler.tokenUpdate()) { + if (proxy.tokenUpdate()) { MultiMap dataMap = new MultiMap(); dataMap.add("serviceType", service.toString()); String urlEncodedData = UrlEncoded.encode(dataMap, Charset.defaultCharset(), false); - Request req = httpClient.POST(handler.serviceExecutionAPI); + Request req = httpClient.POST(serviceExecutionAPI); req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); req.header("Content-Length", urlEncodedData.length() + ""); - req.header(HttpHeader.AUTHORIZATION, handler.token.getBearerToken()); + req.header(HttpHeader.AUTHORIZATION, proxy.getToken().getBearerToken()); req.content(new StringContentProvider(urlEncodedData)); // logger.info("URL encoded data {}", urlEncodedData); // logger.info("Data size {} ", urlEncodedData.length()); try { - ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); + ContentResponse contentResponse = req.timeout(TIMEOUT_SEC, TimeUnit.SECONDS).send(); if (contentResponse.getStatus() != 200) { - logger.info("URL {}", handler.serviceExecutionAPI); + logger.info("URL {}", serviceExecutionAPI); logger.info("Status {}", contentResponse.getStatus()); logger.info("Reason {}", contentResponse.getReason()); reset(); @@ -150,26 +165,25 @@ public void getState() { logger.warn("Giving up updating state for {} after {} times", serviceExecuting, giveUpCounter); } counter++; - Request req = httpClient.newRequest(handler.serviceExecutionStateAPI + serviceExecuting); + Request req = httpClient.newRequest(serviceExecutionStateAPI + serviceExecuting); req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); - req.header(HttpHeader.AUTHORIZATION, handler.token.getBearerToken()); + req.header(HttpHeader.AUTHORIZATION, proxy.getToken().getBearerToken()); try { - ContentResponse contentResponse = req.timeout(30, TimeUnit.SECONDS).send(); + ContentResponse contentResponse = req.timeout(TIMEOUT_SEC, TimeUnit.SECONDS).send(); if (contentResponse.getStatus() != 200) { - logger.info("URL {}", handler.serviceExecutionStateAPI); + logger.info("URL {}", serviceExecutionStateAPI); logger.info("Status {}", contentResponse.getStatus()); logger.info("Reason {}", contentResponse.getReason()); } else { String state = contentResponse.getContentAsString(); - logger.info("Executed {}, Response {}", serviceExecuting.toString(), state); + logger.info("Executed {}, Response {}", serviceExecuting.get(), state); ExecutionStatusContainer esc = ConnectedCarHandler.GSON.fromJson(state, ExecutionStatusContainer.class); ExecutionStatus execStatus = esc.executionStatus; + handler.updateRemoteExecutionStatus(serviceExecuting.get(), execStatus.status); if (!ExecutionState.EXECUTED.toString().equals(execStatus.status)) { logger.info("Continue state observing"); - handler.updateRemoteExecutionStatus( - Converter.toTitleCase(serviceExecuting + " " + execStatus.status)); handler.getScheduler().schedule(this::getState, 1, TimeUnit.SECONDS); } else { logger.info("Execution finished"); @@ -186,7 +200,7 @@ public void getState() { private void reset() { synchronized (this) { - serviceExecuting = null; + serviceExecuting = Optional.empty(); counter = 0; } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ResponseCallback.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ResponseCallback.java new file mode 100644 index 0000000000000..e44ec8e632e2d --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ResponseCallback.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link ResponseCallback} Marker Interface for all callbacks + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public interface ResponseCallback { + public void onError(String reason); +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/StringResponseCallback.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/StringResponseCallback.java new file mode 100644 index 0000000000000..f8a3cec2257ae --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/StringResponseCallback.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import java.util.Optional; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link StringResponseCallback} Interface for all Callbacks from async REST API results + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public interface StringResponseCallback extends ResponseCallback { + + public void onResponse(Optional result); + +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BimmerConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java similarity index 97% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BimmerConstants.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java index 4c47e26c7d362..d1a2b027c9bae 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BimmerConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.bmwconnecteddrive.internal.handler; +package org.openhab.binding.bmwconnecteddrive.internal.utils; import java.util.HashMap; import java.util.Map; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java index c8d77a4b479cd..dae8f13d4f9b7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java @@ -17,20 +17,28 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; + /** * The {@link Converter} Data Transfer Object * * @author Bernd Weymann - Initial contribution */ +@NonNullByDefault public class Converter { - public static final DateTimeFormatter serviceDateInputPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - public static final DateTimeFormatter serviceDateOutputPattern = DateTimeFormatter.ofPattern("MMM yyyy"); + public static final DateTimeFormatter SERVICE_DATE_INPUT_PATTERN = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + public static final DateTimeFormatter SERVICE_DATE_OUTPUT_PATTERN = DateTimeFormatter.ofPattern("MMM yyyy"); public static final String SPACE = " "; public static final String UNDERLINE = "_"; - private static final DateTimeFormatter inputPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); - private static final DateTimeFormatter outputPattern = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); + public static final DateTimeFormatter DATE_INPUT_PATTERN = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); + public static final DateTimeFormatter DATE_TIMEZONE_INPUT_PATTERN = DateTimeFormatter + .ofPattern("yyyy-MM-dd'T'HH:mm:ssZ"); + private static final DateTimeFormatter DATE_OUTPUT_PATTERN = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); + + public static final int MILES_TO_FEET_FACTOR = 5280; public static double round(double value) { double scale = Math.pow(10, 1); @@ -38,19 +46,48 @@ public static double round(double value) { } public static String getLocalDateTime(String input) { - LocalDateTime ldt = LocalDateTime.parse(input, Converter.inputPattern); + if (input == null) { + return Converter.toTitleCase(VehicleStatus.UNKNOWN); + } + + LocalDateTime ldt = LocalDateTime.parse(input, Converter.DATE_INPUT_PATTERN); ZonedDateTime zdtUTC = ldt.atZone(ZoneId.of("UTC")); ZonedDateTime zdtLZ = zdtUTC.withZoneSameInstant(ZoneId.systemDefault()); - return zdtLZ.format(Converter.outputPattern); + return zdtLZ.format(Converter.DATE_OUTPUT_PATTERN); + } + + public static String getZonedDateTime(String input) { + if (input == null) { + return Converter.toTitleCase(VehicleStatus.UNKNOWN); + } + + ZonedDateTime zdt = ZonedDateTime.parse(input, Converter.DATE_TIMEZONE_INPUT_PATTERN); + ZonedDateTime zdtLZ = zdt.withZoneSameInstant(ZoneId.systemDefault()); + return zdtLZ.format(Converter.DATE_OUTPUT_PATTERN); } public static String toTitleCase(String input) { - String lower = input.replaceAll(UNDERLINE, SPACE).toLowerCase(); - String[] arr = lower.split(SPACE); - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < arr.length; i++) { - sb.append(Character.toUpperCase(arr[i].charAt(0))).append(arr[i].substring(1)).append(" "); + if (input == null) { + return Converter.toTitleCase(VehicleStatus.UNKNOWN); + } else { + String lower = input.replaceAll(UNDERLINE, SPACE).toLowerCase(); + String[] arr = lower.split(SPACE); + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < arr.length; i++) { + sb.append(Character.toUpperCase(arr[i].charAt(0))).append(arr[i].substring(1)).append(" "); + } + return sb.toString().trim(); } - return sb.toString().trim(); + } + + public static double measure(float lat1, float lon1, float lat2, float lon2) { + double earthRadius = 6378.137; // Radius of earth in KM + double dLat = lat2 * Math.PI / 180 - lat1 * Math.PI / 180; + double dLon = lon2 * Math.PI / 180 - lon1 * Math.PI / 180; + double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat1 * Math.PI / 180) + * Math.cos(lat2 * Math.PI / 180) * Math.sin(dLon / 2) * Math.sin(dLon / 2); + double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + double d = earthRadius * c; + return d * 1000; // meters } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/HTTPConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/HTTPConstants.java similarity index 92% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/HTTPConstants.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/HTTPConstants.java index 9354b112f04e7..ba0496ad55ead 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/HTTPConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/HTTPConstants.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.bmwconnecteddrive.internal.handler; +package org.openhab.binding.bmwconnecteddrive.internal.utils; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -32,6 +32,7 @@ public class HTTPConstants { public static final String CREDENTIALS = "Credentials"; public static final String USERNAME = "username"; public static final String PASSWORD = "password"; + public static final String CONTENT_LENGTH = "Content-Length"; public static final String ACCESS_TOKEN = "access_token"; public static final String TOKEN_TYPE = "token_type"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/binding/binding.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/binding/binding.xml index bb1d905db4e35..f2395ba6ee8f1 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/binding/binding.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/binding/binding.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd"> BMW ConnectedDrive - Provides access to your Car via BMW Connected Drive Portal + Provides access to your Vehicle Data via BMW Connected Drive Portal Bernd Weymann diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml index a2c19d1f1781e..8b925523cd8c0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml @@ -25,8 +25,8 @@ - - BMW Car VIN + + Data Refresh Rate for your Vehicle data diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml index f45bf1ce3030e..c7fab5f1d4d5b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml @@ -29,8 +29,8 @@ BMW Car VIN - - Data Refresh Rate for your Car values + + Data Refresh Rate for your Vehicle data 5 @@ -54,7 +54,7 @@ - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml index 9cd6a23418b32..362a582fd3718 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml @@ -27,8 +27,8 @@ BMW Car VIN - - Data Refresh Rate for your Car values + + Data Refresh Rate for your Vehicle data 5 @@ -52,7 +52,7 @@ - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml index 1af7978667151..8c0ea98308f71 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml @@ -29,8 +29,8 @@ BMW Car VIN - - Data Refresh Rate for your Car values + + Data Refresh Rate for your Vehicle data 5 @@ -54,7 +54,7 @@ - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java new file mode 100644 index 0000000000000..2636c418da5c7 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.discovery; + +import static org.mockito.Mockito.*; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.smarthome.config.discovery.DiscoveryListener; +import org.eclipse.smarthome.config.discovery.DiscoveryResult; +import org.eclipse.smarthome.config.discovery.DiscoveryService; +import org.eclipse.smarthome.core.thing.Bridge; +import org.eclipse.smarthome.core.thing.ThingUID; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.openhab.binding.bmwconnecteddrive.internal.dto.ConnectedDriveUserInfo; +import org.openhab.binding.bmwconnecteddrive.internal.handler.ConnectedDriveBridgeHandler; +import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; + +/** + * The {@link DiscoveryTest} Test Discovery Results + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class DiscoveryTest { + private final Logger logger = LoggerFactory.getLogger(DiscoveryTest.class); + private static final Gson GSON = new Gson(); + + @Test + public void testDiscovery() { + String content = FileReader.readFileInString("src/test/resources/responses/vehicles.json"); + ConnectedDriveBridgeHandler bh = mock(ConnectedDriveBridgeHandler.class); + Bridge b = mock(Bridge.class); + when(bh.getThing()).thenReturn(b); + when(b.getUID()).thenReturn(new ThingUID("testbinding", "test")); + ConnectedCarDiscovery discovery = new ConnectedCarDiscovery(bh); + DiscoveryListener listener = mock(DiscoveryListener.class); + discovery.addDiscoveryListener(listener); + ConnectedDriveUserInfo cdui = GSON.fromJson(content, ConnectedDriveUserInfo.class); + ArgumentCaptor discoveries = ArgumentCaptor.forClass(DiscoveryResult.class); + ArgumentCaptor services = ArgumentCaptor.forClass(DiscoveryService.class); + + discovery.scan(cdui); + verify(listener, times(8)).thingDiscovered(services.capture(), discoveries.capture()); + List results = discoveries.getAllValues(); + results.forEach(entry -> { + logger.info("{}", entry.toString()); + }); + } + +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java index c79ebca53f74a..e8f3353da20a2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java @@ -54,7 +54,7 @@ public void testUserInfo() { @Test public void testChannelUID() { - ThingTypeUID THING_TYPE_PHEV = new ThingTypeUID("bmwconnecteddrive", "plugin-hybrid-car"); - assertEquals("Car Type", "plugin-hybrid-car", THING_TYPE_PHEV.getId()); + ThingTypeUID thingTypePHEV = new ThingTypeUID("bmwconnecteddrive", "plugin-hybrid-car"); + assertEquals("Car Type", "plugin-hybrid-car", thingTypePHEV.getId()); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/RemoteStatusTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/RemoteStatusTest.java index 5af63d6a47453..16a36f0e9b59a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/RemoteStatusTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/RemoteStatusTest.java @@ -12,8 +12,11 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.dto.remote; +import static org.junit.Assert.assertEquals; + import org.eclipse.jdt.annotation.NonNullByDefault; import org.junit.Test; +import org.openhab.binding.bmwconnecteddrive.internal.handler.RemoteServiceHandler.ExecutionState; import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; import com.google.gson.Gson; @@ -32,6 +35,6 @@ public void testStatus() { String resource1 = FileReader.readFileInString("src/test/resources/webapi/remote-services/pending.json"); ExecutionStatusContainer esc = GSON.fromJson(resource1, ExecutionStatusContainer.class); ExecutionStatus execStatus = esc.executionStatus; - System.out.println(execStatus.status); + assertEquals("Status", ExecutionState.PENDING.toString(), execStatus.status); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripTest.java index 6cfd4b5ef9f3a..cf00243fae0d9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripTest.java @@ -12,7 +12,7 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.dto.statistics; -import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.*; import org.eclipse.jdt.annotation.NonNullByDefault; import org.junit.Test; @@ -35,6 +35,6 @@ public void testUserInfo() { LastTripContainer lt = GSON.fromJson(content, LastTripContainer.class); LastTrip trip = lt.lastTrip; assertNotNull(trip); - System.out.println(trip.totalDistance); + assertEquals("Distance Driven", 2.0, trip.totalDistance, 0.01); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/StatusWrapper.java new file mode 100644 index 0000000000000..423f7a7331e29 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/StatusWrapper.java @@ -0,0 +1,247 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.status; + +import static org.junit.Assert.*; +import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; + +import java.util.List; + +import javax.measure.Unit; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.library.types.DecimalType; +import org.eclipse.smarthome.core.library.types.QuantityType; +import org.eclipse.smarthome.core.library.types.StringType; +import org.eclipse.smarthome.core.library.unit.ImperialUnits; +import org.eclipse.smarthome.core.library.unit.MetricPrefix; +import org.eclipse.smarthome.core.library.unit.SIUnits; +import org.eclipse.smarthome.core.library.unit.SmartHomeUnits; +import org.eclipse.smarthome.core.thing.ChannelUID; +import org.eclipse.smarthome.core.types.State; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CarType; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; + +import com.google.gson.Gson; + +/** + * The {@link StatusWrapper} Test json responses from ConnectedDrive Portal + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class StatusWrapper { + private static final Gson GSON = new Gson(); + private static final Unit KILOMETRE = MetricPrefix.KILO(SIUnits.METRE); + + private VehicleStatus vStatus; + private boolean imperial; + private boolean isElectric; + private boolean hasFuel; + private boolean isHybrid; + + public StatusWrapper(@Nullable String type, boolean imperial, @Nullable String statusJson) { + this.imperial = imperial; + hasFuel = type.equals(CarType.CONVENTIONAL.toString()) || type.equals(CarType.PLUGIN_HYBRID.toString()) + || type.equals(CarType.ELECTRIC_REX.toString()); + isElectric = type.equals(CarType.PLUGIN_HYBRID.toString()) || type.equals(CarType.ELECTRIC_REX.toString()) + || type.equals(CarType.ELECTRIC.toString()); + isHybrid = hasFuel && isElectric; + VehicleStatusContainer container = GSON.fromJson(statusJson, VehicleStatusContainer.class); + assertNotNull(container); + assertNotNull(container.vehicleStatus); + vStatus = container.vehicleStatus; + + } + + public boolean checkResults(@Nullable List channels, @Nullable List states) { + assertNotNull(channels); + assertNotNull(states); + assertTrue("Same list sizes ", channels.size() == states.size()); + for (int i = 0; i < channels.size(); i++) { + checkResult(channels.get(i), states.get(i)); + } + return true; + } + + private void checkResult(ChannelUID channelUID, State state) { + String cUid = channelUID.getIdWithoutGroup(); + QuantityType qt; + StringType st; + DecimalType dt; + switch (cUid) { + case MILEAGE: + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + if (imperial) { + assertEquals("Miles", ImperialUnits.MILE, qt.getUnit()); + } else { + assertEquals("KM", KILOMETRE, qt.getUnit()); + } + assertEquals("Mileage", qt.intValue(), vStatus.mileage); + break; + case REMAINING_RANGE_ELECTRIC: + assertTrue("Is Eelctric", isElectric); + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + if (imperial) { + assertEquals("Miles", ImperialUnits.MILE, qt.getUnit()); + assertEquals("Mileage", Converter.round(qt.floatValue()), + Converter.round(vStatus.remainingRangeElectricMls), 0.01); + } else { + assertEquals("KM", KILOMETRE, qt.getUnit()); + assertEquals("Mileage", Converter.round(qt.floatValue()), + Converter.round(vStatus.remainingRangeElectric), 0.01); + } + break; + case REMAINING_RANGE_FUEL: + assertTrue("Has Fuel", hasFuel); + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + if (imperial) { + assertEquals("Miles", ImperialUnits.MILE, qt.getUnit()); + assertEquals("Mileage", Converter.round(qt.floatValue()), + Converter.round(vStatus.remainingRangeFuelMls), 0.01); + } else { + assertEquals("KM", KILOMETRE, qt.getUnit()); + assertEquals("Mileage", Converter.round(qt.floatValue()), + Converter.round(vStatus.remainingRangeFuel), 0.01); + } + break; + case REMAINING_RANGE_HYBRID: + assertTrue("Is Hybrid", isHybrid); + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + if (imperial) { + assertEquals("Miles", ImperialUnits.MILE, qt.getUnit()); + assertEquals("Mileage", Converter.round(qt.floatValue()), + Converter.round(vStatus.remainingRangeElectricMls + vStatus.remainingRangeFuelMls), 0.01); + } else { + assertEquals("KM", KILOMETRE, qt.getUnit()); + assertEquals("Mileage", Converter.round(qt.floatValue()), + Converter.round(vStatus.remainingRangeElectric + vStatus.remainingRangeFuel), 0.01); + } + break; + case REMAINING_FUEL: + assertTrue("Has Fuel", hasFuel); + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + assertEquals("Percent", SmartHomeUnits.LITRE, qt.getUnit()); + assertEquals("Percent", Converter.round(vStatus.remainingFuel), Converter.round(qt.floatValue()), 0.01); + break; + case REMAINING_SOC: + assertTrue("Is Eelctric", isElectric); + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + assertEquals("Percent", SmartHomeUnits.PERCENT, qt.getUnit()); + assertEquals("Percent", Converter.round(vStatus.chargingLevelHv), Converter.round(qt.floatValue()), + 0.01); + break; + case LOCK: + assertTrue(state instanceof StringType); + st = (StringType) state; + assertEquals("Vehicle locked", Converter.toTitleCase(vStatus.doorLockState), st.toString()); + break; + case DOORS: + assertTrue(state instanceof StringType); + st = (StringType) state; + Doors doorState = GSON.fromJson(GSON.toJson(vStatus), Doors.class); + assertEquals("Doors Closed", VehicleStatus.checkClosed(doorState), st.toString()); + break; + case WINDOWS: + assertTrue(state instanceof StringType); + st = (StringType) state; + Windows windowState = GSON.fromJson(GSON.toJson(vStatus), Windows.class); + assertEquals("Windows Closed", VehicleStatus.checkClosed(windowState), st.toString()); + break; + case CHECK_CONTROL: + assertTrue(state instanceof StringType); + st = (StringType) state; + assertEquals("Check Control", vStatus.getCheckControl(), st.toString()); + break; + case SERVICE: + assertTrue(state instanceof StringType); + st = (StringType) state; + assertEquals("Next Service", vStatus.getNextService(imperial), st.toString()); + break; + case CHARGING_STATUS: + assertTrue("Is Eelctric", isElectric); + assertTrue(state instanceof StringType); + st = (StringType) state; + assertEquals("Charge Status", Converter.toTitleCase(vStatus.chargingStatus), st.toString()); + break; + case LAST_UPDATE: + assertTrue(state instanceof StringType); + st = (StringType) state; + if (vStatus.internalDataTimeUTC != null) { + assertEquals("Last Update", Converter.getLocalDateTime(vStatus.internalDataTimeUTC), st.toString()); + } else { + assertEquals("Last Update", Converter.getZonedDateTime(vStatus.updateTime), st.toString()); + } + break; + case LATITUDE: + assertTrue(state instanceof DecimalType); + dt = (DecimalType) state; + assertNotNull(vStatus.position); + assertEquals("Latitude", Converter.round(vStatus.position.lat), Converter.round(dt.floatValue()), 0.01); + break; + case LONGITUDE: + assertTrue(state instanceof DecimalType); + dt = (DecimalType) state; + assertNotNull(vStatus.position); + assertEquals("Longitude", Converter.round(vStatus.position.lon), Converter.round(dt.floatValue()), + 0.01); + break; + case HEADING: + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + assertEquals("Angle Unit", SmartHomeUnits.DEGREE_ANGLE, qt.getUnit()); + assertNotNull(vStatus.position); + assertEquals("Heading", vStatus.position.heading, qt.intValue(), 0.01); + break; + case LATLONG: + assertTrue(state instanceof StringType); + st = ((StringType) state); + assertNotNull(vStatus.position); + assertEquals("Lat/Long", vStatus.position.lat + "," + vStatus.position.lon, st.toString()); + break; + case RANGE_RADIUS: + assertTrue(state instanceof DecimalType); + dt = (DecimalType) state; + int totalRange = 0; + if (imperial) { + if (isElectric) { + totalRange += vStatus.remainingRangeElectricMls * Converter.MILES_TO_FEET_FACTOR; + } + if (hasFuel) { + totalRange += vStatus.remainingRangeFuelMls * Converter.MILES_TO_FEET_FACTOR; + } + } else { + if (isElectric) { + totalRange += vStatus.remainingRangeElectric * 1000; + } + if (hasFuel) { + totalRange += vStatus.remainingRangeFuel * 1000; + } + } + assertEquals("Range Circle", totalRange, dt.intValue()); + break; + default: + // fail in case of unknown update + assertFalse("Channel " + channelUID + " " + state + " not found", true); + break; + } + } + +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusTest.java index af4e64b0359d7..ed3dc5ccbeec0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusTest.java @@ -30,12 +30,15 @@ public class VehicleStatusTest { private static final Gson GSON = new Gson(); @Test - public void testtestBEV_REX_Values() { + public void testtestBevRexValues() { String resource1 = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); VehicleStatusContainer status = GSON.fromJson(resource1, VehicleStatusContainer.class); VehicleStatus vStatus = status.vehicleStatus; assertEquals("Mileage", 17273.0, vStatus.mileage, 0.1); Position p = vStatus.position; assertEquals("Heading", 219, p.heading); + + assertEquals("DCS Activation", "NA", vStatus.dcsCchActivation); + assertEquals("DCS Ongoing", false, vStatus.dcsCchOngoing); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java index 10862b01465b5..4590caa3cf7e0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java @@ -17,9 +17,8 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jetty.client.HttpClient; -import org.eclipse.smarthome.core.thing.Bridge; import org.junit.Test; -import org.osgi.framework.BundleContext; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,11 +34,10 @@ public class AuthTest { @Test public void testTokenDecoding() { - Bridge b = mock(Bridge.class); - ConnectedDriveBridgeHandler cdbh = new ConnectedDriveBridgeHandler(b, new HttpClient(), - mock(BundleContext.class)); String headerValue = "https://www.bmw-connecteddrive.com/app/static/external-dispatch.html#access_token=SfXKgkEXeeFJkVqdD4XMmfUU224MRuyh&token_type=Bearer&expires_in=7199"; - Token t = cdbh.getTokenFromUrl(headerValue); + ConnectedDriveProxy dcp = new ConnectedDriveProxy(mock(HttpClient.class), + mock(ConnectedDriveConfiguration.class)); + Token t = dcp.getTokenFromUrl(headerValue); assertEquals("Token", "Bearer SfXKgkEXeeFJkVqdD4XMmfUU224MRuyh", t.getBearerToken()); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java index 0bb883afb6fa1..fe7aa3a2f8d4c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java @@ -12,21 +12,24 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.handler; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; import static org.mockito.Mockito.*; import java.util.List; +import java.util.Optional; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jetty.client.HttpClient; import org.eclipse.smarthome.core.thing.ChannelUID; import org.eclipse.smarthome.core.thing.Thing; import org.eclipse.smarthome.core.thing.ThingUID; import org.eclipse.smarthome.core.thing.binding.ThingHandlerCallback; import org.eclipse.smarthome.core.types.State; -import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CarType; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.StatusWrapper; import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,64 +40,278 @@ * * @author Bernd Weymann - Initial contribution */ +@NonNullByDefault public class CarTests { private final Logger logger = LoggerFactory.getLogger(ConnectedCarHandler.class); // ConnectedCarHandler cch = new Co - @Before - public void setup() { - } + @Nullable + ArgumentCaptor channelCaptor; + @Nullable + ArgumentCaptor stateCaptor; + @Nullable + ThingHandlerCallback tc; + @Nullable + ConnectedCarHandler cch; + @Nullable + List allChannels; + @Nullable + List allStates; + @Nullable + String driveTrain; + boolean imperial; - @Test - public void testi3Rex() { - String content = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); + /** + * Prepare environment for Vehicle Status Updates + */ + public void setup(String type, boolean imperial) { + driveTrain = type; + this.imperial = imperial; Thing thing = mock(Thing.class); when(thing.getUID()).thenReturn(new ThingUID("testbinding", "test")); HttpClient hc = mock(HttpClient.class); - ConnectedCarHandler cch = new ConnectedCarHandler(thing, hc, CarType.ELECTRIC_REX.toString(), true); - ThingHandlerCallback tc = mock(ThingHandlerCallback.class); + cch = new ConnectedCarHandler(thing, hc, type, imperial); + tc = mock(ThingHandlerCallback.class); cch.setCallback(tc); - cch.updateRangeValues(content); + channelCaptor = ArgumentCaptor.forClass(ChannelUID.class); + stateCaptor = ArgumentCaptor.forClass(State.class); + + } + + private boolean testCar(@Nullable String statusContent, int callbacksExpected) { + assertNotNull(statusContent); - ArgumentCaptor channelCaptor = ArgumentCaptor.forClass(ChannelUID.class); - ArgumentCaptor stateCaptor = ArgumentCaptor.forClass(State.class); - ; + cch.vehicleStatusCallback.onResponse(Optional.of(statusContent)); + verify(tc, times(callbacksExpected)).stateUpdated(channelCaptor.capture(), stateCaptor.capture()); + allChannels = channelCaptor.getAllValues(); + allStates = stateCaptor.getAllValues(); - // ArgumentCaptor> channelCaptor; - // ArgumentCaptor> stateCaptor; + assertNotNull(driveTrain); + StatusWrapper checker = new StatusWrapper(driveTrain, imperial, statusContent); + trace(); + return checker.checkResults(allChannels, allStates); + } - verify(tc, times(12)).stateUpdated(channelCaptor.capture(), stateCaptor.capture()); - List allChannels = channelCaptor.getAllValues(); - List allStates = stateCaptor.getAllValues(); + private void trace() { for (int i = 0; i < allChannels.size(); i++) { logger.info("Channel {} {}", allChannels.get(i), allStates.get(i)); } - assertEquals("Results ", 12, allChannels.size()); } + /** + * Sequence for BEV_REX + * Channel testbinding::test:status#lock Secured + * Channel testbinding::test:status#doors Closed + * Channel testbinding::test:status#windows Closed + * Channel testbinding::test:status#check-control Ok + * Channel testbinding::test:status#service Nov 2021 - Brake Fluid + * Channel testbinding::test:status#charging-status Invalid + * Channel testbinding::test:range#mileage 17273.0 km + * Channel testbinding::test:range#remaining-range-electric 148.0 km + * Channel testbinding::test:range#remaining-range-fuel 70.0 km + * Channel testbinding::test:range#remaining-range-hybrid 218.0 km + * Channel testbinding::test:location#range-radius 218000.0 + * Channel testbinding::test:range#remaining-soc 71.0 % + * Channel testbinding::test:range#remaining-fuel 4.0 l + * Channel testbinding::test:range#last-update 24.08.2020 17:55 + * Channel testbinding::test:location#latitude 50.55604934692383 + * Channel testbinding::test:location#longitude 8.4956693649292 + * Channel testbinding::test:location#latlong 50.55605,8.495669 + * Channel testbinding::test:location#heading 219.0 ° + */ @Test - public void testi3RexStatus() { + public void testMyi3Rex() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(CarType.ELECTRIC_REX.toString(), false); String content = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); - Thing thing = mock(Thing.class); - when(thing.getUID()).thenReturn(new ThingUID("testbinding", "test")); - HttpClient hc = mock(HttpClient.class); - ConnectedCarHandler cch = new ConnectedCarHandler(thing, hc, CarType.ELECTRIC_REX.toString(), true); - ThingHandlerCallback tc = mock(ThingHandlerCallback.class); - cch.setCallback(tc); - cch.updateVehicleStatus(content); + assertTrue(testCar(content, 18)); + } + + /** + * Channel testbinding::test:status#lock Secured + * Channel testbinding::test:status#doors Closed + * Channel testbinding::test:status#windows Closed + * Channel testbinding::test:status#check-control Ok + * Channel testbinding::test:status#service Nov 2021 - Brake Fluid + * Channel testbinding::test:status#charging-status Invalid + * Channel testbinding::test:range#mileage 17273.0 mi + * Channel testbinding::test:range#remaining-range-electric 91.0 mi + * Channel testbinding::test:range#remaining-range-fuel 43.0 mi + * Channel testbinding::test:range#remaining-range-hybrid 134.0 mi + * Channel testbinding::test:location#range-radius 707520.0 + * Channel testbinding::test:range#remaining-soc 71.0 % + * Channel testbinding::test:range#remaining-fuel 4.0 l + * Channel testbinding::test:range#last-update 24.08.2020 17:55 + * Channel testbinding::test:location#latitude 50.55604934692383 + * Channel testbinding::test:location#longitude 8.4956693649292 + * Channel testbinding::test:location#latlong 50.55605,8.495669 + * Channel testbinding::test:location#heading 219.0 ° + */ + @Test + public void testMyi3RexMiles() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(CarType.ELECTRIC_REX.toString(), true); + String content = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); + assertTrue(testCar(content, 18)); + } - ArgumentCaptor channelCaptor = ArgumentCaptor.forClass(ChannelUID.class); - ArgumentCaptor stateCaptor = ArgumentCaptor.forClass(State.class); - ; + /** + * Channel testbinding::test:status#lock Unlocked + * Channel testbinding::test:status#doors Closed + * Channel testbinding::test:status#windows Closed + * Channel testbinding::test:status#check-control Ok + * Channel testbinding::test:status#service Jun 2018 or in 12000 km - Oil + * Channel testbinding::test:range#mileage 1629.0 km + * Channel testbinding::test:range#remaining-range-fuel 249.0 km + * Channel testbinding::test:location#range-radius 249000.0 + * Channel testbinding::test:range#remaining-fuel 30.0 l + * Channel testbinding::test:range#last-update 09.03.2018 04:21 + * Channel testbinding::test:location#latitude 123.12300109863281 + * Channel testbinding::test:location#longitude -123.12300109863281 + * Channel testbinding::test:location#latlong 123.123,-123.123 + * Channel testbinding::test:location#heading 11.0 ° + */ + @Test + public void testF15() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(CarType.CONVENTIONAL.toString(), false); + String content = FileReader.readFileInString("src/test/resources/responses/F15/status.json"); + assertTrue(testCar(content, 14)); + } - // ArgumentCaptor> channelCaptor; - // ArgumentCaptor> stateCaptor; + @Test + public void testF15Miles() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(CarType.CONVENTIONAL.toString(), true); + String content = FileReader.readFileInString("src/test/resources/responses/F15/status.json"); + assertTrue(testCar(content, 14)); + } - verify(tc, times(6)).stateUpdated(channelCaptor.capture(), stateCaptor.capture()); - List allChannels = channelCaptor.getAllValues(); - List allStates = stateCaptor.getAllValues(); - for (int i = 0; i < allChannels.size(); i++) { - logger.info("Channel {} {}", allChannels.get(i), allStates.get(i)); - } + /** + * Channel testbinding::test:status#lock Unkown + * Channel testbinding::test:status#doors Unkown + * Channel testbinding::test:status#windows Unkown + * Channel testbinding::test:status#check-control Unkown + * Channel testbinding::test:status#service Unkown + * Channel testbinding::test:range#mileage 0.0 km + * Channel testbinding::test:range#remaining-range-fuel 0.0 km + * Channel testbinding::test:location#range-radius 0.0 + * Channel testbinding::test:range#remaining-fuel 0.0 l + * Channel testbinding::test:range#last-update Unkown + * Channel testbinding::test:location#latitude 12.345600128173828 + * Channel testbinding::test:location#longitude 34.56779861450195 + * Channel testbinding::test:location#latlong 12.3456,34.5678 + * Channel testbinding::test:location#heading 0.0 ° @Test + */ + @Test + public void testF31() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(CarType.CONVENTIONAL.toString(), false); + String content = FileReader.readFileInString("src/test/resources/responses/F31/status.json"); + assertTrue(testCar(content, 14)); + } + + @Test + public void testF31Miles() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(CarType.CONVENTIONAL.toString(), true); + String content = FileReader.readFileInString("src/test/resources/responses/F31/status.json"); + assertTrue(testCar(content, 14)); + } + + @Test + public void testF35() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(CarType.CONVENTIONAL.toString(), false); + String content = FileReader.readFileInString("src/test/resources/responses/F35/status.json"); + assertTrue(testCar(content, 14)); + } + + @Test + public void testF35Miles() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(CarType.CONVENTIONAL.toString(), true); + String content = FileReader.readFileInString("src/test/resources/responses/F35/status.json"); + assertTrue(testCar(content, 14)); + } + + @Test + public void testF45() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(CarType.CONVENTIONAL.toString(), false); + String content = FileReader.readFileInString("src/test/resources/responses/F45/status.json"); + assertTrue(testCar(content, 14)); + } + + @Test + public void testF45Miles() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(CarType.CONVENTIONAL.toString(), true); + String content = FileReader.readFileInString("src/test/resources/responses/F45/status.json"); + assertTrue(testCar(content, 14)); + } + + @Test + public void testF48() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(CarType.CONVENTIONAL.toString(), false); + String content = FileReader.readFileInString("src/test/resources/responses/F48/status.json"); + assertTrue(testCar(content, 14)); + } + + @Test + public void testF48Miles() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(CarType.CONVENTIONAL.toString(), true); + String content = FileReader.readFileInString("src/test/resources/responses/F48/status.json"); + assertTrue(testCar(content, 14)); + } + + @Test + public void testG31NBTEvo() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(CarType.CONVENTIONAL.toString(), false); + String content = FileReader.readFileInString("src/test/resources/responses/G31_NBTevo/status.json"); + assertTrue(testCar(content, 14)); + } + + @Test + public void testG31NBTEvoMiles() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(CarType.CONVENTIONAL.toString(), true); + String content = FileReader.readFileInString("src/test/resources/responses/G31_NBTevo/status.json"); + assertTrue(testCar(content, 14)); + } + + @Test + public void testI01NoRex() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(CarType.ELECTRIC.toString(), false); + String content = FileReader.readFileInString("src/test/resources/responses/I01_NOREX/status.json"); + assertTrue(testCar(content, 15)); + } + + @Test + public void testI01NoRexMiles() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(CarType.ELECTRIC.toString(), true); + String content = FileReader.readFileInString("src/test/resources/responses/I01_NOREX/status.json"); + assertTrue(testCar(content, 15)); + } + + @Test + public void testI01Rex() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(CarType.ELECTRIC_REX.toString(), false); + String content = FileReader.readFileInString("src/test/resources/responses/I01_REX/status.json"); + assertTrue(testCar(content, 18)); + } + + @Test + public void testI01RexMiles() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(CarType.ELECTRIC_REX.toString(), true); + String content = FileReader.readFileInString("src/test/resources/responses/I01_REX/status.json"); + assertTrue(testCar(content, 18)); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ErrorResponseTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ErrorResponseTest.java new file mode 100644 index 0000000000000..0514f87dcb0c1 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ErrorResponseTest.java @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import static org.mockito.Mockito.*; + +import java.util.List; +import java.util.Optional; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.smarthome.core.thing.ChannelUID; +import org.eclipse.smarthome.core.thing.Thing; +import org.eclipse.smarthome.core.thing.ThingUID; +import org.eclipse.smarthome.core.thing.binding.ThingHandlerCallback; +import org.eclipse.smarthome.core.types.State; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link ErrorResponseTest} is responsible for handling commands, which are + * sent to one of the channels. + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class ErrorResponseTest { + private final Logger logger = LoggerFactory.getLogger(ConnectedCarHandler.class); + // ConnectedCarHandler cch = new Co + + @Nullable + ArgumentCaptor channelCaptor; + @Nullable + ArgumentCaptor stateCaptor; + @Nullable + ThingHandlerCallback tc; + @Nullable + ConnectedCarHandler cch; + @Nullable + List allChannels; + @Nullable + List allStates; + @Nullable + String driveTrain; + boolean imperial; + + /** + * Prepare environment for Vehicle Status Updates + */ + public void setup(String type, boolean imperial) { + driveTrain = type; + this.imperial = imperial; + Thing thing = mock(Thing.class); + when(thing.getUID()).thenReturn(new ThingUID("testbinding", "test")); + HttpClient hc = mock(HttpClient.class); + cch = new ConnectedCarHandler(thing, hc, type, imperial); + tc = mock(ThingHandlerCallback.class); + cch.setCallback(tc); + channelCaptor = ArgumentCaptor.forClass(ChannelUID.class); + stateCaptor = ArgumentCaptor.forClass(State.class); + + } + + // private boolean testCar(@Nullable String statusContent, int callbacksExpected) { + // assertNotNull(statusContent); + // + // cch.vehicleStatusCallback.onResponse(Optional.of(statusContent)); + // verify(tc, times(callbacksExpected)).stateUpdated(channelCaptor.capture(), stateCaptor.capture()); + // allChannels = channelCaptor.getAllValues(); + // allStates = stateCaptor.getAllValues(); + // + // assertNotNull(driveTrain); + // StatusWrapper checker = new StatusWrapper(driveTrain, imperial, statusContent); + // trace(); + // return checker.checkResults(allChannels, allStates); + // } + // + // private void trace() { + // for (int i = 0; i < allChannels.size(); i++) { + // logger.info("Channel {} {}", allChannels.get(i), allStates.get(i)); + // } + // } + + @Test + public void testErrorResponseCallbacks() { + String error = "{\"error\":true,\"reason\":\"offline\"}"; + setup("BEV", false); + cch.vehicleStatusCallback.onResponse(Optional.of(error)); + cch.allTripsCallback.onResponse(Optional.of(error)); + cch.lastTripCallback.onResponse(Optional.of(error)); + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java index 922873cfd57c8..0b662b857658a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java @@ -17,10 +17,11 @@ import java.time.LocalDate; import java.util.Locale; +import org.eclipse.jdt.annotation.NonNullByDefault; import org.junit.Test; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants; -import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import com.google.gson.Gson; @@ -31,6 +32,7 @@ * * @author Bernd Weymann - Initial contribution */ +@NonNullByDefault public class LocaleTest { private static final Gson GSON = new Gson(); @@ -54,9 +56,15 @@ public void testTimeUTCToLocaleTime() { @Test public void testServiceDatePattern() { String pattern = "2021-11-01"; - LocalDate ldt = LocalDate.parse(pattern, Converter.serviceDateInputPattern); + LocalDate ldt = LocalDate.parse(pattern, Converter.SERVICE_DATE_INPUT_PATTERN); assertEquals("Parsed Date", "2021-11-01", ldt.toString()); - System.out.println(); - assertEquals("Parsed Date", "Nov 2021", ldt.format(Converter.serviceDateOutputPattern)); + assertEquals("Parsed Date", "Nov 2021", ldt.format(Converter.SERVICE_DATE_OUTPUT_PATTERN)); + } + + @Test + public void testTimeZoneDateTime() { + String pattern = "2018-07-16T21:47:46+0000"; + assertEquals("ZonedDateTime", "16.07.2018 23:47", Converter.getZonedDateTime(pattern)); } + } From 8a4c05e7c38a91aa2a01ef1eef50afd7450bd653 Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 1 Sep 2020 20:02:47 +0200 Subject: [PATCH 014/176] Constant cleanup, Network error handling and logging cleanup Signed-off-by: Bernd (cherry picked from commit a3b8723d5f262dd4e4c0b62b18f6751db688937b) Signed-off-by: Bernd --- .../internal/ConnectedCarConfiguration.java | 3 +- .../internal/ConnectedDriveConfiguration.java | 7 +- .../discovery/ConnectedCarDiscovery.java | 62 ++++++++------- ...edDriveUserInfo.java => NetworkError.java} | 22 +++--- .../internal/dto/charge/ChargeProfile.java | 22 ++++++ .../internal/dto/charge/ChargingWindow.java | 23 ++++++ .../internal/dto/charge/Timer.java | 34 ++++++++ .../internal/dto/charge/WeeklyPlanner.java | 29 +++++++ .../internal/dto/{ => discovery}/Dealer.java | 2 +- .../internal/dto/{ => discovery}/Vehicle.java | 6 +- .../dto/discovery/VehiclesContainer.java | 24 ++++++ .../internal/dto/status/VehicleStatus.java | 12 +-- .../handler/ByteResponseCallback.java | 2 +- .../internal/handler/ConnectedCarHandler.java | 78 +++++++++++-------- .../handler/ConnectedDriveBridgeHandler.java | 53 ++++++------- .../internal/handler/ConnectedDriveProxy.java | 18 ++--- .../handler/RemoteServiceHandler.java | 7 +- .../internal/handler/ResponseCallback.java | 5 +- .../handler/StringResponseCallback.java | 2 +- .../internal/handler/Token.java | 12 +-- .../internal/utils/Constants.java | 47 +++++++++++ .../internal/utils/Converter.java | 16 ++-- .../internal/discovery/DiscoveryTest.java | 29 ++++++- .../internal/dto/ConnectedDriveTest.java | 6 +- .../internal/dto/status/StatusWrapper.java | 5 +- .../resources/webapi/charging-profile.json | 15 +++- 26 files changed, 382 insertions(+), 159 deletions(-) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/{ConnectedDriveUserInfo.java => NetworkError.java} (55%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargeProfile.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargingWindow.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/WeeklyPlanner.java rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/{ => discovery}/Dealer.java (90%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/{ => discovery}/Vehicle.java (88%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/VehiclesContainer.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java index 894618d275960..99bd9982d7bc2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedCarConfiguration.java @@ -13,6 +13,7 @@ package org.openhab.binding.bmwconnecteddrive.internal; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; /** * The {@link ConnectedCarConfiguration} class contains fields mapping thing configuration parameters. @@ -24,7 +25,7 @@ public class ConnectedCarConfiguration { /** * Vehilce Identification Number (VIN) */ - public String vin = ""; + public String vin = Constants.EMPTY; /** * Data refresh rate in minutes diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConfiguration.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConfiguration.java index 2488bda3802f9..cf2dfb98baef0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConfiguration.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConfiguration.java @@ -13,6 +13,7 @@ package org.openhab.binding.bmwconnecteddrive.internal; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; /** * The {@link ConnectedDriveConfiguration} class contains fields mapping thing configuration parameters. @@ -25,15 +26,15 @@ public class ConnectedDriveConfiguration { /** * Depending on the location the correct server needs to be called */ - public String region = ""; + public String region = Constants.EMPTY; /** * BMW Connected Drive Username */ - public String userName = ""; + public String userName = Constants.EMPTY; /** * BMW Connected Drive Password */ - public String password = ""; + public String password = Constants.EMPTY; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java index 21a90c1fea0d0..36ba3ae4d027b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java @@ -23,9 +23,10 @@ import org.eclipse.smarthome.config.discovery.AbstractDiscoveryService; import org.eclipse.smarthome.config.discovery.DiscoveryResultBuilder; import org.eclipse.smarthome.core.thing.ThingUID; -import org.openhab.binding.bmwconnecteddrive.internal.dto.ConnectedDriveUserInfo; -import org.openhab.binding.bmwconnecteddrive.internal.dto.Vehicle; +import org.openhab.binding.bmwconnecteddrive.internal.dto.discovery.Vehicle; +import org.openhab.binding.bmwconnecteddrive.internal.dto.discovery.VehiclesContainer; import org.openhab.binding.bmwconnecteddrive.internal.handler.ConnectedDriveBridgeHandler; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,12 +50,11 @@ public ConnectedCarDiscovery(ConnectedDriveBridgeHandler bh) { @Override protected void startScan() { - // nothing to start - wait until first results of ConnectedDriveBridgeHandler results + bridgeHandler.requestVehicles(); } - public void scan(ConnectedDriveUserInfo cdui) { - List vehicles = cdui.getVehicles(); - logger.info("Discovered {} Vehicles", vehicles.size()); + public void onResponse(VehiclesContainer container) { + List vehicles = container.vehicles; vehicles.forEach(vehicle -> { ThingUID bridgeUID = bridgeHandler.getThing().getUID(); // the DriveTrain field in the delivered json is defining the Vehicle Type @@ -63,34 +63,44 @@ public void scan(ConnectedDriveUserInfo cdui) { if (entry.getId().equals(vehicleType)) { ThingUID uid = new ThingUID(entry, vehicle.vin); Map properties = new HashMap<>(); - properties.put("vin", vehicle.vin); - properties.put("refreshInterval", 5); - properties.put("model", vehicle.model); - properties.put("statisticsCommunityEnabled", vehicle.color); - properties.put("driveTrain", vehicle.driveTrain); - properties.put("brand", vehicle.brand); - properties.put("yearOfConstruction", vehicle.yearOfConstruction); - properties.put("bodytype", vehicle.bodytype); - properties.put("statisticsCommunityEnabled", vehicle.color); + // Dealer if (vehicle.dealer != null) { - properties.put("dealerName", vehicle.dealer.name); - properties.put("dealerAddress", vehicle.dealer.street + " " + vehicle.dealer.country + " " + properties.put("Dealer", vehicle.dealer.name); + properties.put("Dealer Address", vehicle.dealer.street + " " + vehicle.dealer.country + " " + vehicle.dealer.postalCode + " " + vehicle.dealer.city); - properties.put("dealerPhone", vehicle.dealer.phone); + properties.put("Dealer Phone", vehicle.dealer.phone); } - properties.put("breakdownNumber", vehicle.breakdownNumber); - StringBuffer chargingModes = new StringBuffer(); + + // Services & Support + properties.put("Services Activated", getObject(vehicle, Constants.ACTIVATED)); + properties.put("Services Supported", getObject(vehicle, Constants.SUPPORTED)); + properties.put("Services Not Supported", getObject(vehicle, Constants.NOT_SUPPORTED)); + properties.put("Support Breakdown Number", vehicle.breakdownNumber); + + // Vehicle Properties if (vehicle.supportedChargingModes != null) { + StringBuffer chargingModes = new StringBuffer(); vehicle.supportedChargingModes.forEach(e -> { - chargingModes.append(e + " "); + chargingModes.append(e).append(Constants.SPACE); }); + properties.put("Vehicle Charge Modes", chargingModes.toString()); } + properties.put("Vehicle Brand", vehicle.brand); + properties.put("Vehicle Bodytype", vehicle.bodytype); + properties.put("Vehicle Color", vehicle.color); + properties.put("Vehicle Construction Year", vehicle.yearOfConstruction); + properties.put("Vehicle Drive Train", vehicle.driveTrain); + properties.put("Vehicle Model", vehicle.model); + + // Properties needed for functional THing + properties.put("vin", vehicle.vin); + properties.put("refreshInterval", 15); + properties.put("units", "AUTODETECT"); + properties.put("imageSize", 500); + properties.put("imageViewport", "FRONT"); - properties.put("activatedServcies", getObject(vehicle, Vehicle.ACTIVATED)); - properties.put("supportedServices", getObject(vehicle, Vehicle.SUPPORTED)); - properties.put("activatedServcies", getObject(vehicle, Vehicle.NOT_SUPPORTED)); String carLabel = vehicle.brand + " " + vehicle.model; - logger.info("Thing {} discovered", carLabel); + logger.debug("Thing {} discovered", carLabel); thingDiscovered(DiscoveryResultBuilder.create(uid).withBridge(bridgeUID) .withRepresentationProperty("vin").withLabel(carLabel).withProperties(properties).build()); } @@ -105,7 +115,7 @@ public String getObject(Object obj, String compare) { try { if (field.get(obj) != null) { if (field.get(obj).equals(compare)) { - buf.append(field.getName()); + buf.append(field.getName() + Constants.SPACE); } } } catch (IllegalArgumentException e) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveUserInfo.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/NetworkError.java similarity index 55% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveUserInfo.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/NetworkError.java index 4d33963c73c25..037878ca44a5d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveUserInfo.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/NetworkError.java @@ -12,23 +12,21 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.dto; -import java.util.List; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; /** - * The {@link ConnectedDriveUserInfo} Data Transfer Object + * The {@link NetworkError} Data Transfer Object * * @author Bernd Weymann - Initial contribution */ -public class ConnectedDriveUserInfo { - // @SerializedName("sampling_rate") - // private int samplingRate; - private List vehicles; +public class NetworkError { + public String url; + public int status; + public String reason; - public List getVehicles() { - return vehicles; - } - - public void setVehicles(List vehicles) { - this.vehicles = vehicles; + @Override + public String toString() { + return new StringBuffer(url).append(Constants.HYPHEN).append(status).append(Constants.HYPHEN).append(reason) + .toString(); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargeProfile.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargeProfile.java new file mode 100644 index 0000000000000..67326b31fbdf7 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargeProfile.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.charge; + +/** + * The {@link ChargeProfile} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class ChargeProfile { + public WeeklyPlanner weeklyPlanner; +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargingWindow.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargingWindow.java new file mode 100644 index 0000000000000..cfa4ad82be67d --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargingWindow.java @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.charge; + +/** + * The {@link ChargingWindow} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class ChargingWindow { + public String startTime;// ":"11:00", + public String endTime;// ":"17:00"}} +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java new file mode 100644 index 0000000000000..07081626f5c92 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.charge; + +import java.util.List; + +/** + * The {@link Timer} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class Timer { + public String departureTime;// ": "05:00", + public boolean timerEnabled;// ": false, + public List weekdays; + /** + * "MONDAY", + * "TUESDAY", + * "WEDNESDAY", + * "THURSDAY", + * "FRIDAY" + * ] ' + */ +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/WeeklyPlanner.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/WeeklyPlanner.java new file mode 100644 index 0000000000000..b2f5359451b77 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/WeeklyPlanner.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.charge; + +/** + * The {@link WeeklyPlanner} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class WeeklyPlanner { + public boolean climatizationEnabled; // ": true, + public String chargingMode;// ": "IMMEDIATE_CHARGING", + public String chargingPreferences; // ": "CHARGING_WINDOW", + public Timer timer1; // : { + public Timer timer2;// ": { + public Timer timer3;// ":{"departureTime":"00:00","timerEnabled":false,"weekdays":[]}," + public Timer overrideTimer;// ":{"departureTime":"12:00","timerEnabled":false,"weekdays":["SATURDAY"]}," + public ChargingWindow preferredChargingWindow;// ":{"startTime":"11:00","endTime":"17:00"}} +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Dealer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Dealer.java similarity index 90% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Dealer.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Dealer.java index aadc268478661..a6c3c788bc174 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Dealer.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Dealer.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.bmwconnecteddrive.internal.dto; +package org.openhab.binding.bmwconnecteddrive.internal.dto.discovery; /** * The {@link Dealer} Data Transfer Object diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Vehicle.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Vehicle.java similarity index 88% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Vehicle.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Vehicle.java index ec0642e3b27be..e627f60e71bf0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Vehicle.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Vehicle.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.bmwconnecteddrive.internal.dto; +package org.openhab.binding.bmwconnecteddrive.internal.dto.discovery; import java.util.ArrayList; import java.util.List; @@ -21,10 +21,6 @@ * @author Bernd Weymann - Initial contribution */ public class Vehicle { - public static final String ACTIVATED = "ACTIVATED"; - public static final String SUPPORTED = "SUPPORTED"; - public static final String NOT_SUPPORTED = "NOT_SUPPORTED"; - public String vin; public String model; public String driveTrain; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/VehiclesContainer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/VehiclesContainer.java new file mode 100644 index 0000000000000..3ebe21dd79fbc --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/VehiclesContainer.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.discovery; + +import java.util.List; + +/** + * The {@link VehiclesContainer} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class VehiclesContainer { + public List vehicles; +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java index 8086b2eaaf264..e7cde7df499c5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java @@ -12,6 +12,8 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.dto.status; +import static org.openhab.binding.bmwconnecteddrive.internal.utils.Constants.*; + import java.lang.reflect.Field; import java.time.LocalDate; import java.util.List; @@ -26,16 +28,6 @@ * @author Bernd Weymann - Initial contribution */ public class VehicleStatus { - public static final String OK = "Ok"; - public static final String OPEN = "OPEN"; - public static final String INVALID = "INVALID"; - public static final String CLOSED = "CLOSED"; - public static final String UNKNOWN = "UNKOWN"; - public static final String NO_SERVICE_REQUEST = "No Service Requests"; - public static final String APPENDIX_DAY = "-01"; // needed to complete Service Date - public static final String MILES_SHORT = "mi"; - public static final String KM_SHORT = "km"; - public int mileage;// ": 17273, public float remainingFuel;// ": 4, public float remainingRangeElectric;// ": 148, diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ByteResponseCallback.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ByteResponseCallback.java index 454be8d312fcc..e83e38ec4c938 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ByteResponseCallback.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ByteResponseCallback.java @@ -17,7 +17,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; /** - * The {@link ByteResponseCallback} Interface for all Callbacks from async REST API results + * The {@link ByteResponseCallback} Interface for all raw byte results from ASYNC REST API * * @author Bernd Weymann - Initial contribution */ diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java index 29103ad8ce1b8..e4ebfa2177511 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java @@ -43,6 +43,7 @@ import org.eclipse.smarthome.io.net.http.HttpUtil; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedCarConfiguration; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CarType; +import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTrips; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTripsContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTrip; @@ -54,6 +55,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Windows; import org.openhab.binding.bmwconnecteddrive.internal.handler.RemoteServiceHandler.ExecutionState; import org.openhab.binding.bmwconnecteddrive.internal.handler.RemoteServiceHandler.RemoteService; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -107,7 +109,7 @@ public ConnectedCarHandler(Thing thing, HttpClient hc, String type, boolean impe isElectric = type.equals(CarType.PLUGIN_HYBRID.toString()) || type.equals(CarType.ELECTRIC_REX.toString()) || type.equals(CarType.ELECTRIC.toString()); isHybrid = hasFuel && isElectric; - logger.info("DriveTrain {} isElectric {} hasFuel {} Imperial {}", type, isElectric, hasFuel, imperial); + logger.debug("DriveTrain {} isElectric {} hasFuel {} Imperial {}", type, isElectric, hasFuel, imperial); } @Override @@ -371,10 +373,9 @@ public ScheduledExecutorService getScheduler() { /** * Callbacks for ConnectedDrive Portal * - * @author bernd + * @author Bernd Weymann * */ - @NonNullByDefault public class ChargeProfilesCallback implements StringResponseCallback { @Override @@ -382,9 +383,13 @@ public void onResponse(Optional content) { chargeProfileCache = content; } + /** + * Store Error Report in cache variable. Via Fingerprint Channel error is logged and Issue can be raised + */ @Override - public void onError(String reason) { - logger.debug("Unable to retrieve Charging Profile: {}", reason); + public void onError(NetworkError error) { + logger.debug("{}", error.toString()); + chargeProfileCache = Optional.of(GSON.toJson(error)); } } @@ -395,9 +400,13 @@ public void onResponse(Optional content) { rangeMapCache = content; } + /** + * Store Error Report in cache variable. Via Fingerprint Channel error is logged and Issue can be raised + */ @Override - public void onError(String reason) { - logger.debug("Unable to retrieve RangeMap: {}", reason); + public void onError(NetworkError error) { + logger.debug("{}", error.toString()); + rangeMapCache = Optional.of(GSON.toJson(error)); } } @@ -406,18 +415,17 @@ public class ImageCallback implements ByteResponseCallback { @Override public void onResponse(Optional content) { if (content.isPresent()) { - // byte[] image = content.get().getBytes(); - logger.info("Content {} {} {} {}", content.get()[0], content.get()[1], content.get()[2], - content.get()[3]); String contentType = HttpUtil.guessContentTypeFromData(content.get()); - logger.info("Image Content Type {} Size {}", contentType, content.get().length); updateState(imageChannel, new RawType(content.get(), contentType)); } } + /** + * Store Error Report in cache variable. Via Fingerprint Channel error is logged and Issue can be raised + */ @Override - public void onError(String reason) { - logger.debug("Unable to retrieve Image: {}", reason); + public void onError(NetworkError error) { + logger.debug("{}", error.toString()); } } @@ -445,11 +453,14 @@ public void onResponse(Optional content) { } } + /** + * Store Error Report in cache variable. Via Fingerprint Channel error is logged and Issue can be raised + */ @Override - public void onError(String reason) { - logger.debug("Unable to retrieve All Trips: {}", reason); + public void onError(NetworkError error) { + logger.debug("{}", error.toString()); + allTripsCache = Optional.of(GSON.toJson(error)); } - } @NonNullByDefault @@ -474,9 +485,13 @@ public void onResponse(Optional content) { } } + /** + * Store Error Report in cache variable. Via Fingerprint Channel error is logged and Issue can be raised + */ @Override - public void onError(String reason) { - logger.debug("Unable to retrieve Last Trip: {}", reason); + public void onError(NetworkError error) { + logger.debug("{}", error.toString()); + lastTripCache = Optional.of(GSON.toJson(error)); } } @@ -487,9 +502,16 @@ public void onError(String reason) { public class VehicleStatusCallback implements StringResponseCallback { private ThingStatus thingStatus = ThingStatus.UNKNOWN; + /** + * Vehicle Satus is supported by all cars so callback result is used to report Thing Status. + * If valid content is delivered in onResponse Thing goes online while onError Thing goes offline + * + * @param status + * @param detail + * @param reason + */ private void setThingStatus(ThingStatus status, ThingStatusDetail detail, String reason) { if (thingStatus != status) { - // STatus is supported by all cars so callback is used to report ONLINE state updateStatus(status, detail, reason); } } @@ -497,8 +519,8 @@ private void setThingStatus(ThingStatus status, ThingStatusDetail detail, String @Override public void onResponse(Optional content) { if (content.isPresent()) { + setThingStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE, Constants.EMPTY); vehicleStatusCache = content; - logger.info("Content: {}", content.get()); VehicleStatusContainer status = GSON.fromJson(content.get(), VehicleStatusContainer.class); VehicleStatus vStatus = status.vehicleStatus; if (vStatus == null) { @@ -524,17 +546,11 @@ public void onResponse(Optional content) { totalRange += vStatus.remainingRangeElectric; updateState(remainingRangeElectric, QuantityType.valueOf(vStatus.remainingRangeElectric, MetricPrefix.KILO(SIUnits.METRE))); - logger.info("updated {} {}", remainingRangeElectric, vStatus.remainingRangeElectric); - } else { - logger.info("{} not updated", remainingRangeElectric); } if (hasFuel) { totalRange += vStatus.remainingRangeFuel; updateState(remainingRangeFuel, QuantityType.valueOf(vStatus.remainingRangeFuel, MetricPrefix.KILO(SIUnits.METRE))); - logger.info("updated {} {}", remainingRangeFuel, vStatus.remainingRangeFuel); - } else { - logger.info("{} not updated", remainingRangeFuel); } if (isHybrid) { updateState(remainingRangeHybrid, @@ -558,7 +574,7 @@ public void onResponse(Optional content) { updateState(remainingRangeHybrid, QuantityType.valueOf(Converter.round(totalRange), ImperialUnits.MILE)); } - updateState(rangeRadius, new DecimalType((totalRange) * Converter.MILES_TO_FEET_FACTOR)); + updateState(rangeRadius, new DecimalType((totalRange) * Constants.MILES_TO_FEET_FACTOR)); } if (isElectric) { updateState(remainingSoc, QuantityType.valueOf(vStatus.chargingLevelHv, SmartHomeUnits.PERCENT)); @@ -583,10 +599,10 @@ public void onResponse(Optional content) { } @Override - public void onError(String reason) { - logger.debug("Unable to retrieve Vehicle Status {}", reason); - setThingStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, reason); + public void onError(NetworkError error) { + logger.debug("{}", error.toString()); + vehicleStatusCache = Optional.of(GSON.toJson(error)); + setThingStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, error.reason); } - } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java index efc282b433963..fa550d5ef6e76 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java @@ -30,8 +30,9 @@ import org.eclipse.smarthome.core.types.Command; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConfiguration; import org.openhab.binding.bmwconnecteddrive.internal.discovery.ConnectedCarDiscovery; -import org.openhab.binding.bmwconnecteddrive.internal.dto.ConnectedDriveUserInfo; -import org.openhab.binding.bmwconnecteddrive.internal.dto.Dealer; +import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; +import org.openhab.binding.bmwconnecteddrive.internal.dto.discovery.Dealer; +import org.openhab.binding.bmwconnecteddrive.internal.dto.discovery.VehiclesContainer; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.slf4j.Logger; @@ -51,8 +52,8 @@ public class ConnectedDriveBridgeHandler extends BaseBridgeHandler implements St private static final Gson GSON = new Gson(); private HttpClient httpClient; private BundleContext bundleContext; - private ServiceRegistration discoveryServiceRegstration; private ConnectedCarDiscovery discoveryService; + private ServiceRegistration discoveryServiceRegstration; private Optional proxy = Optional.empty(); private Optional configuration = Optional.empty(); private Optional> refreshJob = Optional.empty(); @@ -74,9 +75,9 @@ public ConnectedDriveBridgeHandler(Bridge bridge, HttpClient hc, BundleContext b @Override public void handleCommand(ChannelUID channelUID, Command command) { - if (channelUID.getIdWithoutGroup().equals(DISCOVERY_FINGERPRINT)) { - if (command instanceof OnOffType) { - if (command.equals(OnOffType.ON)) { + if (command instanceof OnOffType) { + if (command.equals(OnOffType.ON)) { + if (channelUID.getIdWithoutGroup().equals(DISCOVERY_FINGERPRINT)) { if (troubleshootFingerprint.isPresent()) { logger.warn("BMW ConnectedDrive Binding - Discovery Troubleshoot fingerprint - BEGIN"); logger.warn("{}", troubleshootFingerprint.get()); @@ -85,21 +86,17 @@ public void handleCommand(ChannelUID channelUID, Command command) { logger.warn( "BMW ConnectedDrive Binding - No Discovery Troubleshoot fingerprint available. Please check for valid username and password Settings for proper connection towards ConnectDrive"); } - } - // Switch back to off immediately - updateState(discoveryfingerPrint, OnOffType.OFF); - } - } else if (channelUID.getIdWithoutGroup().equals(DISCOVERY_TRIGGER)) { - if (command instanceof OnOffType) { - if (command.equals(OnOffType.ON)) { + // Switch back to off immediately + updateState(discoveryfingerPrint, OnOffType.OFF); + } else if (channelUID.getIdWithoutGroup().equals(DISCOVERY_TRIGGER)) { // trigger discovery again - helpful after the user performed some changes in the ConnectedDrive // Portal and wants to get the changes if (proxy.isPresent()) { proxy.get().requestVehicles(this); } + // Switch back to off immediately + updateState(discoveryTrigger, OnOffType.OFF); } - // Switch back to off immediately - updateState(discoveryTrigger, OnOffType.OFF); } } } @@ -110,9 +107,7 @@ public void initialize() { configuration = Optional.of(getConfigAs(ConnectedDriveConfiguration.class)); if (configuration.isPresent()) { proxy = Optional.of(new ConnectedDriveProxy(httpClient, configuration.get())); - if (proxy.isPresent()) { - proxy.get().requestVehicles(this); - } + proxy.get().requestVehicles(this); } else { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR); } @@ -127,20 +122,26 @@ public void dispose() { } } + public void requestVehicles() { + if (proxy.isPresent()) { + proxy.get().requestVehicles(this); + } + } + /** * There's only the Vehicles response available */ @Override public void onResponse(Optional response) { if (response.isPresent()) { - ConnectedDriveUserInfo userInfo = GSON.fromJson(response.get(), ConnectedDriveUserInfo.class); - discoveryService.scan(userInfo); + VehiclesContainer container = GSON.fromJson(response.get(), VehiclesContainer.class); + discoveryService.onResponse(container); updateStatus(ThingStatus.ONLINE); - if (userInfo.getVehicles() != null) { - if (userInfo.getVehicles().isEmpty()) { + if (container.vehicles != null) { + if (container.vehicles.isEmpty()) { troubleshootFingerprint = Optional.of("No Cars found in your ConnectedDrive Account"); } else { - userInfo.getVehicles().forEach(entry -> { + container.vehicles.forEach(entry -> { entry.vin = ANONYMOUS; entry.breakdownNumber = ANONYMOUS; if (entry.dealer != null) { @@ -153,7 +154,7 @@ public void onResponse(Optional response) { d.street = ANONYMOUS; } }); - troubleshootFingerprint = Optional.of(GSON.toJson(userInfo)); + troubleshootFingerprint = Optional.of(GSON.toJson(container)); } } } else { @@ -162,8 +163,8 @@ public void onResponse(Optional response) { } @Override - public void onError(String reason) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, reason); + public void onError(NetworkError error) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, error.reason); } public Optional getProxy() { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index 7bfcaac0bbe5e..81fde4d786c2f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -34,6 +34,7 @@ import org.eclipse.jetty.util.UrlEncoded; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedCarConfiguration; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConfiguration; +import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; import org.openhab.binding.bmwconnecteddrive.internal.utils.BimmerConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -108,12 +109,13 @@ public void request(String url, Optional> params, ResponseCallb @Override public void onComplete(org.eclipse.jetty.client.api.Result result) { if (result.getResponse().getStatus() != 200) { - logger.warn("Call URL {}", url.toString()); - logger.warn("Return Status {}", result.getResponse().getStatus()); - logger.warn("Reason {}", result.getResponse().getReason()); - callback.onError(result.getResponse().getReason()); + NetworkError error = new NetworkError(); + error.url = url; + error.status = result.getResponse().getStatus(); + error.reason = result.getResponse().getReason(); + logger.warn("{}", error.toString()); + callback.onError(error); } else { - logger.warn("Call URL {} success", url.toString()); if (callback instanceof StringResponseCallback) { ((StringResponseCallback) callback).onResponse(Optional.of(getContentAsString())); } else { @@ -203,12 +205,12 @@ public Token getToken() { } /** - * Authorize at BMW Connected Drive Portal and re + * Authorize at BMW Connected Drive Portal and get Token * * @return */ public Token getNewToken() { - http.setFollowRedirects(false); + // http.setFollowRedirects(false); Request req = http.POST(authUri); req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); @@ -244,11 +246,9 @@ public Token getTokenFromUrl(String encodedUrl) { UrlEncoded.decodeTo(encodedUrl, tokenMap, StandardCharsets.US_ASCII); final Token token = new Token(); tokenMap.forEach((key, value) -> { - logger.info("Key {} Value {}", key, value); if (key.endsWith(ACCESS_TOKEN)) { token.setToken(value.get(0).toString()); } else if (key.equals(EXPIRES_IN)) { - logger.info("Expires {}", value.get(0).toString()); token.setExpiration(Integer.parseInt(value.get(0).toString())); } else if (key.equals(TOKEN_TYPE)) { token.setType(value.get(0).toString()); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java index a051eb660f900..3f9e22accf595 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -157,15 +157,18 @@ boolean execute(RemoteService service) { } public void getState() { - if (serviceExecuting == null) { + if (!serviceExecuting.isPresent()) { logger.warn("No Service executed to get state"); return; } if (counter >= giveUpCounter) { logger.warn("Giving up updating state for {} after {} times", serviceExecuting, giveUpCounter); + reset(); + // immediately refresh data + handler.getData(); } counter++; - Request req = httpClient.newRequest(serviceExecutionStateAPI + serviceExecuting); + Request req = httpClient.newRequest(serviceExecutionStateAPI + serviceExecuting.get()); req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); req.header(HttpHeader.AUTHORIZATION, proxy.getToken().getBearerToken()); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ResponseCallback.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ResponseCallback.java index e44ec8e632e2d..798cccbc083ea 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ResponseCallback.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ResponseCallback.java @@ -13,13 +13,14 @@ package org.openhab.binding.bmwconnecteddrive.internal.handler; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; /** - * The {@link ResponseCallback} Marker Interface for all callbacks + * The {@link ResponseCallback} Marker Interface for all ASYNC REST API callbacks * * @author Bernd Weymann - Initial contribution */ @NonNullByDefault public interface ResponseCallback { - public void onError(String reason); + public void onError(NetworkError error); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/StringResponseCallback.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/StringResponseCallback.java index f8a3cec2257ae..1ef5f23ce0207 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/StringResponseCallback.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/StringResponseCallback.java @@ -17,7 +17,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; /** - * The {@link StringResponseCallback} Interface for all Callbacks from async REST API results + * The {@link StringResponseCallback} Interface for all String results from ASYNC REST API * * @author Bernd Weymann - Initial contribution */ diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java index 91b769ce37b71..b18391af78631 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java @@ -13,21 +13,21 @@ package org.openhab.binding.bmwconnecteddrive.internal.handler; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; /** - * The {@link Token} class contains fields mapping thing configuration parameters. + * The {@link Token} BMW ConnectedDrive Token storage * * @author Bernd Weymann - Initial contribution */ @NonNullByDefault public class Token { - private static final String EMPTY = ""; - private String token = EMPTY; - private String tokenType = EMPTY; + private String token = Constants.EMPTY; + private String tokenType = Constants.EMPTY; private long expiration = 0; public String getBearerToken() { - return tokenType + " " + token; + return new StringBuffer(tokenType).append(Constants.SPACE).append(token).toString(); } public void setToken(String token) { @@ -47,6 +47,6 @@ public void setType(String type) { } public boolean isValid() { - return (!token.equals(EMPTY) && !tokenType.equals(EMPTY) && expiration > 0); + return (!token.equals(Constants.EMPTY) && !tokenType.equals(Constants.EMPTY) && expiration > 0); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java new file mode 100644 index 0000000000000..8c438d0bd7536 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.utils; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link Constants} General Constant Definitions + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class Constants { + // For Vehicle Status + public static final String OK = "Ok"; + public static final String OPEN = "OPEN"; + public static final String INVALID = "INVALID"; + public static final String CLOSED = "CLOSED"; + public static final String UNKNOWN = "UNKOWN"; + public static final String NO_SERVICE_REQUEST = "No Service Requests"; + public static final String APPENDIX_DAY = "-01"; // needed to complete Service Date + public static final String MILES_SHORT = "mi"; + public static final String KM_SHORT = "km"; + + // Services in Discovery + public static final String ACTIVATED = "ACTIVATED"; + public static final String SUPPORTED = "SUPPORTED"; + public static final String NOT_SUPPORTED = "NOT_SUPPORTED"; + + // General Constants for String concatenation + public static final String SPACE = " "; + public static final String UNDERLINE = "_"; + public static final String HYPHEN = " - "; + public static final String EMPTY = ""; + + public static final int MILES_TO_FEET_FACTOR = 5280; +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java index dae8f13d4f9b7..8984d8523a873 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java @@ -18,7 +18,6 @@ import java.time.format.DateTimeFormatter; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; /** * The {@link Converter} Data Transfer Object @@ -30,16 +29,11 @@ public class Converter { public static final DateTimeFormatter SERVICE_DATE_INPUT_PATTERN = DateTimeFormatter.ofPattern("yyyy-MM-dd"); public static final DateTimeFormatter SERVICE_DATE_OUTPUT_PATTERN = DateTimeFormatter.ofPattern("MMM yyyy"); - public static final String SPACE = " "; - public static final String UNDERLINE = "_"; - public static final DateTimeFormatter DATE_INPUT_PATTERN = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); public static final DateTimeFormatter DATE_TIMEZONE_INPUT_PATTERN = DateTimeFormatter .ofPattern("yyyy-MM-dd'T'HH:mm:ssZ"); private static final DateTimeFormatter DATE_OUTPUT_PATTERN = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); - public static final int MILES_TO_FEET_FACTOR = 5280; - public static double round(double value) { double scale = Math.pow(10, 1); return Math.round(value * scale) / scale; @@ -47,7 +41,7 @@ public static double round(double value) { public static String getLocalDateTime(String input) { if (input == null) { - return Converter.toTitleCase(VehicleStatus.UNKNOWN); + return Converter.toTitleCase(Constants.UNKNOWN); } LocalDateTime ldt = LocalDateTime.parse(input, Converter.DATE_INPUT_PATTERN); @@ -58,7 +52,7 @@ public static String getLocalDateTime(String input) { public static String getZonedDateTime(String input) { if (input == null) { - return Converter.toTitleCase(VehicleStatus.UNKNOWN); + return Converter.toTitleCase(Constants.UNKNOWN); } ZonedDateTime zdt = ZonedDateTime.parse(input, Converter.DATE_TIMEZONE_INPUT_PATTERN); @@ -68,10 +62,10 @@ public static String getZonedDateTime(String input) { public static String toTitleCase(String input) { if (input == null) { - return Converter.toTitleCase(VehicleStatus.UNKNOWN); + return Converter.toTitleCase(Constants.UNKNOWN); } else { - String lower = input.replaceAll(UNDERLINE, SPACE).toLowerCase(); - String[] arr = lower.split(SPACE); + String lower = input.replaceAll(Constants.UNDERLINE, Constants.SPACE).toLowerCase(); + String[] arr = lower.split(Constants.SPACE); StringBuffer sb = new StringBuffer(); for (int i = 0; i < arr.length; i++) { sb.append(Character.toUpperCase(arr[i].charAt(0))).append(arr[i].substring(1)).append(" "); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java index 2636c418da5c7..f04c34155fe93 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java @@ -24,7 +24,7 @@ import org.eclipse.smarthome.core.thing.ThingUID; import org.junit.Test; import org.mockito.ArgumentCaptor; -import org.openhab.binding.bmwconnecteddrive.internal.dto.ConnectedDriveUserInfo; +import org.openhab.binding.bmwconnecteddrive.internal.dto.discovery.VehiclesContainer; import org.openhab.binding.bmwconnecteddrive.internal.handler.ConnectedDriveBridgeHandler; import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; import org.slf4j.Logger; @@ -44,6 +44,28 @@ public class DiscoveryTest { @Test public void testDiscovery() { + String content = FileReader.readFileInString("src/test/resources/webapi/connected-drive-account-info.json"); + ConnectedDriveBridgeHandler bh = mock(ConnectedDriveBridgeHandler.class); + Bridge b = mock(Bridge.class); + when(bh.getThing()).thenReturn(b); + when(b.getUID()).thenReturn(new ThingUID("testbinding", "test")); + ConnectedCarDiscovery discovery = new ConnectedCarDiscovery(bh); + DiscoveryListener listener = mock(DiscoveryListener.class); + discovery.addDiscoveryListener(listener); + VehiclesContainer container = GSON.fromJson(content, VehiclesContainer.class); + ArgumentCaptor discoveries = ArgumentCaptor.forClass(DiscoveryResult.class); + ArgumentCaptor services = ArgumentCaptor.forClass(DiscoveryService.class); + + discovery.onResponse(container); + verify(listener, times(1)).thingDiscovered(services.capture(), discoveries.capture()); + List results = discoveries.getAllValues(); + results.forEach(entry -> { + logger.info("{}", entry.toString()); + }); + } + + @Test + public void testBimmerDiscovery() { String content = FileReader.readFileInString("src/test/resources/responses/vehicles.json"); ConnectedDriveBridgeHandler bh = mock(ConnectedDriveBridgeHandler.class); Bridge b = mock(Bridge.class); @@ -52,16 +74,15 @@ public void testDiscovery() { ConnectedCarDiscovery discovery = new ConnectedCarDiscovery(bh); DiscoveryListener listener = mock(DiscoveryListener.class); discovery.addDiscoveryListener(listener); - ConnectedDriveUserInfo cdui = GSON.fromJson(content, ConnectedDriveUserInfo.class); + VehiclesContainer container = GSON.fromJson(content, VehiclesContainer.class); ArgumentCaptor discoveries = ArgumentCaptor.forClass(DiscoveryResult.class); ArgumentCaptor services = ArgumentCaptor.forClass(DiscoveryService.class); - discovery.scan(cdui); + discovery.onResponse(container); verify(listener, times(8)).thingDiscovered(services.capture(), discoveries.capture()); List results = discoveries.getAllValues(); results.forEach(entry -> { logger.info("{}", entry.toString()); }); } - } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java index e8f3353da20a2..c08eb658979d5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java @@ -19,6 +19,8 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.smarthome.core.thing.ThingTypeUID; import org.junit.Test; +import org.openhab.binding.bmwconnecteddrive.internal.dto.discovery.Vehicle; +import org.openhab.binding.bmwconnecteddrive.internal.dto.discovery.VehiclesContainer; import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; import com.google.gson.Gson; @@ -35,8 +37,8 @@ public class ConnectedDriveTest { @Test public void testUserInfo() { String resource1 = FileReader.readFileInString("src/test/resources/webapi/connected-drive-account-info.json"); - ConnectedDriveUserInfo userInfo = GSON.fromJson(resource1, ConnectedDriveUserInfo.class); - List vehicles = userInfo.getVehicles(); + VehiclesContainer container = GSON.fromJson(resource1, VehiclesContainer.class); + List vehicles = container.vehicles; assertEquals("Number of Vehicles", 1, vehicles.size()); Vehicle v = vehicles.get(0); // assertEquals("VIN", "WBY1Z81040V905639", v.getVin()); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/StatusWrapper.java index 423f7a7331e29..c0c2d9b132970 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/StatusWrapper.java @@ -31,6 +31,7 @@ import org.eclipse.smarthome.core.thing.ChannelUID; import org.eclipse.smarthome.core.types.State; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CarType; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import com.google.gson.Gson; @@ -222,10 +223,10 @@ private void checkResult(ChannelUID channelUID, State state) { int totalRange = 0; if (imperial) { if (isElectric) { - totalRange += vStatus.remainingRangeElectricMls * Converter.MILES_TO_FEET_FACTOR; + totalRange += vStatus.remainingRangeElectricMls * Constants.MILES_TO_FEET_FACTOR; } if (hasFuel) { - totalRange += vStatus.remainingRangeFuelMls * Converter.MILES_TO_FEET_FACTOR; + totalRange += vStatus.remainingRangeFuelMls * Constants.MILES_TO_FEET_FACTOR; } } else { if (isElectric) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/charging-profile.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/charging-profile.json index 04dee7537f6b2..840559b6cf134 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/charging-profile.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/charging-profile.json @@ -1,6 +1,6 @@ { "weeklyPlanner": { - "climatizationEnabled": false, + "climatizationEnabled": true, "chargingMode": "IMMEDIATE_CHARGING", "chargingPreferences": "CHARGING_WINDOW", "timer1": { @@ -16,7 +16,7 @@ }, "timer2": { "departureTime": "12:00", - "timerEnabled": false, + "timerEnabled": true, "weekdays": [ "SATURDAY" ] @@ -26,9 +26,16 @@ "timerEnabled": false, "weekdays": [] }, + "overrideTimer": { + "departureTime": "12:00", + "timerEnabled": false, + "weekdays": [ + "SATURDAY" + ] + }, "preferredChargingWindow": { - "startTime": "00:00", - "endTime": "00:00" + "startTime": "11:00", + "endTime": "17:00" } } } \ No newline at end of file From 1cfba137c5275811276b380a1be9bb272fab4e84 Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 1 Sep 2020 22:29:03 +0200 Subject: [PATCH 015/176] discovery optimization Signed-off-by: Bernd (cherry picked from commit 000f413bdef80b792cb26ae209c41bfe07d22343) Signed-off-by: Bernd --- .../api/vehicle/BevRexAttributes.java | 93 ------------------- .../efficiency/CharacterristicsScore.java | 42 --------- .../obsolete/efficiency/Efficiency.java | 30 ------ .../obsolete/efficiency/Score.java | 59 ------------ .../obsolete/efficiency/TripEntry.java | 57 ------------ .../obsolete/test.json | 0 .../internal/ConnectedDriveConstants.java | 10 +- .../ConnectedDriveHandlerFactory.java | 16 +++- .../discovery/ConnectedCarDiscovery.java | 58 +++++++++--- .../internal/handler/ConnectedCarHandler.java | 16 ++-- .../handler/ConnectedDriveBridgeHandler.java | 15 +-- .../internal/handler/ConnectedDriveProxy.java | 11 ++- .../internal/utils/Constants.java | 1 + .../internal/utils/Converter.java | 4 + .../ESH-INF/thing/bridge-connected-drive.xml | 1 - 15 files changed, 87 insertions(+), 326 deletions(-) delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/obsolete/api/vehicle/BevRexAttributes.java delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/CharacterristicsScore.java delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/Efficiency.java delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/Score.java delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/TripEntry.java delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/obsolete/test.json diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/api/vehicle/BevRexAttributes.java b/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/api/vehicle/BevRexAttributes.java deleted file mode 100644 index 22364473d2730..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/api/vehicle/BevRexAttributes.java +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; - -import java.util.List; - -/** - * The {@link BevRexAttributes} Data Transfer Object - * - * @author Bernd Weymann - Initial contribution - */ -public class BevRexAttributes { - public String unitOfLength; - public float mileage; // "17236", - public float beMaxRangeElectricKm; // "209.0", - public float beRemainingRangeElectric; // "179.0", - public float beRemainingRangeElectricKm; // "179.0", - public float beRemainingRangeFuelMile; // "41.0", - public float beRemainingRangeFuel; // "67.0", - public float beMaxRangeElectricMile; // "129.0", - public float beRemainingRangeElectricMile; // "111.0", - public float beRemainingRangeFuelKm; // "67.0", - public float kombi_current_remaining_range_fuel; // "67.0", - public float soc_hv_percent; // "82.6", - public float chargingLevelHv; // "89.0", - public float fuelPercent; // "47", - public float remaining_fuel; // "4", - - public String sunroof_state; // : "CLOSED" - public String chargingLogicCurrentlyActive;// ; // "NOT_CHARGING", - public int vehicle_tracking; // ; // "1", - public String updateTime_converted; // "22.08.2020 13:55", - public String door_driver_rear; // "CLOSED", - public String head_unit_pu_software; // "07/16", - public String door_passenger_rear; // "CLOSED", - public String door_driver_front; // "CLOSED", - public String shdStatusUnified; // "CLOSED", - public String hood_state; // "CLOSED", - public String charging_status; // "NOCHARGING", - public String beMaxRangeElectric; // "209.0", - public String window_driver_rear; // "CLOSED", - public String lastChargingEndResult; // "SUCCESS", - public String check_control_messages; // "", - public String unitOfEnergy; // "kWh", - public int sunroof_position; // "0", - public String single_immediate_charging; // "isUnused", - public String updateTime_converted_time; // "13:55", - public String chargingHVStatus; // "INVALID", - public String connectorStatus; // "DISCONNECTED", - public String chargingSystemStatus; // "NOCHARGING", - public String unitOfCombustionConsumption; // "l/100km", - public String window_driver_front; // "CLOSED", - public String Segment_LastTrip_ratio_electric_driven_distance; // "100", - public String condition_based_services; // "00003,OK,2021-11,;00017,OK,2021-11,;00001,OK,2021-11,;00032,OK,2021-11,", - public String window_passenger_front; // "CLOSED", - public String window_passenger_rear; // "CLOSED", - public String lastChargingEndReason; // "CHARGING_GOAL_REACHED", - public String updateTime_converted_date; // "22.08.2020", - public String door_passenger_front; // "CLOSED", - public String updateTime_converted_timestamp; // "1598104546000", - public String charging_inductive_positioning; // "not_positioned", - public String lsc_trigger; // "VEHCSHUTDOWN_SECURED", - public String lights_parking; // "OFF", - public String door_lock_state; // "SECURED", - public String updateTime; // "22.08.2020 12:55:46 UTC", - public String prognosisWhileChargingStatus; // "NOT_NEEDED", - public String head_unit; // "EntryNav", - public String trunk_state; // "CLOSED", - public int battery_size_max; // "33200", - public String charging_connection_type; // "CONDUCTIVE", - public String unitOfElectricConsumption; // "kWh/100km", - public String lastUpdateReason; // ": "VEHCSHUTDOWN_SECURED" - public List vehicleMessages; - - public float gps_lat; // "50.556164", - public float gps_lng; // "8.495482", - public float heading; // "41", - - public String Segment_LastTrip_time_segment_end_formatted; // "22.08.2020 14:52", - public String Segment_LastTrip_time_segment_end; // "22.08.2020 14:52:00 UTC", - public String Segment_LastTrip_time_segment_end_formatted_date; // "22.08.2020", - public String Segment_LastTrip_time_segment_end_formatted_time; // "14:52", -} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/CharacterristicsScore.java b/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/CharacterristicsScore.java deleted file mode 100644 index c2c1a70d555b1..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/CharacterristicsScore.java +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.efficiency; - -/** - * The {@link CharacterristicsScore} Data Transfer Object - * - * @author Bernd Weymann - Initial contribution - */ -public class CharacterristicsScore { - public String characteristic; - public int quantity; - // "characteristic": "TOTAL_CONSUMPTION", - // "quantity": 2 - // }, - // { - // "characteristic": "AUXILIARY_CONSUMPTION", - // "quantity": 2 - // }, - // { - // "characteristic": "DRIVING_MODE", - // "quantity": 0 - // }, - // { - // "characteristic": "ACCELERATION", - // "quantity": 3 - // }, - // { - // "characteristic": "ANTICIPATION", - // "quantity": 3 - // } -} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/Efficiency.java b/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/Efficiency.java deleted file mode 100644 index 0436fbbdbe955..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/Efficiency.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.efficiency; - -import java.util.List; - -/** - * The {@link Efficiency} Data Transfer Object - * - * @author Bernd Weymann - Initial contribution - */ -public class Efficiency { - public boolean communitySwitch;// ": false, - public String modelType; // ": "I3"," - public int efficiencyQuotient; // ": 44, - public List lifeTimeList; // ": [], - public List scoreList; - public List lastTripList; - public List characteristicList; -} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/Score.java b/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/Score.java deleted file mode 100644 index ad9f7f8a67c61..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/Score.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.efficiency; - -/** - * The {@link Score} Data Transfer Object - * - * @author Bernd Weymann - Initial contribution - */ -public class Score { - public final static String AVERAGE_ELECTRIC_CONSUMPTION = "AVERAGE_ELECTRIC_CONSUMPTION"; - public final static String AVERAGE_RECUPERATED_ENERGY_PER_100_KM = "AVERAGE_RECUPERATED_ENERGY_PER_100_KM"; - public final static String CUMULATED_ELECTRIC_DRIVEN_DISTANCE = "CUMULATED_ELECTRIC_DRIVEN_DISTANCE"; - public final static String LONGEST_DISTANCE_WITHOUT_CHARGING = "LONGEST_DISTANCE_WITHOUT_CHARGING"; - - public String attrName; - public String attrUnit; - public float minValue; - public float maxValue; - public float lifeTime; - // { - // "attrName": "AVERAGE_ELECTRIC_CONSUMPTION", - // "attrUnit": "KWH_PER_100KM", - // "minValue": 0.0, - // "maxValue": 40.0, - // "lifeTime": 16.5 - // }, - // { - // "attrName": "AVERAGE_RECUPERATED_ENERGY_PER_100_KM", - // "attrUnit": "KWH_PER_100KM", - // "minValue": 0.0, - // "maxValue": 20.0, - // "lifeTime": 4.5 - // }, - // { - // "attrName": "CUMULATED_ELECTRIC_DRIVEN_DISTANCE", - // "attrUnit": "KM", - // "minValue": 0.0, - // "maxValue": 16593.4, - // "lifeTime": 16592.4 - // }, - // { - // "attrName": "LONGEST_DISTANCE_WITHOUT_CHARGING", - // "attrUnit": "KM", - // "minValue": 0.0, - // "maxValue": 270.0, - // "lifeTime": 185.5 - // }], -} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/TripEntry.java b/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/TripEntry.java deleted file mode 100644 index 1faec732525be..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/efficiency/TripEntry.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.efficiency; - -/** - * The {@link TripEntry} Data Transfer Object - * - * @author Bernd Weymann - Initial contribution - */ -public class TripEntry { - public final static String LASTTRIP_DELTA_KM = "LASTTRIP_DELTA_KM"; - public final static String ACTUAL_DISTANCE_WITHOUT_CHARGING = "ACTUAL_DISTANCE_WITHOUT_CHARGING"; - public final static String AVERAGE_ELECTRIC_CONSUMPTION = "AVERAGE_ELECTRIC_CONSUMPTION"; - public final static String AVERAGE_RECUPERATED_ENERGY_PER_100_KM = "AVERAGE_RECUPERATED_ENERGY_PER_100_KM"; - public final static String CUMULATED_ELECTRIC_DRIVEN_DISTANCE = "CUMULATED_ELECTRIC_DRIVEN_DISTANCE"; - - public String name; - public String unit; - public float lastTrip; - // "lastTripList": [ - // { - // "name": "LASTTRIP_DELTA_KM", - // "unit": "KM", - // "lastTrip": "2.0" - // }, - // { - // "name": "ACTUAL_DISTANCE_WITHOUT_CHARGING", - // "unit": "KM", - // "lastTrip": "31.0" - // }, - // { - // "name": "AVERAGE_ELECTRIC_CONSUMPTION", - // "unit": "KWH_PER_100KM", - // "lastTrip": "14.5" - // }, - // { - // "name": "AVERAGE_RECUPERATED_ENERGY_PER_100_KM", - // "unit": "KWH_PER_100KM", - // "lastTrip": "8.0" - // }, - // { - // "name": "CUMULATED_ELECTRIC_DRIVEN_DISTANCE", - // "unit": "KM", - // "lastTrip": "16592.4" - // } - // ], -} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/test.json b/bundles/org.openhab.binding.bmwconnecteddrive/obsolete/test.json deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index cd90210665ab7..04a99aa47b069 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -29,8 +29,6 @@ public class ConnectedDriveConstants { private static final String BINDING_ID = "bmwconnecteddrive"; - public static final String ANONYMOUS = "ANONYMOUS"; - // Units public static final String UNITS_AUTODETECT = "AUTODETECT"; public static final String UNITS_IMPERIAL = "IMPERIAL"; @@ -95,10 +93,8 @@ public String toString() { } }; - // Bridge Channels - public static final String DISCOVERY_TRIGGER = "discovery-trigger"; + // Bridge Channel public static final String DISCOVERY_FINGERPRINT = "discovery-fingerprint"; - public static final String CARDATA_FINGERPRINT = "cardata-fingerprint"; // Thing Group definitions public static final String CHANNEL_GROUP_STATUS = "status"; @@ -176,4 +172,8 @@ public String toString() { public static final String REMOTE_SERVICE_HORN = "horn"; public static final String REMOTE_SERVICE_AIR_CONDITIONING = "climate"; public static final String REMOTE_STATE = "state"; + + // Troubleshoot + public static final String CARDATA_FINGERPRINT = "cardata-fingerprint"; + } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java index 7dd503ffa8a02..ca90436596a0b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java @@ -14,6 +14,9 @@ import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.smarthome.core.i18n.LocaleProvider; @@ -41,6 +44,7 @@ public class ConnectedDriveHandlerFactory extends BaseThingHandlerFactory { private final HttpClientFactory httpClientFactory; + private static final List CARHANDLER_REGISTRY = new ArrayList(); private boolean imperial = false; @Activate @@ -61,8 +65,10 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { return new ConnectedDriveBridgeHandler((Bridge) thing, httpClientFactory.getCommonHttpClient(), bundleContext); } else if (SUPPORTED_THING_SET.contains(thingTypeUID)) { - return new ConnectedCarHandler(thing, httpClientFactory.getCommonHttpClient(), thingTypeUID.getId(), - imperial); + ConnectedCarHandler cch = new ConnectedCarHandler(thing, httpClientFactory.getCommonHttpClient(), + thingTypeUID.getId(), imperial); + CARHANDLER_REGISTRY.add(cch); + return cch; } return null; } @@ -72,6 +78,12 @@ protected void removeHandler(ThingHandler thingHandler) { if (thingHandler instanceof ConnectedDriveBridgeHandler) { // close Handler and remove Discovery Service ((ConnectedDriveBridgeHandler) thingHandler).close(); + } else { + CARHANDLER_REGISTRY.remove(thingHandler); } } + + public static List getHandlerRegistry() { + return CARHANDLER_REGISTRY; + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java index 36ba3ae4d027b..b67992894abfc 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java @@ -18,15 +18,21 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.smarthome.config.core.Configuration; import org.eclipse.smarthome.config.discovery.AbstractDiscoveryService; import org.eclipse.smarthome.config.discovery.DiscoveryResultBuilder; +import org.eclipse.smarthome.core.thing.Thing; import org.eclipse.smarthome.core.thing.ThingUID; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveHandlerFactory; import org.openhab.binding.bmwconnecteddrive.internal.dto.discovery.Vehicle; import org.openhab.binding.bmwconnecteddrive.internal.dto.discovery.VehiclesContainer; +import org.openhab.binding.bmwconnecteddrive.internal.handler.ConnectedCarHandler; import org.openhab.binding.bmwconnecteddrive.internal.handler.ConnectedDriveBridgeHandler; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -62,7 +68,7 @@ public void onResponse(VehiclesContainer container) { SUPPORTED_THING_SET.forEach(entry -> { if (entry.getId().equals(vehicleType)) { ThingUID uid = new ThingUID(entry, vehicle.vin); - Map properties = new HashMap<>(); + Map properties = new HashMap<>(); // Dealer if (vehicle.dealer != null) { properties.put("Dealer", vehicle.dealer.name); @@ -88,25 +94,49 @@ public void onResponse(VehiclesContainer container) { properties.put("Vehicle Brand", vehicle.brand); properties.put("Vehicle Bodytype", vehicle.bodytype); properties.put("Vehicle Color", vehicle.color); - properties.put("Vehicle Construction Year", vehicle.yearOfConstruction); + properties.put("Vehicle Construction Year", Short.toString(vehicle.yearOfConstruction)); properties.put("Vehicle Drive Train", vehicle.driveTrain); properties.put("Vehicle Model", vehicle.model); - // Properties needed for functional THing - properties.put("vin", vehicle.vin); - properties.put("refreshInterval", 15); - properties.put("units", "AUTODETECT"); - properties.put("imageSize", 500); - properties.put("imageViewport", "FRONT"); - - String carLabel = vehicle.brand + " " + vehicle.model; - logger.debug("Thing {} discovered", carLabel); - thingDiscovered(DiscoveryResultBuilder.create(uid).withBridge(bridgeUID) - .withRepresentationProperty("vin").withLabel(carLabel).withProperties(properties).build()); + // Check now if a thing with the same VIN exists + final AtomicBoolean foundVehicle = new AtomicBoolean(false); + List l = ConnectedDriveHandlerFactory.getHandlerRegistry(); + logger.debug("Handler regsitry has {} entries", l.size()); + l.forEach(handler -> { + Thing vehicleThing = handler.getThing(); + Configuration c = vehicleThing.getConfiguration(); + if (c.containsKey("vin")) { + String thingVIN = c.get("vin").toString(); + logger.debug("Found VIN {} ", thingVIN); + if (vehicle.vin.equals(thingVIN)) { + vehicleThing.setProperties(properties); + logger.debug("Car {} updated", thingVIN); + foundVehicle.set(true); + } + } + }); + + // Vehicle not found -> trigger discovery + if (!foundVehicle.get()) { + // Properties needed for functional THing + properties.put("vin", vehicle.vin); + properties.put("refreshInterval", Integer.toString(15)); + properties.put("units", "AUTODETECT"); + properties.put("imageSize", Integer.toString(500)); + properties.put("imageViewport", "FRONT"); + + String carLabel = vehicle.brand + " " + vehicle.model; + logger.debug("Thing {} discovered", carLabel); + Map convertedProperties = new HashMap(properties); + thingDiscovered(DiscoveryResultBuilder.create(uid).withBridge(bridgeUID) + .withRepresentationProperty("vin").withLabel(carLabel) + .withProperties(convertedProperties).build()); + } } }); }); + } public String getObject(Object obj, String compare) { @@ -115,7 +145,7 @@ public String getObject(Object obj, String compare) { try { if (field.get(obj) != null) { if (field.get(obj).equals(compare)) { - buf.append(field.getName() + Constants.SPACE); + buf.append(Converter.capitalizeFirst(field.getName()) + Constants.SPACE); } } } catch (IllegalArgumentException e) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java index e4ebfa2177511..657ae4c12f991 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java @@ -184,7 +184,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { VehicleStatusContainer container = GSON.fromJson(vehicleStatusCache.get(), VehicleStatusContainer.class); VehicleStatus status = container.vehicleStatus; - status.vin = ANONYMOUS; + status.vin = Constants.ANONYMOUS; if (status.position != null) { status.position.lat = -1; status.position.lon = -1; @@ -196,27 +196,31 @@ public void handleCommand(ChannelUID channelUID, Command command) { } if (lastTripCache.isPresent()) { logger.warn("### Last Trip ###"); - logger.warn("{}", lastTripCache.get()); + logger.warn("{}", + lastTripCache.get().replaceAll(configuration.get().vin, Constants.ANONYMOUS)); } else { logger.warn("### Last Trip Empty ###"); } if (allTripsCache.isPresent()) { logger.warn("### All Trips ###"); - logger.warn("{}", allTripsCache.get()); + logger.warn("{}", + allTripsCache.get().replaceAll(configuration.get().vin, Constants.ANONYMOUS)); } else { logger.warn("### All Trips Empty ###"); } if (isElectric) { if (chargeProfileCache.isPresent()) { logger.warn("### Charge Profile ###"); - logger.warn("{}", chargeProfileCache.get()); + logger.warn("{}", chargeProfileCache.get().replaceAll(configuration.get().vin, + Constants.ANONYMOUS)); } else { logger.warn("### Charge Profile Empty ###"); } } if (rangeMapCache.isPresent()) { logger.warn("### Range Map ###"); - logger.warn("{}", rangeMapCache.get()); + logger.warn("{}", + rangeMapCache.get().replaceAll(configuration.get().vin, Constants.ANONYMOUS)); } else { logger.warn("### Range Map Empty ###"); } @@ -348,7 +352,7 @@ void requestRangeMap(Position p) { dataMap.add("dlat", Float.toString(p.lat)); dataMap.add("dlon", Float.toString(p.lon)); if (configuration.isPresent()) { - proxy.get().requestRangeMap(configuration.get(), dataMap, rangeMapCallback); + proxy.get().requestRangeMap(configuration.get(), Optional.empty(), rangeMapCallback); } } currentPosition = p; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java index fa550d5ef6e76..cc1021222e318 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java @@ -17,6 +17,7 @@ import java.util.Hashtable; import java.util.Optional; import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jetty.client.HttpClient; @@ -59,7 +60,6 @@ public class ConnectedDriveBridgeHandler extends BaseBridgeHandler implements St private Optional> refreshJob = Optional.empty(); private Optional troubleshootFingerprint = Optional.empty(); - private ChannelUID discoveryTrigger; private ChannelUID discoveryfingerPrint; public ConnectedDriveBridgeHandler(Bridge bridge, HttpClient hc, BundleContext bc) { @@ -69,7 +69,6 @@ public ConnectedDriveBridgeHandler(Bridge bridge, HttpClient hc, BundleContext b discoveryService = new ConnectedCarDiscovery(this); discoveryServiceRegstration = bundleContext.registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<>()); - discoveryTrigger = new ChannelUID(thing.getUID(), DISCOVERY_TRIGGER); discoveryfingerPrint = new ChannelUID(thing.getUID(), DISCOVERY_FINGERPRINT); } @@ -88,14 +87,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { } // Switch back to off immediately updateState(discoveryfingerPrint, OnOffType.OFF); - } else if (channelUID.getIdWithoutGroup().equals(DISCOVERY_TRIGGER)) { - // trigger discovery again - helpful after the user performed some changes in the ConnectedDrive - // Portal and wants to get the changes - if (proxy.isPresent()) { - proxy.get().requestVehicles(this); - } - // Switch back to off immediately - updateState(discoveryTrigger, OnOffType.OFF); } } } @@ -107,11 +98,11 @@ public void initialize() { configuration = Optional.of(getConfigAs(ConnectedDriveConfiguration.class)); if (configuration.isPresent()) { proxy = Optional.of(new ConnectedDriveProxy(httpClient, configuration.get())); - proxy.get().requestVehicles(this); + // give the system some time to create all predefined Vehicles + scheduler.schedule(this::requestVehicles, 5, TimeUnit.SECONDS); } else { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR); } - updateState(discoveryTrigger, OnOffType.OFF); updateState(discoveryfingerPrint, OnOffType.OFF); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index 81fde4d786c2f..cc4a297f801a2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -110,7 +110,7 @@ public void request(String url, Optional> params, ResponseCallb public void onComplete(org.eclipse.jetty.client.api.Result result) { if (result.getResponse().getStatus() != 200) { NetworkError error = new NetworkError(); - error.url = url; + error.url = completeUrl.toString(); error.status = result.getResponse().getStatus(); error.reason = result.getResponse().getReason(); logger.warn("{}", error.toString()); @@ -155,10 +155,9 @@ public void requestDestinations(ConnectedCarConfiguration config, StringResponse callback); } - public void requestRangeMap(ConnectedCarConfiguration config, MultiMap params, + public void requestRangeMap(ConnectedCarConfiguration config, Optional> params, StringResponseCallback callback) { - request(new StringBuffer(baseUrl).append(config.vin).append(rangeMapAPI).toString(), Optional.of(params), - callback); + request(new StringBuffer(baseUrl).append(config.vin).append(rangeMapAPI).toString(), params, callback); } public void requestImage(ConnectedCarConfiguration config, ByteResponseCallback callback) { @@ -210,7 +209,7 @@ public Token getToken() { * @return */ public Token getNewToken() { - // http.setFollowRedirects(false); + http.setFollowRedirects(false); Request req = http.POST(authUri); req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); @@ -234,10 +233,12 @@ public Token getNewToken() { logger.info("Status {} ", contentResponse.getStatus()); HttpFields fields = contentResponse.getHeaders(); HttpField field = fields.getField(HttpHeader.LOCATION); + http.setFollowRedirects(true); return getTokenFromUrl(field.getValue()); } catch (InterruptedException | ExecutionException | TimeoutException e) { logger.warn("Auth Exception: {}", e.getMessage()); } + http.setFollowRedirects(true); return new Token(); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java index 8c438d0bd7536..f395102963de2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -43,5 +43,6 @@ public class Constants { public static final String HYPHEN = " - "; public static final String EMPTY = ""; + public static final String ANONYMOUS = "ANONYMOUS"; public static final int MILES_TO_FEET_FACTOR = 5280; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java index 8984d8523a873..1b5e943267a8b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java @@ -74,6 +74,10 @@ public static String toTitleCase(String input) { } } + public static String capitalizeFirst(String str) { + return str.substring(0, 1).toUpperCase() + str.substring(1); + } + public static double measure(float lat1, float lon1, float lat2, float lon2) { double earthRadius = 6378.137; // Radius of earth in KM double dLat = lat2 * Math.PI / 180 - lat1 * Math.PI / 180; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml index fa508d7a95f1c..5f8e6849f1a88 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml @@ -10,7 +10,6 @@ Access to BMW ConnectedDrive Portal for a specific user - From 0d76c7c868faeedc19276bfd7a33d170c52e64be Mon Sep 17 00:00:00 2001 From: Bernd Date: Thu, 3 Sep 2020 00:45:19 +0200 Subject: [PATCH 016/176] readme.md plus organizational changes Signed-off-by: Bernd (cherry picked from commit e1398cb5390c12b8220cdffba2777b9de19748b0) Signed-off-by: Bernd --- .../README-toc.xml | 41 +++ .../README.html | 338 ++++++++++++++++++ .../README.md | 328 ++++++++++++++--- .../doc/properties.png | Bin 0 -> 74860 bytes .../internal/ConnectedDriveConstants.java | 39 +- .../discovery/ConnectedCarDiscovery.java | 17 +- .../internal/dto/discovery/Vehicle.java | 1 + .../internal/dto/status/VehicleStatus.java | 1 - .../handler/ByteResponseCallback.java | 1 - .../handler/ConnectedCarChannelHandler.java | 62 +--- .../internal/handler/ConnectedCarHandler.java | 20 +- .../handler/ConnectedDriveBridgeHandler.java | 3 +- .../internal/handler/ConnectedDriveProxy.java | 5 +- .../handler/StringResponseCallback.java | 1 - .../internal/utils/Converter.java | 9 + .../ESH-INF/thing/bridge-connected-drive.xml | 10 +- ...l-groups.xml => charge-channel-groups.xml} | 7 +- .../ESH-INF/thing/charge-channel-types.xml | 10 + ...roups.xml => conv-range-channel-group.xml} | 2 +- ...trip-groups.xml => ev-last-trip-group.xml} | 0 ...etime-groups.xml => ev-lifetime-group.xml} | 0 ...-groups.xml => ev-range-channel-group.xml} | 6 +- ...ups.xml => hybrid-range-channel-group.xml} | 10 +- ...nel-groups.xml => image-channel-group.xml} | 4 +- .../ESH-INF/thing/image-channel-types.xml | 4 +- ...-groups.xml => location-channel-group.xml} | 2 - .../ESH-INF/thing/loction-channel-types.xml | 8 - .../ESH-INF/thing/range-channel-types.xml | 26 +- ....xml => remote-services-channel-group.xml} | 0 ....xml => remote-services-channel-types.xml} | 4 +- .../resources/ESH-INF/thing/thing-bev.xml | 3 +- .../resources/ESH-INF/thing/thing-bev_rex.xml | 3 +- .../resources/ESH-INF/thing/thing-phev.xml | 3 +- ...ups.xml => troubleshoot-channel-group.xml} | 2 +- .../thing/troubleshoot-channel-types.xml | 4 +- ...s.xml => vehicle-status-channel-types.xml} | 14 +- ...el-groups.xml => vehicle-status-group.xml} | 1 + .../internal/dto/status/StatusWrapper.java | 25 +- .../internal/handler/CarTests.java | 1 - .../internal/handler/ErrorResponseTest.java | 1 - .../internal/util/LocaleTest.java | 1 - .../test3.json | 76 ---- 42 files changed, 793 insertions(+), 300 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/README-toc.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/README.html create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/doc/properties.png rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/{elv-status-channel-groups.xml => charge-channel-groups.xml} (66%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-types.xml rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/{conv-range-channel-groups.xml => conv-range-channel-group.xml} (90%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/{ev-last-trip-groups.xml => ev-last-trip-group.xml} (100%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/{ev-lifetime-groups.xml => ev-lifetime-group.xml} (100%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/{ev-range-channel-groups.xml => ev-range-channel-group.xml} (75%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/{hybrid-range-channel-groups.xml => hybrid-range-channel-group.xml} (65%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/{image-channel-groups.xml => image-channel-group.xml} (77%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/{location-channel-groups.xml => location-channel-group.xml} (86%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/{status-channel-groups.xml => remote-services-channel-group.xml} (100%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/{status-channel-types.xml => remote-services-channel-types.xml} (93%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/{troubleshoot-channel-groups.xml => troubleshoot-channel-group.xml} (90%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/{remote-service-channel-types.xml => vehicle-status-channel-types.xml} (75%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/{remote-service-channel-groups.xml => vehicle-status-group.xml} (93%) delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/test3.json diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README-toc.xml b/bundles/org.openhab.binding.bmwconnecteddrive/README-toc.xml new file mode 100644 index 0000000000000..8b485d5e28411 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README-toc.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.html b/bundles/org.openhab.binding.bmwconnecteddrive/README.html new file mode 100644 index 0000000000000..925387d04c212 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.html @@ -0,0 +1,338 @@ + + + + + + +

BMW ConnectedDrive Binding

+

The Binding connects your BMW Vehicles which are registered in the + Garageof your BMW ConnectedDrive Portal. + Due to the high variety of Cars and ConnectedDrive Services you need to check which Channels are applicable to your Car. + The Discovery Service recognizes your Car with the correct type +

+
    +
  • Conventional Fuel Vehicle
  • +
  • Plugin-Hybrid Electrical Vehicle
  • +
  • Battery Electric Vehicle with Range Extender
  • +
  • Batterie Electric Vehicle
  • +
+

In addition Properties are attached to the Vehcile Thing to obeserve the Suppoerted & Activated Services. + Different Channel Groups are available so you are able to cross-check which group is supported by your Car. +
+

+

Supported Things

+

Bridge

+

The Bridge establishes the Connection between BMW ConnectedDrive Portal and opanHAB.

+

| Name | Bridge Type ID | Description | + |----------------------------|----------------|------------------------------------------------------------| + | BMW ConnectedDrive Account | account | Access to BMW ConnectedDrive Portal for a specific user |

+

Things

+

Four different Vehicle Types are provided. They differ in the supported Channel Groups & Channels. + While Conventional Fuel Vehicles have no "Charging Profile" Electric Vehicles don't provide a _fuel range_. + For Hybrid Vehicles + fuel rangeand + electric rangeis provided and in addition a + combined range +

+

| Name | Thing Type ID | Supported Channel Groups | + |-------------------------------------|---------------|------------------------------------------------------------| + | BMW Electric Vehicle | BEV | status, range, last-trip, all-trips, charge-profile, image, troubeshoot | + | BMW Electric Vehicle with REX | BEV_REX | status, range, last-trip, all-trips, charge-profile, image, troubeshoot | + | BMW Plug-In-Hybrid Electric Vehicle | PHEV | status, range, last-trip, all-trips, image, troubeshoot | + | BMW Conventional Vehicle | CONV | status, range, last-trip, all-trips, image, troubeshoot |

+

Properties

+

For each Vehicle Properties are set with various informations. + They are especially handy to figure out the provided Services of your Vehicle. + In the right picture you can see in + Activated Servicese.g. the + DoorLockand + DoorUnlockServices are mentioned. + So you're sure that in Channel Group + Remote Servicesyou are able to execute these commands. + Also + LastDestinationsis mentioned in + Supported Servicesso it's valid to connect Channel Group + Last Destinationsin order to display the last 3 Navigation Destinations. +

+

Basically 3 Types of Information are registered as Properties

+
    +
  • Informations regarding your Dealer with Address and Phone Number
  • +
  • Which services are available or not available
  • +
  • Vehicle Properties like Color, Model Type, Drive Train and Construction Year
  • +
+

Discovery

+

Auto Discovery is starting after you created the Bridge towards BMW ConnectedDrive. + A list of your registered Vehicles is queried and all found Vehicles are added in Inbox. + As Unique Identifier the + Vehicle Identification Number(VIN) is used. + If you already predefined a Thing in *.things configuration with the same VIN the Discovery won't discover it again. + The Discovery still takes care updating the Properties of your Vehicle. +

+

Configuration

+

Bridge

+

| Parameter | Type | Description | +
+ |-----------------|---------|-------------------------------------------------------------------------| + | userName | text | BMW Connected Drive Username | + | password | text | BMW Connected Drive Password | + | region | text | Select your Region in order to connect to the appropriate BMW Server. | +

+

The region Configuration has 3 different possibilities

+
    +
  • + NORTH_AMERICA +
  • +
  • + CHINA +
  • +
  • + ROWfor Rest of World +
  • +
+

Things

+

All Things are needing the same Configuration Data

+

| Parameter | Type | Description | +
+ |-----------------|---------|-------------------------------------------------------------------------| + | vin | text | Vehicle Identification Number (VIN) | + | refreshInterval | integer | Refresh Interval in Minutes | + | units | text | Unit Selection | + | imageSize | integer | Image Picture Size< | + | imageViewport | text | Image Viewport | +

+

The units can be configured in 3 ways

+
    +
  • + AUTODETECTselects Miles for US & UK, Kilometre otherwise +
  • +
  • + METRICselects directly Kilometers +
  • +
  • + IMPERIALselects directly Miles +
  • +
+

The imageVieport allows you to show your Car from different angels. + Possible values are FRONT, REAR, SIDE, DASHBOARD or DRIVERDOOR

+

Channels

+

There are many Channels available for each Vehicle. + For better overview they are clustered in different Channel Groups. + The Channel Groups are different for the Car Types but also depends on the build in Sensors of your Car. + This means also the Construction Year is relevant if some Channels are supported or not.

+

Channel Group + Vehicle Status +

+

Available for all Vehicles.

+

| Channel Label | Channel Group ID | Channel ID | Type | Description | + |-----------------------|------------------|---------------------|--------|---------------------------------------------------| + | Door Status | status | doors | String | Closed if all closed, else reports the Door which is still open | + | Window Status | status | windows | String | Closed if all closed, else reports the Window which is still open | + | Doors Locked | status | lock | String | Status if Doors are locked or unlocked | + | Upcoming Service | status | service | String | Upcoming Service either after certain Mileage, Date, or both | + | Check Control | status | check-control | String | Description of actual Check Control message, Ok if none is activae |

+

Channel Group + Range Data +

+

Available for all Vehicles. + Based on Vehicle Type (Thing Type ID) the Channel is presented or not. + For Conventional Fuel Cars the + Remaining Electric Rangeisn't presented while for Battery Electric Vehicles + Remaining Range Fuelisn't valid. + Hybrid Vehicles have both and in addition + Remaining Hybrid Range +

+

| Channel Label | Channel Group ID | Channel ID | Type | Valid for | Description | + |-----------------------|------------------|---------------------|---------------|-----------|----------------------------------------| + | Mileage | range | mileage | Number:Length | All | Total Distance Driven | + | Hybrid Range | range | range-hybrid | Number:Length | All | Total Distance Driven | + | Battery Range | range | range-electric | Number:Length | All | Total Distance Driven | + | Battery Charge Level | range | soc | Number:Length | All | Total Distance Driven | + | Fuel Range | range | range-fuel | Number:Length | All | Total Distance Driven | + | Remaining Fuel | range | remaining-fuel | Number:Length | All | Total Distance Driven |

+

Channel Group + Last Trip +

+

| Channel Label | Channel Group ID | Channel ID | Type | Description | + |-----------------------|------------------|---------------------|--------|---------------------------------------------------| + | Modbus-ID | status | modbus-id | String | Modbus ID / Magic Byte of E3DC |

+

Channel Group + Lifetime Statistics +

+

| Channel Label | Channel Group ID | Channel ID | Type | Description | + |-----------------------|------------------|---------------------|--------|---------------------------------------------------| + | Modbus-ID | range | modbus-id | String | Modbus ID / Magic Byte of E3DC |

+

Channel Group + Vehicle Location +

+

| Channel Label | Channel Group ID | Channel ID | Type | Description | + |-----------------------|------------------|---------------------|--------|---------------------------------------------------| + | Modbus-ID | status | modbus-id | String | Modbus ID / Magic Byte of E3DC |

+

Channel Group + Remote Services +

+

| Channel Label | Channel Group ID | Channel ID | Type | Description | + |-----------------------|------------------|---------------------|--------|---------------------------------------------------| + | Modbus-ID | range | modbus-id | String | Modbus ID / Magic Byte of E3DC |

+

Channel Group + Image +

+

| Channel Label | Channel Group ID | Channel ID | Type | Description | + |-----------------------|------------------|---------------------|--------|---------------------------------------------------| + | Modbus-ID | status | modbus-id | String | Modbus ID / Magic Byte of E3DC |

+

Channel Group + Troubleshooting +

+

| Channel Label | Channel Group ID | Channel ID | Type | Description | + |-----------------------|------------------|---------------------|--------|---------------------------------------------------| + | Modbus-ID | range | modbus-id | String | Modbus ID / Magic Byte of E3DC |

+

TroubleShooting

+

In order to to identify issues the TroubleShooting Channels are providing Analysis Informations

+

Discovery

+

If your Vehicle isn't discovered correctly perform the following steps

+
    +
  • Check if your Vehicle is attached correctly in ConnectedDrive. Only if it's attached to your ConnectedDrive Account it's possible to detect it.
  • +
  • In the below example sitemap the Switch + Log Discovery Fingerprintcan be executed. +
  • +
+

Car Data

+

Update Timestamp

+

There's a timestamp showing the last update of your Vehicle. If this isn't shown correctly please check the date settings. + In case of Raspberry Pi execute + raspi-cinfig_, select _Localization Options_, the _Change Time Zone + Select your + Geaographical Areaand afterwards the correct City. + One restart of openHAB service with + systemctl restart openhab2is necessary in order to see the corrected Time Settings. +

+

Full Example

+

The example is based on a BMW i3 with Range Extender (REX). + Exchange the 3 configuration parameters in the Things section

+
    +
  • YOUR_USERNAME - with your ConnectedDrive Login Username
  • +
  • YOUR_PASSWORD - with your ConnectedDrive Password Credentials
  • +
  • VEHICLE_VIN - the Vehicle Identification Number
  • +
+

and you're ready to go!

+

Things

+
Bridge bmwconnecteddrive:account:user   "BMW ConnectedDrive Account" [userName="YOUR_USERNAME",password="YOUR_PASSWORD",region="ROW"] {
+         Thing BEV_REX i3       "BMW i3 94h REX"                [ vin="VEHICLE_VIN",units="AUTODETECT",imageSize=2048,imageViewport="FRONT",refreshInterval=15]
+}
+

Items

+
Number:Length           i3Mileage                 "Odometer"                 <chart>    (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:range#mileage" }                                                                           
+Number:Length           i3Range                   "Hybrid Range"             <motion>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-range-hybrid"}
+Number:Length           i3RangeElectric           "Electric Range"           <motion>   (i3,long)   {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-range-electric"}   
+Number:Length           i3RangeFuel               "Fuel Range"               <motion>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-range-fuel"}
+Number:Dimensionless    i3BatterySoc              "Battery Charged"          <battery>  (i3,long)   {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-soc"}
+Number:Dimensionless    i3Fuel                    "Fuel Charged"             <oil>      (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-fuel"}
+String                  i3LastUpdate              "Updated"                  <calendar> (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:range#last-update"}
+
+String                  i3DoorStatus              "Door Status"       <lock>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:status#doors" }
+String                  i3WindowStatus            "Window Status"       <lock>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:status#windows" }
+String                  i3LockStatus              "Locked Status"       <lock>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:status#lock" }
+String                  i3ServiceStatus           "Service"       <calendar>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:status#service" }
+String                  i3CheckControl            "Check Control"       <error>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:status#check-control" }
+String                  i3ChargingStatus          "Charging"       <batterylevel>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:status#charging-status" }
+
+Number:Length           i3TripDistance            "Distance"                 <chart>    (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance" }                                                                           
+Number:Length           i3TripDistanceSinceCharge "Driven Since last Charge" <chart>    (i3,long)    {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance-since-charging" }                                                                           
+Number:Energy           i3AvgTripConsumption      "Average Consumption"      <energy>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-consumption" }                                                                           
+Number:Energy           i3AvgTripRecuperation     "Average Recuperation"     <energy>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-recuperation" }                                                                           
+
+Number:Length           i3CumulatedElectric       "Eletric Driven Distance"  <chart>    (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#cumulated-driven-distance" }                                                                           
+Number:Length           i3LongestEVTrip           "Longest Eletric Trip"     <chart>    (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#single-longest-distance" }                                                                           
+Number:Energy           i3AvgConsumption          "Average Consumption"      <energy>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#average-consumption" }                                                                           
+Number:Energy           i3AvgRecuperation         "Average Recuperation"     <energy>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#average-recuperation" }  
+
+Number                  i3Longitude               "Location Longitude"       <zoom>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:location#longitude" }                                                                           
+Number                  i3Latitude                "Location Latitude"        <zoom>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:location#latitude" }                                                                           
+String                  i3LatLong                 "Location as String"       <zoom>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:location#latlong" }
+Number:Angle            i3Heading                 "Vehicle Heading"          <zoom>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:location#heading" }  
+Number                  i3RangeRadius             "Range Radius"             <zoom>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:location#range-radius" }
+
+Switch                  i3RemoteFlash             "Remote Flashlight"        <switch>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#light" } 
+Switch                  i3RemoteFinder            "Remote Flashlight"        <switch>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#finder" } 
+Switch                  i3RemoteLock              "Remote Flashlight"        <switch>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#lock" } 
+Switch                  i3RemoteUnlock            "Remote Flashlight"        <switch>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#unlock" } 
+Switch                  i3RemoteHorn              "Remote Flashlight"        <switch>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#horn" } 
+Switch                  i3RemoteClimate           "Remote Flashlight"        <switch>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#climate" } 
+String                  i3RemoteState             "Remote Flashlight"        <status>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#state" } 
+
+Image                   i3Image                   "Car Image"                <switch> (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:image#rendered" }  
+
+Switch                  i3Troubleshoot            "Force Fingerprint Log"    <switch>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:troubleshoot#cardata-fingerprint" }  
+Switch                  i3DiscoveryFinger         "Discovery Fingerprint"    <switch>   (i3)   {channel="bmwconnecteddrive:account:user:discovery-fingerprint"}
+

Sitemap

+
sitemap BMW label="BMW" {
+  Frame label="BMW i3" {
+    Image  item=i3Image                     label="Car Image"
+  } 
+  Frame label="Range" {
+    Text    item=i3Mileage                  label="Odometer [%d %unit%]"
+    Text    item=i3Range                    label="Range [%d %unit%]"
+    Text    item=i3RangeElectric            label="Eletric Range [%d %unit%]"
+    Text    item=i3RangeFuel                label="Fuel Range [%d %unit%]"
+    Text    item=i3BatterySoc               label="Battery Charge [%.1f %%]"
+    Text    item=i3Fuel                     label="Fuel Charge [%.1f %%]"
+    Text    item=i3LastUpdate               label="Last Update [%s]"
+  }
+  Frame label="Status" {
+    Text    item=i3DoorStatus               label="Door Status [%s]"
+    Text    item=i3WindowStatus             label="Window Status [%s]"
+    Text    item=i3LockStatus               label="Lock Status [%s]"
+    Text    item=i3ServiceStatus            label="Service [%s]"
+    Text    item=i3CheckControl             label="Check Control [%s]"
+    Text    item=i3ChargingStatus           label="Charging [%s]"
+  }
+  Frame label="Remote Services" {
+    Switch  item=i3RemoteFlash              label="Flash"
+    Switch  item=i3RemoteFinder             label="Finder"
+    Switch  item=i3RemoteLock               label="Lock"
+    Switch  item=i3RemoteUnlock             label="Unlock"
+    Switch  item=i3RemoteHorn               label="Horn"
+    Switch  item=i3RemoteClimate            label="Air Conditioning"
+    Text    item=i3RemoteState              label="Execution Status"
+}
+  Frame label="Last Trip" {
+    Text    item=i3TripDistance             label="Distance [%d %unit%]"
+    Text    item=i3TripDistanceSinceCharge  label="Distance since last Charge [%d %unit%]"
+    Text    item=i3AvgTripConsumption       label="Average Consumption [%.1f %unit%]"
+    Text    item=i3AvgTripRecuperation      label="Average Recuperation [%.1f %unit%]"
+  }
+  Frame label="Lifetime" {
+    Text    item=i3CumulatedElectric        label="Eletric Distance Driven [%d %unit%]"
+    Text    item=i3LongestEVTrip            label="Longest Trip [%d %unit%]"
+    Text    item=i3AvgConsumption           label="Average Consumption [%.1f %unit%]"
+    Text    item=i3AvgRecuperation          label="Average Recuperation [%.1f %unit%]"      
+  }
+  Frame label="Location" {
+    Text    item=i3Latitude                 label="Latitude  [%.4f]"
+    Text    item=i3Longitude                label="Longitude [%.4f]"
+    Text    item=i3LatLong                  label="Location  [%s]"
+    Text    item=i3Heading                  label="Heading [%.1f %unit%]" 
+    Text    item=i3RangeRadius              label="Radius [%d]"   
+  }
+  Frame label="Troubleshooting" {    
+    Switch  item=i3DiscoveryFinger          label="Log Discovery Fingerprint"
+    Switch  item=i3Troubleshoot             label="Log CarData Fingerprint"
+    
+  } 
+}
+

Going further

+

You're now able to receive your Vehicle Data in openHAB. Continue the work and combine this data with other Powerful openHAB Bindings and Widgets.

+

OpenstreetMap Widget

+

OpenWeatherMap Binding and Widget

+

Especially Electric Vehicles which maybe are charged with your Local Photovoltaic System the Weather forecast and corresponding Cloudiness is interesting. + Use the OpenWeatherMap Binding and existing + Widget Solutions to check this data in addition to your Vehicles State of Charge. +

+

Credits

+

This work is based on the work of + Bimmer Connected. + Also a + manual installation based on python was already available for openHAB. + This Binding is basically a port to openHAB based on these concept works! +
+

+ + \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 6a0d587f38767..773d4d7ad422c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -1,14 +1,24 @@ -# BMWConnectedDrive Binding +# BMW ConnectedDrive Binding -The Binding connects your BMW Vehicales which are registered in your _Garage_ in your BMW ConnectedDrive Portal. +The Binding connects your BMW Vehicles which are registered in the _Garage_ of your BMW ConnectedDrive Portal. +Due to the high variety of Cars and ConnectedDrive Services you need to check which Channels are applicable to your Car. +The Discovery Service recognizes your Car with the correct type + +* Conventional Fuel Vehicle +* Plugin-Hybrid Electrical Vehicle +* Battery Electric Vehicle with Range Extender +* Batterie Electric Vehicle + +In addition Properties are attached to the Vehcile Thing to obeserve the Suppoerted & Activated Services. +Different Channel Groups are available so you are able to cross-check which group is supported by your Car. ## Supported Things ### Bridge -The Bridge etsablishes the Connection between BMW ConnectedDrive Portal and opanHAB. +The Bridge establishes the Connection between BMW ConnectedDrive Portal and opanHAB. | Name | Bridge Type ID | Description | |----------------------------|----------------|------------------------------------------------------------| @@ -17,7 +27,7 @@ The Bridge etsablishes the Connection between BMW ConnectedDrive Portal and opan ### Things -Four different Vehcile Types are provided. They differ in the supported Channel Groups & Channels. +Four different Vehicle Types are provided. They differ in the supported Channel Groups & Channels. While Conventional Fuel Vehicles have no "Charging Profile" Electric Vehicles don't provide a _fuel range_. For Hybrid Vehicles _fuel range_ and _electric range_ is provided and in addition a _combined range_ @@ -28,13 +38,29 @@ For Hybrid Vehicles _fuel range_ and _electric range_ is provided and in additio | BMW Plug-In-Hybrid Electric Vehicle | PHEV | status, range, last-trip, all-trips, image, troubeshoot | | BMW Conventional Vehicle | CONV | status, range, last-trip, all-trips, image, troubeshoot | +#### Properties + + + +For each Vehicle Properties are set with various informations. +They are especially handy to figure out the provided Services of your Vehicle. +In the right picture you can see in _Activated Services_ e.g. the _DoorLock_ and _DoorUnlock_ Services are mentioned. +So you're sure that in Channel Group _Remote Services_ you are able to execute these commands. +Also _LastDestinations_ is mentioned in _Supported Services_ so it's valid to connect Channel Group _Last Destinations_ in order to display the last 3 Navigation Destinations. + +Basically 3 Types of Information are registered as Properties + +* Informations regarding your Dealer with Address and Phone Number +* Which services are available or not available +* Vehicle Properties like Color, Model Type, Drive Train and Construction Year + ## Discovery -Auto Discovery is starting after you created the Bridge towards BMW ConnectedDrive Portal. +Auto Discovery is starting after you created the Bridge towards BMW ConnectedDrive. A list of your registered Vehicles is queried and all found Vehicles are added in Inbox. As Unique Identifier the _Vehicle Identification Number_ (VIN) is used. -So if you already predefined a Thing in *.things configuration with the same VIN the Discovery won't highlight it again. -Please note for Auto Detected Vehicles there are many Properties for the Vehicle added like Color, Model Type, responsible Dealer and more. +If you already predefined a Thing in *.things configuration with the same VIN the Discovery won't discover it again. +The Discovery still takes care updating the Properties of your Vehicle. ## Configuration @@ -44,7 +70,13 @@ Please note for Auto Detected Vehicles there are many Properties for the Vehicle |-----------------|---------|-------------------------------------------------------------------------| | userName | text | BMW Connected Drive Username | | password | text | BMW Connected Drive Password | -| region | text | Select your Region in order to connect to the appropriate BMW Server. Select from Drop Down list _North America_, _China_ or _Rest of World_. | +| region | text | Select your Region in order to connect to the appropriate BMW Server. | + +The region Configuration has 3 different possibilities + +* _NORTH_AMERICA_ +* _CHINA_ +* _ROW_ for Rest of World ### Things @@ -54,79 +86,164 @@ All Things are needing the same Configuration Data |-----------------|---------|-------------------------------------------------------------------------| | vin | text | Vehicle Identification Number (VIN) | | refreshInterval | integer | Refresh Interval in Minutes | -| units | text | Unit Selection. Either AUTODETECT (UK & US) or directly set the desired Units Metric or Imperial | +| units | text | Unit Selection | | imageSize | integer | Image Picture Size< | -| imageViewport | text | Image Viewport - FRONT, REAR, SIDE, DASHBOARD, DRIVERDOOR | +| imageViewport | text | Image Viewport | + +The units can be configured in 3 ways + +* _AUTODETECT_ selects Miles for US & UK, Kilometre otherwise +* _METRIC_ selects directly Kilometers +* _IMPERIAL_ selects directly Miles + +The imageVieport allows you to show your Car from different angels. +Possible values are FRONT, REAR, SIDE, DASHBOARD or DRIVERDOOR ## Channels -There are many Channels available for each Vehilce. For better overview they are clustered in different Channel Groups. +There are many Channels available for each Vehicle. +For better overview they are clustered in different Channel Groups. +The Channel Groups are different for the Car Types but also depends on the build in Sensors of your Car. +This means also the Construction Year is relevant if some Channels are supported or not. -### Channel Group _Status_ +### Bridge Channels -| Channel Label | Channel Group ID | Channel ID | Type | Description | -|-----------------------|------------------|---------------------|--------|---------------------------------------------------| -| Modbus-ID | status | modbus-id | String | Modbus ID / Magic Byte of E3DC | +| Channel Label | Channel ID | Type | Description | +|-----------------------|-----------------------|--------|---------------------------------------------------| +| Door Status | discovery-fingerprint | Switch | Forcing a log entry to analyze Discovery Problems | + +### Thing Channel Groups +#### Channel Group _Vehicle Status_ -### Channel Group _Range Data_ +Available for all Vehicles. | Channel Label | Channel Group ID | Channel ID | Type | Description | |-----------------------|------------------|---------------------|--------|---------------------------------------------------| -| Modbus-ID | range | modbus-id | String | Modbus ID / Magic Byte of E3DC | +| Door Status | status | doors | String | Closed if all closed, else reports the Door which is still open | +| Window Status | status | windows | String | Closed if all closed, else reports the Window which is still open | +| Doors Locked | status | lock | String | Status if Doors are locked or unlocked | +| Upcoming Service | status | service | String | Upcoming Service either after certain Mileage, Date, or both | +| Check Control | status | check-control | String | Description of actual Check Control message, Ok if none is activae | -### Channel Group _Last Trip_ -| Channel Label | Channel Group ID | Channel ID | Type | Description | -|-----------------------|------------------|---------------------|--------|---------------------------------------------------| -| Modbus-ID | status | modbus-id | String | Modbus ID / Magic Byte of E3DC | +#### Channel Group _Range Data_ +Based on Vehicle Type (Thing Type ID) some Channels are presented or not. +For Conventional Fuel Cars the _Electric Range_ isn't presented while for Battery Electric Vehicles _Range Fuel_ isn't valid. +Hybrid Vehicles have both and in addition _Hybrid Range_ -### Channel Group _Lifetime Statistics_ +| Channel Label | Channel Group ID | Channel ID | Type | Valid for | Description | +|-----------------------|------------------|---------------------|----------------------|-------------------------|----------------------------------------| +| Mileage | range | mileage | Number:Length | All | Total Distance Driven | +| Hybrid Range | range | range-hybrid | Number:Length | PHEV BEV_REX | Electric Range + Fuel Range | +| Battery Range | range | range-electric | Number:Length | PHEV BEV_REX BEV | Electric Range | +| Battery Charge Level | range | soc | Number:Dimensionless | PHEV BEV_REX BEV | Battery State of Charge | +| Fuel Range | range | range-fuel | Number:Length | CONV PHEV BEV_REX | Fuel Range | +| Remaining Fuel | range | remaining-fuel | Number:Volume | CONV PHEV BEV_REX | Remaining Fuel in Liters | -| Channel Label | Channel Group ID | Channel ID | Type | Description | -|-----------------------|------------------|---------------------|--------|---------------------------------------------------| -| Modbus-ID | range | modbus-id | String | Modbus ID / Magic Byte of E3DC | +#### Channel Group _Vehicle Location_ -### Channel Group _Vehicle Location_ +Available for all Vehicles. -| Channel Label | Channel Group ID | Channel ID | Type | Description | -|-----------------------|------------------|---------------------|--------|---------------------------------------------------| -| Modbus-ID | status | modbus-id | String | Modbus ID / Magic Byte of E3DC | +| Channel Label | Channel Group ID | Channel ID | Type | Description | +|----------------|------------------|---------------------|--------------|---------------------------------------------------| +| Latitude | location | latitude | Number | Vehicle Location Longitude | +| Longitude | location | longitude | Number | Vehicle Location Latitude | +| Heading | location | heading | Number:Angle | Vehicle Heading | +#### Channel Group _Last Trip_ -### Channel Group _Remote Services_ +Check in your Vehicle Thing Properties if _Statistics_ is present in _Services Supported_ -| Channel Label | Channel Group ID | Channel ID | Type | Description | -|-----------------------|------------------|---------------------|--------|---------------------------------------------------| -| Modbus-ID | range | modbus-id | String | Modbus ID / Magic Byte of E3DC | +| Channel Label | Channel Group ID | Channel ID | Type | Description | +|-----------------------------|------------------|-------------------------|---------------|---------------------------------------------------| +| Distance Driven | last-trip | distance | Number:Length | Distance Driven on your Last Trip | +| Distance since Last Charge | last-trip | distance-since-charging | Number:Length | Distance Driven since Last Charge | +| Average Consumption | last-trip | average-consumption | Number:Power | Average Power Consumption on your Last Trip per 100 km | +| Average Recuperation | last-trip | average-recuperation | Number:Power | Average Power Recuperation on your Last Trip per 100 km | -### Channel Group _Image_ -| Channel Label | Channel Group ID | Channel ID | Type | Description | -|-----------------------|------------------|---------------------|--------|---------------------------------------------------| -| Modbus-ID | status | modbus-id | String | Modbus ID / Magic Byte of E3DC | +#### Channel Group _Lifetime Statistics_ +Check in your Vehicle Thing Properties if _Statistics_ is present in _Services Supported_ -### Channel Group _Troubleshooting_ +| Channel Label | Channel Group ID | Channel ID | Type | Description | +|------------------------------------|------------------|--------------------------|---------------|---------------------------------------------------| +| Average Consumption | lifetime | average-consumption | Number:Power | Average Power Consumption on your Last Trip per 100 km | +| Distance since Last Charge | lifetime | average-recuperation | Number:Power | Average Power Recuperation on your Last Trip per 100 km | +| Cumulated Electric Driven Distance | lifetime | cumulated-driven-distance | Number:Length | Total Distance Driven with Electric Power | +| Longest Distance with one Charge | lifetime | single-longest-distance | Number:Length | Longest Distance Driven with one single Charge | -| Channel Label | Channel Group ID | Channel ID | Type | Description | -|-----------------------|------------------|---------------------|--------|---------------------------------------------------| -| Modbus-ID | range | modbus-id | String | Modbus ID / Magic Byte of E3DC | + +#### Channel Group _Remote Services_ + +Check in your Vehicle Thing Properties _Services Activated_ which Remote Services are available +Only one Remote Service can be executed each Time. +Parallel execution isn't supported. +The _Service Execution State_ Channel is reporting the state. +State _Executed_ is the final State when Execution is finished. + +| Channel Label | Channel Group ID | Channel ID | Type | +|-------------------------|------------------|---------------------|--------| +| Activate Flash Lights | remote | light | Switch | +| Find Vehicle | remote | finder | Switch | +| Lock Doors | remote | lock | Switch | +| Unlock Doors | remote | unlock | Switch | +| Horn Blow | remote | horn | Switch | +| Active Air Conditioning | remote | climate | Switch | +| Service Execution State | remote | state | STring | + + +#### Channel Group _Image_ + +Available for all Vehicles. + +| Channel Label | Channel Group ID | Channel ID | Type | +|-------------------------------|------------------|---------------------|--------| +| Rendered Image of your Vehicle| image | png | Image | + +#### Channel Group _Troubleshooting_ + +Available for all Vehicles - really! +Please check [TroubleShooting Section](#TroubleShooting) for further advice + +| Channel Label | Channel Group ID | Channel ID | Type | Description | +|-------------------------------------|------------------|---------------------|--------|---------------------------------------------------| +| Log Vehicle Fingerprint | troubleshoot | vehicle-fingerprint | Switch | Forces log entries in openHAB logger in order to raise issues | ## TroubleShooting -In order to to identify issues the TroubleShooting Channels are providing Analysis Informations +As stated at the beginning: BMW has a high bandwidth of Vehicles supported by BMWs ConnectedDrive. +In case of any issues you face with this Binding please help to resolve it! +Before raising an issue _Fingerprint_ data is needed in order to provide a proper analysis. +Two Fingerprints are available + +* Discovery - Your Vehicle isn't found automatically +* Vehicle - You have issue with the delivered Vehicle values + +I've done my best to eliminate any private data from these Fingerprints. +Following data is replaced with ANONYMOUS data + +* Dealer Properties +* Vehcile Identification Number (VIN) +* Location Latitude / Longitude is set to 0 + +After you've generated the corresponding Fingerprint please [follow the instructions to raise an Issue](https://community.openhab.org/t/how-to-file-an-issue/68464) and attach the Fingerprint data! +Your feedback is highly appreciated! ### Discovery -If your Vehicle isn't discovered correctly perform the following steps +If your Vehicle isn't discovered correctly or you cannot find the correct Properties perform the following steps * Check if your Vehicle is attached correctly in ConnectedDrive. Only if it's attached to your ConnectedDrive Account it's possible to detect it. -* In the below example sitemap the Switch _Log Discovery Fingerprint_ can be executed. +* In the below example Sitemap the Switch _Log Discovery Fingerprint_ can be executed. + +Copy the the log which can be found in general at [http://openhab:9001/](http://openhab:9001/) and raise an issue as described before. -### Car Data +### Vehicle Data +Maybe your Vehicle is discovered correctly and the Properties are correct but you've issue with the delivered Vehicle Values ### Update Timestamp There's a timestamp showing the last update of your Vehicle. If this isn't shown correctly please check the date settings. @@ -136,12 +253,131 @@ One restart of openHAB service with _systemctl restart openhab2_ is necessary in ## Full Example +The example is based on a BMW i3 with Range Extender (REX). +Exchange the 3 configuration parameters in the Things section + +* YOUR_USERNAME - with your ConnectedDrive Login Username +* YOUR_PASSWORD - with your ConnectedDrive Password Credentials +* VEHICLE_VIN - the Vehicle Identification Number + +and you're ready to go! + ### Things +``` +Bridge bmwconnecteddrive:account:user "BMW ConnectedDrive Account" [userName="YOUR_USERNAME",password="YOUR_PASSWORD",region="ROW"] { + Thing BEV_REX i3 "BMW i3 94h REX" [ vin="VEHICLE_VIN",units="AUTODETECT",imageSize=2048,imageViewport="FRONT",refreshInterval=15] +} +``` + ### Items +``` +Number:Length i3Mileage "Odometer" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#mileage" } +Number:Length i3Range "Hybrid Range" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-range-hybrid"} +Number:Length i3RangeElectric "Electric Range" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-range-electric"} +Number:Length i3RangeFuel "Fuel Range" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-range-fuel"} +Number:Dimensionless i3BatterySoc "Battery Charged" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-soc"} +Number:Dimensionless i3Fuel "Fuel Charged" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-fuel"} +String i3LastUpdate "Updated" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#last-update"} + +String i3DoorStatus "Door Status" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#doors" } +String i3WindowStatus "Window Status" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#windows" } +String i3LockStatus "Locked Status" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#lock" } +String i3ServiceStatus "Service" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#service" } +String i3CheckControl "Check Control" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#check-control" } +String i3ChargingStatus "Charging" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#charging-status" } + +Number:Length i3TripDistance "Distance" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance" } +Number:Length i3TripDistanceSinceCharge "Driven Since last Charge" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance-since-charging" } +Number:Energy i3AvgTripConsumption "Average Consumption" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-consumption" } +Number:Energy i3AvgTripRecuperation "Average Recuperation" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-recuperation" } + +Number:Length i3CumulatedElectric "Eletric Driven Distance" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#cumulated-driven-distance" } +Number:Length i3LongestEVTrip "Longest Eletric Trip" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#single-longest-distance" } +Number:Energy i3AvgConsumption "Average Consumption" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#average-consumption" } +Number:Energy i3AvgRecuperation "Average Recuperation" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#average-recuperation" } + +Number i3Longitude "Location Longitude" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:location#longitude" } +Number i3Latitude "Location Latitude" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:location#latitude" } +String i3LatLong "Location as String" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:location#latlong" } +Number:Angle i3Heading "Vehicle Heading" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:location#heading" } +Number i3RangeRadius "Range Radius" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:location#range-radius" } + +Switch i3RemoteFlash "Remote Flashlight" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#light" } +Switch i3RemoteFinder "Remote Flashlight" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#finder" } +Switch i3RemoteLock "Remote Flashlight" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#lock" } +Switch i3RemoteUnlock "Remote Flashlight" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#unlock" } +Switch i3RemoteHorn "Remote Flashlight" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#horn" } +Switch i3RemoteClimate "Remote Flashlight" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#climate" } +String i3RemoteState "Remote Flashlight" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#state" } + +Image i3Image "Car Image" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:image#rendered" } + +Switch i3Troubleshoot "Force Fingerprint Log" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:troubleshoot#cardata-fingerprint" } +Switch i3DiscoveryFinger "Discovery Fingerprint" (i3) {channel="bmwconnecteddrive:account:user:discovery-fingerprint"} + ``` + ### Sitemap +``` +sitemap BMW label="BMW" { + Frame label="BMW i3" { + Image item=i3Image label="Car Image" + } + Frame label="Range" { + Text item=i3Mileage label="Odometer [%d %unit%]" + Text item=i3Range label="Range [%d %unit%]" + Text item=i3RangeElectric label="Eletric Range [%d %unit%]" + Text item=i3RangeFuel label="Fuel Range [%d %unit%]" + Text item=i3BatterySoc label="Battery Charge [%.1f %%]" + Text item=i3Fuel label="Fuel Charge [%.1f %%]" + Text item=i3LastUpdate label="Last Update [%s]" + } + Frame label="Status" { + Text item=i3DoorStatus label="Door Status [%s]" + Text item=i3WindowStatus label="Window Status [%s]" + Text item=i3LockStatus label="Lock Status [%s]" + Text item=i3ServiceStatus label="Service [%s]" + Text item=i3CheckControl label="Check Control [%s]" + Text item=i3ChargingStatus label="Charging [%s]" + } + Frame label="Remote Services" { + Switch item=i3RemoteFlash label="Flash" + Switch item=i3RemoteFinder label="Finder" + Switch item=i3RemoteLock label="Lock" + Switch item=i3RemoteUnlock label="Unlock" + Switch item=i3RemoteHorn label="Horn" + Switch item=i3RemoteClimate label="Air Conditioning" + Text item=i3RemoteState label="Execution Status" +} + Frame label="Last Trip" { + Text item=i3TripDistance label="Distance [%d %unit%]" + Text item=i3TripDistanceSinceCharge label="Distance since last Charge [%d %unit%]" + Text item=i3AvgTripConsumption label="Average Consumption [%.1f %unit%]" + Text item=i3AvgTripRecuperation label="Average Recuperation [%.1f %unit%]" + } + Frame label="Lifetime" { + Text item=i3CumulatedElectric label="Eletric Distance Driven [%d %unit%]" + Text item=i3LongestEVTrip label="Longest Trip [%d %unit%]" + Text item=i3AvgConsumption label="Average Consumption [%.1f %unit%]" + Text item=i3AvgRecuperation label="Average Recuperation [%.1f %unit%]" + } + Frame label="Location" { + Text item=i3Latitude label="Latitude [%.4f]" + Text item=i3Longitude label="Longitude [%.4f]" + Text item=i3LatLong label="Location [%s]" + Text item=i3Heading label="Heading [%.1f %unit%]" + Text item=i3RangeRadius label="Radius [%d]" + } + Frame label="Troubleshooting" { + Switch item=i3DiscoveryFinger label="Log Discovery Fingerprint" + Switch item=i3Troubleshoot label="Log CarData Fingerprint" + + } +} +``` + ## Going further You're now able to receive your Vehicle Data in openHAB. Continue the work and combine this data with other Powerful openHAB Bindings and Widgets. @@ -151,7 +387,7 @@ You're now able to receive your Vehicle Data in openHAB. Continue the work and c ### OpenWeatherMap Binding and Widget Especially Electric Vehicles which maybe are charged with your Local Photovoltaic System the Weather forecast and corresponding Cloudiness is interesting. -Use the OpenWeatherMap Binding and existing [Widget Solutions[(https://community.openhab.org/t/openweathermap-widget-for-habpanel/65027) to check this data in addition to your Vehicles State of Charge. +Use the OpenWeatherMap Binding and existing [Widget Solutions](https://community.openhab.org/t/openweathermap-widget-for-habpanel/65027) to check this data in addition to your Vehicles State of Charge. ## Credits diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/doc/properties.png b/bundles/org.openhab.binding.bmwconnecteddrive/doc/properties.png new file mode 100644 index 0000000000000000000000000000000000000000..b2cc9998c3e4da609d2ca7b667c5bf4eccd0d126 GIT binary patch literal 74860 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 result); - } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java index f3ca2bef7d79c..f3a88db3b4822 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java @@ -28,24 +28,6 @@ */ @NonNullByDefault public class ConnectedCarChannelHandler extends BaseThingHandler { - // Property Channels - // protected ChannelUID brandChannel; - // protected ChannelUID modelChannel; - // protected ChannelUID drivetrainChannel; - // protected ChannelUID bodyChannel; - // protected ChannelUID colorChannel; - // protected ChannelUID constructionYearChannel; - // protected ChannelUID communityStatisticsChannel; - // protected ChannelUID alarmChannel; - // protected ChannelUID dealerNameChannel; - // protected ChannelUID dealerAddressChannel; - // protected ChannelUID dealerPhoneChannel; - // protected ChannelUID breakdownPhoneChannel; - // protected ChannelUID activatedServicesChannel; - // protected ChannelUID deactivatedServicesChannel; - // protected ChannelUID supportedServicesChannel; - // protected ChannelUID notSupportedServicesChannel; - // protected ChannelUID chargingModesChannel; // Vahicle Status Channels protected ChannelUID doors; @@ -96,51 +78,30 @@ public class ConnectedCarChannelHandler extends BaseThingHandler { protected ChannelUID remoteStateChannel; // Troubleshooting - protected ChannelUID carDataFingerprint; + protected ChannelUID vehicleFingerPrint; public ConnectedCarChannelHandler(Thing thing) { super(thing); - // create properties channels - // brandChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_BRAND); - // modelChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_MODEL); - // drivetrainChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_DRIVETRAIN); - // bodyChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_BODYTYPE); - // colorChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_COLOR); - // constructionYearChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, - // PROPERTIES_CONSTRUCTION_YEAR); - // communityStatisticsChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_COMMUNITY); - // alarmChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_ALARM); - // dealerNameChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_DEALER_NAME); - // dealerAddressChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_DEALER_ADDRESS); - // dealerPhoneChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_DEALER_PHONE); - // breakdownPhoneChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_BREAKDOWN_PHONE); - // activatedServicesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, - // PROPERTIES_ACTIVATED_SERVICES); - // deactivatedServicesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, - // PROPERTIES_DEACTIVATED_SERVICES); - // supportedServicesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, - // PROPERTIES_SUPPORTED_SERVICES); - // notSupportedServicesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, - // PROPERTIES_NOT_SUPPORTED_SERVICES); - // chargingModesChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_PROPERTIES, PROPERTIES_CHARGING_MODES); - // Vehicle Status channels doors = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, DOORS); windows = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, WINDOWS); lock = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, LOCK); service = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, SERVICE); checkControl = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, CHECK_CONTROL); - chargingStatus = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, CHARGING_STATUS); + lastUpdate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, LAST_UPDATE); + + // Charge Channels + chargingStatus = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGING_STATUS); // range Channels mileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, MILEAGE); - remainingRangeHybrid = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_RANGE_HYBRID); - remainingRangeElectric = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_RANGE_ELECTRIC); - remainingSoc = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_SOC); - remainingRangeFuel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_RANGE_FUEL); + remainingRangeHybrid = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, RANGE_HYBRID); + remainingRangeElectric = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, RANGE_ELECTRIC); + remainingSoc = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, SOC); + remainingRangeFuel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, RANGE_FUEL); remainingFuel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_FUEL); - lastUpdate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, LAST_UPDATE); + rangeRadius = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, RANGE_RADIUS); // Last Trip Channels tripDistance = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, DISTANCE); @@ -160,7 +121,6 @@ public ConnectedCarChannelHandler(Thing thing) { latitude = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, LATITUDE); latlong = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, LATLONG); heading = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, HEADING); - rangeRadius = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, RANGE_RADIUS); imageChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CAR_IMAGE, IMAGE); @@ -172,7 +132,7 @@ public ConnectedCarChannelHandler(Thing thing) { remoteClimateChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_AIR_CONDITIONING); remoteStateChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_STATE); - carDataFingerprint = new ChannelUID(thing.getUID(), CHANNEL_GROUP_TROUBLESHOOT, CARDATA_FINGERPRINT); + vehicleFingerPrint = new ChannelUID(thing.getUID(), CHANNEL_GROUP_TROUBLESHOOT, VEHICLE_FINGERPRINT); } @Override diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java index 657ae4c12f991..e0471e9a5b282 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java @@ -128,10 +128,8 @@ public void handleCommand(ChannelUID channelUID, Command command) { lastTripCallback.onResponse(lastTripCache); } else if (CHANNEL_GROUP_STATUS.equals(group)) { vehicleStatusCallback.onResponse(vehicleStatusCache); - } else if (CHANNEL_GROUP_CHARGE_PROFILE.equals(group)) { + } else if (CHANNEL_GROUP_CHARGE.equals(group)) { vehicleStatusCallback.onResponse(chargeProfileCache); - } else if (CHANNEL_GROUP_RANGE_MAP.equals(group)) { - vehicleStatusCallback.onResponse(rangeMapCache); } } else { // Executing Remote Services @@ -167,14 +165,14 @@ public void handleCommand(ChannelUID channelUID, Command command) { break; } } - updateState(carDataFingerprint, OnOffType.OFF); + updateState(vehicleFingerPrint, OnOffType.OFF); } } } // Log Troubleshoot data - if (channelUID.getIdWithoutGroup().equals(CARDATA_FINGERPRINT)) { - logger.info("Trigger CarData Fingerprint"); + if (channelUID.getIdWithoutGroup().equals(VEHICLE_FINGERPRINT)) { + logger.info("Trigger Vehicle Fingerprint"); if (command instanceof OnOffType) { if (command.equals(OnOffType.ON)) { logger.warn("BMW ConnectedDrive Binding - Car Data Troubleshoot fingerprint - BEGIN"); @@ -276,7 +274,7 @@ public void initialize() { // Switch all Remote Service Channels Off switchRemoteServicesOff(); - updateState(carDataFingerprint, OnOffType.OFF); + updateState(vehicleFingerPrint, OnOffType.OFF); // get Car Image one time at the beginning proxy.get().requestImage(configuration.get(), imageCallback); @@ -352,7 +350,7 @@ void requestRangeMap(Position p) { dataMap.add("dlat", Float.toString(p.lat)); dataMap.add("dlon", Float.toString(p.lon)); if (configuration.isPresent()) { - proxy.get().requestRangeMap(configuration.get(), Optional.empty(), rangeMapCallback); + proxy.get().requestRangeMap(configuration.get(), Optional.of(dataMap), rangeMapCallback); } } currentPosition = p; @@ -560,7 +558,8 @@ public void onResponse(Optional content) { updateState(remainingRangeHybrid, QuantityType.valueOf(Converter.round(totalRange), MetricPrefix.KILO(SIUnits.METRE))); } - updateState(rangeRadius, new DecimalType((totalRange) * 1000)); + updateState(rangeRadius, + QuantityType.valueOf(Converter.guessRange(totalRange), MetricPrefix.KILO(SIUnits.METRE))); } else { updateState(mileage, QuantityType.valueOf(vStatus.mileage, ImperialUnits.MILE)); float totalRange = 0; @@ -578,7 +577,8 @@ public void onResponse(Optional content) { updateState(remainingRangeHybrid, QuantityType.valueOf(Converter.round(totalRange), ImperialUnits.MILE)); } - updateState(rangeRadius, new DecimalType((totalRange) * Constants.MILES_TO_FEET_FACTOR)); + updateState(rangeRadius, + QuantityType.valueOf(Converter.guessRange(totalRange), ImperialUnits.MILE)); } if (isElectric) { updateState(remainingSoc, QuantityType.valueOf(vStatus.chargingLevelHv, SmartHomeUnits.PERCENT)); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java index cc1021222e318..3b09f42e33354 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java @@ -12,7 +12,8 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.handler; -import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; +import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.DISCOVERY_FINGERPRINT; +import static org.openhab.binding.bmwconnecteddrive.internal.utils.Constants.ANONYMOUS; import java.util.Hashtable; import java.util.Optional; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index cc4a297f801a2..6b6516002ca4a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -99,8 +99,11 @@ public void request(String url, Optional> params, ResponseCallb // req.header(CONTENT_LENGTH, Integer.toString(urlEncodedData.length())); // req.content(new StringContentProvider(urlEncodedData)); // logger.info("URL has parameters {}", urlEncodedData); - // logger.info("Complete URL {}", completeUrl.toString()); + logger.info("Params for request: {}", urlEncodedData); + } else { + logger.info("No Params for request: {}", url); } + logger.info("Complete URL {}", completeUrl.toString()); Request req = http.newRequest(completeUrl.toString()); req.header(HttpHeader.CONNECTION, KEEP_ALIVE); req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/StringResponseCallback.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/StringResponseCallback.java index 1ef5f23ce0207..4c89d41bafb1f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/StringResponseCallback.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/StringResponseCallback.java @@ -25,5 +25,4 @@ public interface StringResponseCallback extends ResponseCallback { public void onResponse(Optional result); - } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java index 1b5e943267a8b..aa9d68f48b90c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java @@ -88,4 +88,13 @@ public static double measure(float lat1, float lon1, float lat2, float lon2) { double d = earthRadius * c; return d * 1000; // meters } + + public static double guessRange(float totalRange) { + // Simple guess right now + if (totalRange < 20) { + return totalRange * 0.8; + } else { + return totalRange * 0.7; + } + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml index 5f8e6849f1a88..0a5cd5d4b80ff 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml @@ -35,16 +35,10 @@
- - Switch - - Forcing an update of the ConnectedDrive data. Useful if e.g. user has a new car connected / removed from - his Account - Switch - - Forcing a log entry with needed data needed for problem analysis + + Forcing a log entry to analyze Discovery Problems diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/elv-status-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-groups.xml similarity index 66% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/elv-status-channel-groups.xml rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-groups.xml index 52fa76db148c1..d7ff8317649fe 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/elv-status-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-groups.xml @@ -3,15 +3,10 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - + Provides Status of Doors, Lock State, Service and Check Control Messages - - - - - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-types.xml new file mode 100644 index 0000000000000..426c0222c805a --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-types.xml @@ -0,0 +1,10 @@ + + + + String + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/conv-range-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/conv-range-channel-group.xml similarity index 90% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/conv-range-channel-groups.xml rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/conv-range-channel-group.xml index c15efc5d65cc6..d964fc43194b1 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/conv-range-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/conv-range-channel-group.xml @@ -8,7 +8,7 @@ Provides Mileage, remaining range and fuel level values - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-group.xml similarity index 100% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-groups.xml rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-group.xml diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-group.xml similarity index 100% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-groups.xml rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-group.xml diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-group.xml similarity index 75% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-groups.xml rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-group.xml index b09a63e77b55d..0458e304109d9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-group.xml @@ -8,9 +8,9 @@ Provides Mileage, remaining range and charge level values - - - + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-range-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-range-channel-group.xml similarity index 65% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-range-channel-groups.xml rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-range-channel-group.xml index 7810170baa6ba..d4751ee9115d7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-range-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-range-channel-group.xml @@ -8,12 +8,12 @@ Provides Mileage, remaining range and fuel and charge level values - - - - + + + + - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-group.xml similarity index 77% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-groups.xml rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-group.xml index 063265cc0d372..c010e75a4c445 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-group.xml @@ -5,9 +5,9 @@ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - Provides an Image of your Car based on the given View direction + Provides an Image of your Car based on the Configuration ViewPort - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml index 7a2847f1f6c75..0c539f8d4c58e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - + Image - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/location-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/location-channel-group.xml similarity index 86% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/location-channel-groups.xml rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/location-channel-group.xml index 6f0918d31ff86..2f4f8039d9177 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/location-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/location-channel-group.xml @@ -9,9 +9,7 @@ - - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/loction-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/loction-channel-types.xml index e8bd5dd3a60d7..f91bffe1d11ab 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/loction-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/loction-channel-types.xml @@ -11,16 +11,8 @@ Number - - String - - Number:Angle - - Number - - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml index d97cd4bc73a3f..c2198e6151cfd 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml @@ -7,28 +7,28 @@ Number:Length
- + Number:Length - + - + Number:Length - + - + Number:Dimensionless - + - + Number:Length - + - Number:Dimensionless - + Number:Volume + - - String - + + Number:Length + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/remote-services-channel-group.xml similarity index 100% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-groups.xml rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/remote-services-channel-group.xml diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/remote-services-channel-types.xml similarity index 93% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-types.xml rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/remote-services-channel-types.xml index 294dffb158144..98dafa4ab8b83 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/status-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/remote-services-channel-types.xml @@ -9,7 +9,7 @@ Switch - + Switch @@ -29,6 +29,6 @@ String - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml index 8b925523cd8c0..5217416bd5b96 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml @@ -13,8 +13,9 @@ Electric Car - + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml index c7fab5f1d4d5b..bb37a9d942265 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml @@ -13,8 +13,9 @@ Electric Car with Range Extender - + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml index 8c0ea98308f71..cdd5cdd7d05c9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml @@ -13,8 +13,9 @@ Conventional Fuel Car with supporting Electric Engine - + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-group.xml similarity index 90% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-groups.xml rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-group.xml index 7dea5bbb210c8..6b966dd4ea00b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-group.xml @@ -7,7 +7,7 @@ Generating Debug Data if a Problem Report shall be raised - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml index 88d804f301b0f..14467e56a6886 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - + Switch - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/remote-service-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml similarity index 75% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/remote-service-channel-types.xml rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml index 572baa30057a5..2087c1d3ff187 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/remote-service-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml @@ -9,22 +9,26 @@ String - + String - + String - + String - + + + + String + String - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/remote-service-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-group.xml similarity index 93% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/remote-service-channel-groups.xml rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-group.xml index c9565c0fcc43d..872d1b7c17104 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/remote-service-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-group.xml @@ -12,6 +12,7 @@ + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/StatusWrapper.java index c0c2d9b132970..7cfb4b1d132cb 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/StatusWrapper.java @@ -31,7 +31,6 @@ import org.eclipse.smarthome.core.thing.ChannelUID; import org.eclipse.smarthome.core.types.State; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CarType; -import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import com.google.gson.Gson; @@ -63,7 +62,6 @@ public StatusWrapper(@Nullable String type, boolean imperial, @Nullable String s assertNotNull(container); assertNotNull(container.vehicleStatus); vStatus = container.vehicleStatus; - } public boolean checkResults(@Nullable List channels, @Nullable List states) { @@ -92,7 +90,7 @@ private void checkResult(ChannelUID channelUID, State state) { } assertEquals("Mileage", qt.intValue(), vStatus.mileage); break; - case REMAINING_RANGE_ELECTRIC: + case RANGE_ELECTRIC: assertTrue("Is Eelctric", isElectric); assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); @@ -106,7 +104,7 @@ private void checkResult(ChannelUID channelUID, State state) { Converter.round(vStatus.remainingRangeElectric), 0.01); } break; - case REMAINING_RANGE_FUEL: + case RANGE_FUEL: assertTrue("Has Fuel", hasFuel); assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); @@ -120,7 +118,7 @@ private void checkResult(ChannelUID channelUID, State state) { Converter.round(vStatus.remainingRangeFuel), 0.01); } break; - case REMAINING_RANGE_HYBRID: + case RANGE_HYBRID: assertTrue("Is Hybrid", isHybrid); assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); @@ -141,7 +139,7 @@ private void checkResult(ChannelUID channelUID, State state) { assertEquals("Percent", SmartHomeUnits.LITRE, qt.getUnit()); assertEquals("Percent", Converter.round(vStatus.remainingFuel), Converter.round(qt.floatValue()), 0.01); break; - case REMAINING_SOC: + case SOC: assertTrue("Is Eelctric", isElectric); assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); @@ -218,25 +216,25 @@ private void checkResult(ChannelUID channelUID, State state) { assertEquals("Lat/Long", vStatus.position.lat + "," + vStatus.position.lon, st.toString()); break; case RANGE_RADIUS: - assertTrue(state instanceof DecimalType); - dt = (DecimalType) state; + assertTrue(state instanceof QuantityType); + qt = (QuantityType) state; int totalRange = 0; if (imperial) { if (isElectric) { - totalRange += vStatus.remainingRangeElectricMls * Constants.MILES_TO_FEET_FACTOR; + totalRange += vStatus.remainingRangeElectricMls; } if (hasFuel) { - totalRange += vStatus.remainingRangeFuelMls * Constants.MILES_TO_FEET_FACTOR; + totalRange += vStatus.remainingRangeFuelMls; } } else { if (isElectric) { - totalRange += vStatus.remainingRangeElectric * 1000; + totalRange += vStatus.remainingRangeElectric; } if (hasFuel) { - totalRange += vStatus.remainingRangeFuel * 1000; + totalRange += vStatus.remainingRangeFuel; } } - assertEquals("Range Circle", totalRange, dt.intValue()); + assertEquals("Range Circle", Converter.guessRange(totalRange), qt.floatValue(), 0.1); break; default: // fail in case of unknown update @@ -244,5 +242,4 @@ private void checkResult(ChannelUID channelUID, State state) { break; } } - } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java index fe7aa3a2f8d4c..c0e3da6940c3f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java @@ -75,7 +75,6 @@ public void setup(String type, boolean imperial) { cch.setCallback(tc); channelCaptor = ArgumentCaptor.forClass(ChannelUID.class); stateCaptor = ArgumentCaptor.forClass(State.class); - } private boolean testCar(@Nullable String statusContent, int callbacksExpected) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ErrorResponseTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ErrorResponseTest.java index 0514f87dcb0c1..0e358905899e6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ErrorResponseTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ErrorResponseTest.java @@ -71,7 +71,6 @@ public void setup(String type, boolean imperial) { cch.setCallback(tc); channelCaptor = ArgumentCaptor.forClass(ChannelUID.class); stateCaptor = ArgumentCaptor.forClass(State.class); - } // private boolean testCar(@Nullable String statusContent, int callbacksExpected) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java index 0b662b857658a..7383773d084f8 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java @@ -66,5 +66,4 @@ public void testTimeZoneDateTime() { String pattern = "2018-07-16T21:47:46+0000"; assertEquals("ZonedDateTime", "16.07.2018 23:47", Converter.getZonedDateTime(pattern)); } - } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/test3.json b/bundles/org.openhab.binding.bmwconnecteddrive/test3.json deleted file mode 100644 index 19a5100bbc44b..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/test3.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "vehicleStatus": { - "vin": "WBY1Z81040V905639", - "mileage": 17324, - "updateReason": "VEHICLE_SHUTDOWN_SECURED", - "updateTime": "2020-08-26T03:47:24+0000", - "doorDriverFront": "CLOSED", - "doorDriverRear": "CLOSED", - "doorPassengerFront": "CLOSED", - "doorPassengerRear": "CLOSED", - "windowDriverFront": "CLOSED", - "windowDriverRear": "CLOSED", - "windowPassengerFront": "CLOSED", - "windowPassengerRear": "CLOSED", - "sunroof": "CLOSED", - "trunk": "CLOSED", - "rearWindow": "INVALID", - "hood": "CLOSED", - "doorLockState": "SECURED", - "parkingLight": "OFF", - "positionLight": "ON", - "remainingFuel": 4, - "remainingRangeElectric": 179, - "remainingRangeElectricMls": 111, - "remainingRangeFuel": 71, - "remainingRangeFuelMls": 44, - "maxRangeElectric": 219, - "maxRangeElectricMls": 136, - "maxFuel": 8.5, - "connectionStatus": "DISCONNECTED", - "chargingStatus": "INVALID", - "chargingLevelHv": 83, - "lastChargingEndReason": "END_REQUESTED_BY_DRIVER", - "lastChargingEndResult": "SUCCESS", - "position": { - "lat": 50.57332, - "lon": 8.6638365, - "heading": 217, - "status": "OK" - }, - "internalDataTimeUTC": "2020-08-26T03:47:24", - "singleImmediateCharging": false, - "chargingConnectionType": "CONDUCTIVE", - "chargingInductivePositioning": "NOT_POSITIONED", - "vehicleCountry": "DE", - "checkControlMessages": [], - "cbsData": [ - { - "cbsType": "BRAKE_FLUID", - "cbsState": "OK", - "cbsDueDate": "2021-11", - "cbsDescription": "Next change due at the latest by the stated date." - }, - { - "cbsType": "VEHICLE_CHECK", - "cbsState": "OK", - "cbsDueDate": "2021-11", - "cbsDescription": "Next visual inspection due when the stated distance has been covered or by the stated date." - }, - { - "cbsType": "OIL", - "cbsState": "OK", - "cbsDueDate": "2021-11", - "cbsDescription": "Next change due when the stated distance has been covered or by the specified date." - }, - { - "cbsType": "VEHICLE_TUV", - "cbsState": "OK", - "cbsDueDate": "2021-11", - "cbsDescription": "Next statutory vehicle inspection due by the stated date." - } - ], - "DCS_CCH_Activation": "NA", - "DCS_CCH_Ongoing": false - } -} \ No newline at end of file From 50b196e135d037a91da1be21096e474ff9942829 Mon Sep 17 00:00:00 2001 From: Bernd Date: Thu, 3 Sep 2020 20:31:27 +0200 Subject: [PATCH 017/176] add group destinations Signed-off-by: Bernd (cherry picked from commit 2885dea745fd81c47d744bffcfa4113e94ea6b51) Signed-off-by: Bernd --- .../README.md | 76 +++++++++++-------- .../internal/ConnectedDriveConstants.java | 11 +++ .../internal/dto/Destination.java | 55 ++++++++++++++ .../internal/dto/DestinationContainer.java | 24 ++++++ .../handler/ConnectedCarChannelHandler.java | 21 +++++ .../internal/handler/ConnectedCarHandler.java | 61 ++++++++++++++- .../internal/utils/Constants.java | 2 + .../ESH-INF/thing/charge-channel-groups.xml | 4 +- .../thing/destination-channel-types.xml | 42 ++++++++++ .../ESH-INF/thing/destination-group.xml | 21 +++++ .../resources/ESH-INF/thing/thing-bev.xml | 1 + .../resources/ESH-INF/thing/thing-bev_rex.xml | 1 + .../resources/ESH-INF/thing/thing-conv.xml | 1 + .../resources/ESH-INF/thing/thing-phev.xml | 1 + .../internal/dto/DestinationTest.java | 49 ++++++++++++ .../internal/dto/status/StatusWrapper.java | 7 +- 16 files changed, 341 insertions(+), 36 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DestinationContainer.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-channel-types.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-group.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DestinationTest.java diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 773d4d7ad422c..c5e4a7ae027f4 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -9,16 +9,16 @@ The Discovery Service recognizes your Car with the correct type * Conventional Fuel Vehicle * Plugin-Hybrid Electrical Vehicle * Battery Electric Vehicle with Range Extender -* Batterie Electric Vehicle +* Battery Electric Vehicle -In addition Properties are attached to the Vehcile Thing to obeserve the Suppoerted & Activated Services. +In addition Properties are attached to the Vehicle Thing to observe the Supported & Activated Services. Different Channel Groups are available so you are able to cross-check which group is supported by your Car. ## Supported Things ### Bridge -The Bridge establishes the Connection between BMW ConnectedDrive Portal and opanHAB. +The Bridge establishes the Connection between BMW ConnectedDrive Portal and openHAB. | Name | Bridge Type ID | Description | |----------------------------|----------------|------------------------------------------------------------| @@ -82,13 +82,13 @@ The region Configuration has 3 different possibilities All Things are needing the same Configuration Data -| Parameter | Type | Description | -|-----------------|---------|-------------------------------------------------------------------------| -| vin | text | Vehicle Identification Number (VIN) | -| refreshInterval | integer | Refresh Interval in Minutes | -| units | text | Unit Selection | -| imageSize | integer | Image Picture Size< | -| imageViewport | text | Image Viewport | +| Parameter | Type | Description | +|-----------------|---------|---------------------------------------| +| vin | text | Vehicle Identification Number (VIN) | +| refreshInterval | integer | Refresh Interval in Minutes | +| units | text | Unit Selection | +| imageSize | integer | Image Picture Size | +| imageViewport | text | Image Viewport | The units can be configured in 3 ways @@ -118,13 +118,13 @@ This means also the Construction Year is relevant if some Channels are supported Available for all Vehicles. -| Channel Label | Channel Group ID | Channel ID | Type | Description | -|-----------------------|------------------|---------------------|--------|---------------------------------------------------| -| Door Status | status | doors | String | Closed if all closed, else reports the Door which is still open | -| Window Status | status | windows | String | Closed if all closed, else reports the Window which is still open | -| Doors Locked | status | lock | String | Status if Doors are locked or unlocked | -| Upcoming Service | status | service | String | Upcoming Service either after certain Mileage, Date, or both | -| Check Control | status | check-control | String | Description of actual Check Control message, Ok if none is activae | +| Channel Label | Channel Group ID | Channel ID | Type | Description | +|-----------------------|------------------|---------------------|--------|----------------------------------------------------------------------| +| Door Status | status | doors | String | Closed if all closed, else reports the Door which is still open | +| Window Status | status | windows | String | Closed if all closed, else reports the Window which is still open | +| Doors Locked | status | lock | String | Status if Doors are locked or unlocked | +| Upcoming Service | status | service | String | Upcoming Service either after certain Mileage, Date, or both | +| Check Control | status | check-control | String | Description of actual Check Control message, Ok if none is activated | #### Channel Group _Range Data_ @@ -135,22 +135,22 @@ Hybrid Vehicles have both and in addition _Hybrid Range_ | Channel Label | Channel Group ID | Channel ID | Type | Valid for | Description | |-----------------------|------------------|---------------------|----------------------|-------------------------|----------------------------------------| -| Mileage | range | mileage | Number:Length | All | Total Distance Driven | -| Hybrid Range | range | range-hybrid | Number:Length | PHEV BEV_REX | Electric Range + Fuel Range | -| Battery Range | range | range-electric | Number:Length | PHEV BEV_REX BEV | Electric Range | -| Battery Charge Level | range | soc | Number:Dimensionless | PHEV BEV_REX BEV | Battery State of Charge | -| Fuel Range | range | range-fuel | Number:Length | CONV PHEV BEV_REX | Fuel Range | -| Remaining Fuel | range | remaining-fuel | Number:Volume | CONV PHEV BEV_REX | Remaining Fuel in Liters | +| Mileage | range | mileage | Number:Length | All | Total Distance Driven | +| Hybrid Range | range | range-hybrid | Number:Length | PHEV BEV_REX | Electric Range + Fuel Range | +| Battery Range | range | range-electric | Number:Length | PHEV BEV_REX BEV | Electric Range | +| Battery Charge Level | range | soc | Number:Dimensionless | PHEV BEV_REX BEV | Battery State of Charge | +| Fuel Range | range | range-fuel | Number:Length | CONV PHEV BEV_REX | Fuel Range | +| Remaining Fuel | range | remaining-fuel | Number:Volume | CONV PHEV BEV_REX | Remaining Fuel in Liters | #### Channel Group _Vehicle Location_ Available for all Vehicles. -| Channel Label | Channel Group ID | Channel ID | Type | Description | -|----------------|------------------|---------------------|--------------|---------------------------------------------------| -| Latitude | location | latitude | Number | Vehicle Location Longitude | -| Longitude | location | longitude | Number | Vehicle Location Latitude | -| Heading | location | heading | Number:Angle | Vehicle Heading | +| Channel Label | Channel Group ID | Channel ID | Type | +|----------------|------------------|---------------------|--------------| +| Latitude | location | latitude | Number | +| Longitude | location | longitude | Number | +| Heading | location | heading | Number:Angle | #### Channel Group _Last Trip_ @@ -184,8 +184,8 @@ Parallel execution isn't supported. The _Service Execution State_ Channel is reporting the state. State _Executed_ is the final State when Execution is finished. -| Channel Label | Channel Group ID | Channel ID | Type | -|-------------------------|------------------|---------------------|--------| +| Channel Label | Channel Group ID | Channel ID | Type | +|-------------------------|------------------|---------------------|---------| | Activate Flash Lights | remote | light | Switch | | Find Vehicle | remote | finder | Switch | | Lock Doors | remote | lock | Switch | @@ -194,6 +194,22 @@ State _Executed_ is the final State when Execution is finished. | Active Air Conditioning | remote | climate | Switch | | Service Execution State | remote | state | STring | +#### Channel Group _Destinations_ + +Check in your Vehicle Thing Properties if _LastDestinations_ is present in _Services Supported_ + +| Channel Label | Channel Group ID | Channel ID | Type | +|--------------------------------------|------------------|---------------------|---------| +| Last Destination Name | destination | name-1 | String | +| Last Destination Latitude | destination | lat-1 | Number | +| Last Destination Longitude | destination | lon-1 | Number | +| Second Last Destination Name | destination | name-2 | String | +| Second Last Destination Latitude | destination | lat-2 | Number | +| Second Last Destination Longitude | destination | lon-2 | Number | +| Third Last Destination Name | destination | name-3 | String | +| Third Last Destination Latitude | destination | lat-3 | Number | +| Third Last Destination Longitude | destination | lon-3 | Number | + #### Channel Group _Image_ diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index dd38f1b657de8..0a8b4ac4c5b02 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -105,6 +105,7 @@ public String toString() { public static final String CHANNEL_GROUP_LOCATION = "location"; public static final String CHANNEL_GROUP_CAR_IMAGE = "image"; public static final String CHANNEL_GROUP_REMOTE = "remote"; + public static final String CHANNEL_GROUP_DESTINATION = "destination"; public static final String CHANNEL_GROUP_CHARGE = "charge"; public static final String CHANNEL_GROUP_TROUBLESHOOT = "troubleshoot"; @@ -155,6 +156,16 @@ public String toString() { public static final String REMOTE_SERVICE_AIR_CONDITIONING = "climate"; public static final String REMOTE_STATE = "state"; + public static final String DESTINATION_NAME_1 = "name-1"; + public static final String DESTINATION_LAT_1 = "lat-1"; + public static final String DESTINATION_LON_1 = "lon-1"; + public static final String DESTINATION_NAME_2 = "name-2"; + public static final String DESTINATION_LAT_2 = "lat-2"; + public static final String DESTINATION_LON_2 = "lon-2"; + public static final String DESTINATION_NAME_3 = "name-3"; + public static final String DESTINATION_LAT_3 = "lat-3"; + public static final String DESTINATION_LON_3 = "lon-3"; + // Troubleshoot public static final String VEHICLE_FINGERPRINT = "vehicle-fingerprint"; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java new file mode 100644 index 0000000000000..9c8169d6fa62e --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; + +import static org.openhab.binding.bmwconnecteddrive.internal.utils.Constants.*; + +import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; + +/** + * The {@link Destination} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class Destination { + public float lat;// ": 50.55577087402344, + public float lon;// ": 8.495763778686523, + public String country;// ": "DEUTSCHLAND", + public String city;// ": "WETZLAR", + public String street;// ": "UFERSTRASSE", + public String streetNumber;// ": "4", + public String type;// ": "DESTINATION", + public String createdAt;// ": "2020-08-16T12:52:58+0000" + + public String getAddress() { + StringBuffer buf = new StringBuffer(); + if (street != null) { + buf.append(street); + if (streetNumber != null) { + buf.append(SPACE).append(streetNumber); + } + } + if (city != null) { + if (buf.length() > 0) { + buf.append(COMMA).append(SPACE).append(city); + } else { + buf.append(city); + } + } + if (buf.length() == 0) { + return Converter.toTitleCase(UNKNOWN); + } else { + return Converter.toTitleCase(buf.toString()); + } + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DestinationContainer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DestinationContainer.java new file mode 100644 index 0000000000000..ea13ef7a05b46 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DestinationContainer.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; + +import java.util.List; + +/** + * The {@link DestinationContainer} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class DestinationContainer { + public List destinations; +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java index f3a88db3b4822..56b3112ea1bf5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java @@ -77,6 +77,17 @@ public class ConnectedCarChannelHandler extends BaseThingHandler { protected ChannelUID remoteClimateChannel; protected ChannelUID remoteStateChannel; + // Remote Services + protected ChannelUID destinationName1; + protected ChannelUID destinationLat1; + protected ChannelUID destinationLon1; + protected ChannelUID destinationName2; + protected ChannelUID destinationLat2; + protected ChannelUID destinationLon2; + protected ChannelUID destinationName3; + protected ChannelUID destinationLat3; + protected ChannelUID destinationLon3; + // Troubleshooting protected ChannelUID vehicleFingerPrint; @@ -132,6 +143,16 @@ public ConnectedCarChannelHandler(Thing thing) { remoteClimateChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_AIR_CONDITIONING); remoteStateChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_STATE); + destinationName1 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_NAME_1); + destinationLat1 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_LAT_1); + destinationLon1 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_LON_1); + destinationName2 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_NAME_2); + destinationLat2 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_LAT_2); + destinationLon2 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_LON_2); + destinationName3 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_NAME_3); + destinationLat3 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_LAT_3); + destinationLon3 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_LON_3); + vehicleFingerPrint = new ChannelUID(thing.getUID(), CHANNEL_GROUP_TROUBLESHOOT, VEHICLE_FINGERPRINT); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java index e0471e9a5b282..bedeabf8ecaf0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java @@ -43,6 +43,7 @@ import org.eclipse.smarthome.io.net.http.HttpUtil; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedCarConfiguration; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CarType; +import org.openhab.binding.bmwconnecteddrive.internal.dto.DestinationContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTrips; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTripsContainer; @@ -90,6 +91,7 @@ public class ConnectedCarHandler extends ConnectedCarChannelHandler { StringResponseCallback allTripsCallback = new AllTripsCallback(); StringResponseCallback chargeProfileCallback = new ChargeProfilesCallback(); StringResponseCallback rangeMapCallback = new RangeMapCallback(); + StringResponseCallback destinationCallback = new DestinationsCallback(); ByteResponseCallback imageCallback = new ImageCallback(); private Optional vehicleStatusCache = Optional.empty(); @@ -97,6 +99,7 @@ public class ConnectedCarHandler extends ConnectedCarChannelHandler { private Optional allTripsCache = Optional.empty(); private Optional chargeProfileCache = Optional.empty(); private Optional rangeMapCache = Optional.empty(); + private Optional destinationCache = Optional.empty(); private Optional bridgeHandler = Optional.empty(); protected Optional> refreshJob = Optional.empty(); @@ -327,6 +330,7 @@ public void getData() { proxy.get().requestAllTrips(configuration.get(), allTripsCallback); proxy.get().requestChargingProfile(configuration.get(), chargeProfileCallback); } + proxy.get().requestDestinations(configuration.get(), destinationCallback); } else { logger.warn("ConnectedDrive Proxy isn't present"); } @@ -412,6 +416,44 @@ public void onError(NetworkError error) { } } + @NonNullByDefault + public class DestinationsCallback implements StringResponseCallback { + @Override + public void onResponse(Optional content) { + destinationCache = content; + if (content.isPresent()) { + DestinationContainer dc = GSON.fromJson(content.get(), DestinationContainer.class); + + if (dc.destinations != null) { + if (!dc.destinations.isEmpty()) { + updateState(destinationName1, StringType.valueOf(dc.destinations.get(0).getAddress())); + updateState(destinationLat1, new DecimalType(dc.destinations.get(0).lat)); + updateState(destinationLon1, new DecimalType(dc.destinations.get(0).lon)); + } + if (dc.destinations.size() > 1) { + updateState(destinationName2, StringType.valueOf(dc.destinations.get(1).getAddress())); + updateState(destinationLat2, new DecimalType(dc.destinations.get(1).lat)); + updateState(destinationLon2, new DecimalType(dc.destinations.get(1).lon)); + } + if (dc.destinations.size() > 2) { + updateState(destinationName3, StringType.valueOf(dc.destinations.get(2).getAddress())); + updateState(destinationLat3, new DecimalType(dc.destinations.get(2).lat)); + updateState(destinationLon3, new DecimalType(dc.destinations.get(2).lon)); + } + } + } + } + + /** + * Store Error Report in cache variable. Via Fingerprint Channel error is logged and Issue can be raised + */ + @Override + public void onError(NetworkError error) { + logger.debug("{}", error.toString()); + destinationCache = Optional.of(GSON.toJson(error)); + } + } + @NonNullByDefault public class ImageCallback implements ByteResponseCallback { @Override @@ -528,6 +570,8 @@ public void onResponse(Optional content) { if (vStatus == null) { return; } + + // Vehilce Status updateState(lock, StringType.valueOf(Converter.toTitleCase(vStatus.doorLockState))); Doors doorState = GSON.fromJson(GSON.toJson(vStatus), Doors.class); updateState(doors, StringType.valueOf(VehicleStatus.checkClosed(doorState))); @@ -535,9 +579,6 @@ public void onResponse(Optional content) { updateState(windows, StringType.valueOf(VehicleStatus.checkClosed(windowState))); updateState(checkControl, StringType.valueOf(vStatus.getCheckControl())); updateState(service, StringType.valueOf(vStatus.getNextService(imperial))); - if (isElectric) { - updateState(chargingStatus, StringType.valueOf(Converter.toTitleCase(vStatus.chargingStatus))); - } // Range values // based on unit of length decide if range shall be reported in km or miles @@ -593,6 +634,20 @@ public void onResponse(Optional content) { updateState(lastUpdate, new StringType(Converter.getZonedDateTime(vStatus.updateTime))); } + // Charge Values + if (isElectric) { + if (vStatus.chargingStatus != null) { + if (Constants.INVALID.equals(vStatus.chargingStatus)) { + updateState(chargingStatus, + StringType.valueOf(Converter.toTitleCase(vStatus.lastChargingEndReason))); + } else { + // State INVALID is somehow misleading. Instead show the Last Charging End Reason + updateState(chargingStatus, + StringType.valueOf(Converter.toTitleCase(vStatus.chargingStatus))); + } + } + } + Position p = vStatus.position; updateState(latitude, new DecimalType(p.lat)); updateState(longitude, new DecimalType(p.lon)); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java index f395102963de2..5861a5d77b08b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -38,10 +38,12 @@ public class Constants { public static final String NOT_SUPPORTED = "NOT_SUPPORTED"; // General Constants for String concatenation + public static final String NULL = "null"; public static final String SPACE = " "; public static final String UNDERLINE = "_"; public static final String HYPHEN = " - "; public static final String EMPTY = ""; + public static final String COMMA = ","; public static final String ANONYMOUS = "ANONYMOUS"; public static final int MILES_TO_FEET_FACTOR = 5280; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-groups.xml index d7ff8317649fe..1bf6a391fdec2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-groups.xml @@ -4,8 +4,8 @@ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - - Provides Status of Doors, Lock State, Service and Check Control Messages + + Charge Status and Charge Profiles of Vehicle diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-channel-types.xml new file mode 100644 index 0000000000000..b194fafbb361a --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-channel-types.xml @@ -0,0 +1,42 @@ + + + + String + + + + Number + + + + Number + + + + String + + + + Number + + + + Number + + + + String + + + + Number + + + + Number + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-group.xml new file mode 100644 index 0000000000000..abd07e7ddff8d --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-group.xml @@ -0,0 +1,21 @@ + + + + + Show the Last 3 Destinations + + + + + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml index 5217416bd5b96..b82c11b26d972 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml @@ -19,6 +19,7 @@ + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml index bb37a9d942265..394243244fd53 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml @@ -19,6 +19,7 @@ + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml index 362a582fd3718..59fdaee313266 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml @@ -16,6 +16,7 @@ + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml index cdd5cdd7d05c9..74768385bf6d9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml @@ -19,6 +19,7 @@ + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DestinationTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DestinationTest.java new file mode 100644 index 0000000000000..30f37978c0145 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DestinationTest.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; + +import static org.junit.Assert.*; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.junit.Test; +import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; + +/** + * The {@link DestinationTest} Test json responses from ConnectedDrive Portal + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class DestinationTest { + private final Logger logger = LoggerFactory.getLogger(DestinationTest.class); + private static final Gson GSON = new Gson(); + + @Test + public void testDestinations() { + String resource1 = FileReader.readFileInString("src/test/resources/webapi/destinations.json"); + DestinationContainer container = GSON.fromJson(resource1, DestinationContainer.class); + List destinations = container.destinations; + assertEquals("Number of Vehicles", 9, destinations.size()); + destinations.forEach(entry -> { + logger.info(entry.getAddress()); + assertFalse("No Null contained", entry.getAddress().contains(Constants.NULL)); + }); + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/StatusWrapper.java index 7cfb4b1d132cb..9b46fd763bc69 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/StatusWrapper.java @@ -31,6 +31,7 @@ import org.eclipse.smarthome.core.thing.ChannelUID; import org.eclipse.smarthome.core.types.State; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CarType; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import com.google.gson.Gson; @@ -178,7 +179,11 @@ private void checkResult(ChannelUID channelUID, State state) { assertTrue("Is Eelctric", isElectric); assertTrue(state instanceof StringType); st = (StringType) state; - assertEquals("Charge Status", Converter.toTitleCase(vStatus.chargingStatus), st.toString()); + if (vStatus.chargingStatus.contentEquals(Constants.INVALID)) { + assertEquals("Charge Status", Converter.toTitleCase(vStatus.lastChargingEndReason), st.toString()); + } else { + assertEquals("Charge Status", Converter.toTitleCase(vStatus.chargingStatus), st.toString()); + } break; case LAST_UPDATE: assertTrue(state instanceof StringType); From dd6e5f9aea3fcbd366aa6f2b7d5b5e8340265677 Mon Sep 17 00:00:00 2001 From: Bernd Date: Sat, 5 Sep 2020 22:43:41 +0200 Subject: [PATCH 018/176] de translations Signed-off-by: Bernd (cherry picked from commit 221ef95c20368a47b06307f17b9075657ec78865) Signed-off-by: Bernd --- .../README.md | 8 +- .../internal/ConnectedDriveConstants.java | 24 ++- .../discovery/ConnectedCarDiscovery.java | 6 +- .../internal/dto/Destination.java | 16 +- .../internal/dto/NetworkError.java | 5 + .../internal/dto/discovery/Vehicle.java | 6 +- .../handler/ConnectedCarChannelHandler.java | 58 ++++-- .../internal/handler/ConnectedCarHandler.java | 178 ++++++++++++++---- .../handler/ConnectedDriveBridgeHandler.java | 81 ++++---- .../handler/RemoteServiceHandler.java | 3 +- .../internal/utils/BimmerConstants.java | 1 + .../internal/utils/Constants.java | 6 + .../internal/utils/Converter.java | 64 +++++-- .../i18n/bmwconnecteddrive_be.properties | 140 ++++++++++++-- .../ESH-INF/thing/bridge-connected-drive.xml | 15 +- .../ESH-INF/thing/charge-channel-groups.xml | 17 +- .../ESH-INF/thing/charge-channel-types.xml | 52 +++++ .../thing/conv-range-channel-group.xml | 2 +- .../ESH-INF/thing/ev-last-trip-group.xml | 2 +- .../ESH-INF/thing/ev-lifetime-group.xml | 4 +- .../ESH-INF/thing/ev-range-channel-group.xml | 4 +- .../thing/hybrid-range-channel-group.xml | 5 +- .../ESH-INF/thing/image-channel-group.xml | 4 +- .../ESH-INF/thing/location-channel-group.xml | 4 +- .../ESH-INF/thing/range-channel-types.xml | 14 +- .../resources/ESH-INF/thing/thing-bev.xml | 12 +- .../resources/ESH-INF/thing/thing-bev_rex.xml | 15 +- .../resources/ESH-INF/thing/thing-conv.xml | 13 +- .../resources/ESH-INF/thing/thing-phev.xml | 15 +- .../thing/troubleshoot-channel-types.xml | 2 +- .../thing/vehicle-status-channel-types.xml | 4 - .../ESH-INF/thing/vehicle-status-group.xml | 2 +- .../internal/discovery/DiscoveryTest.java | 7 +- .../internal/dto/ChargeProfileTest.java | 46 +++++ .../internal/dto/ConnectedDriveTest.java | 16 +- .../dto/{statistics => }/LastTripTest.java | 4 +- .../dto/{remote => }/RemoteStatusTest.java | 4 +- .../dto/{status => }/StatusWrapper.java | 67 ++++--- .../dto/{status => }/VehicleStatusTest.java | 5 +- .../internal/handler/CarTests.java | 49 ++--- .../internal/handler/ChargeProfileTest.java | 121 ++++++++++++ .../internal/handler/FingerprintTest.java | 70 +++++++ .../internal/util/FileReader.java | 6 +- .../internal/util/LocaleTest.java | 8 + .../webapi/connected-drive-account-info.json | 14 +- .../test/resources/webapi/destinations.json | 103 +++++----- 46 files changed, 962 insertions(+), 340 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ChargeProfileTest.java rename bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/{statistics => }/LastTripTest.java (83%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/{remote => }/RemoteStatusTest.java (85%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/{status => }/StatusWrapper.java (81%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/{status => }/VehicleStatusTest.java (82%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/FingerprintTest.java diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index c5e4a7ae027f4..2e323a1d0f7c5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -3,8 +3,8 @@ The Binding connects your BMW Vehicles which are registered in the _Garage_ of your BMW ConnectedDrive Portal. -Due to the high variety of Cars and ConnectedDrive Services you need to check which Channels are applicable to your Car. -The Discovery Service recognizes your Car with the correct type +Due to the high variety of Cars and Online Services you need to check which Channels are applicable to your Vehicle. +The Discovery Service recognizes your Vehicle with the correct type * Conventional Fuel Vehicle * Plugin-Hybrid Electrical Vehicle @@ -14,6 +14,10 @@ The Discovery Service recognizes your Car with the correct type In addition Properties are attached to the Vehicle Thing to observe the Supported & Activated Services. Different Channel Groups are available so you are able to cross-check which group is supported by your Car. +Please note **this isn't a _real-time_ Binding**. +If you open the Door the state isn't transmitted immediately and shown in your GUI. +This isn't a flaw in the Binding itself because the state in BMWs own ConnectedDrive App is also updated with delay. + ## Supported Things ### Bridge diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 0a8b4ac4c5b02..6deb6c8659dad 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -24,6 +24,7 @@ * * @author Bernd Weymann - Initial contribution */ +@SuppressWarnings("serial") @NonNullByDefault public class ConnectedDriveConstants { @@ -93,9 +94,6 @@ public String toString() { } }; - // Bridge Channel - public static final String DISCOVERY_FINGERPRINT = "discovery-fingerprint"; - // Thing Group definitions public static final String CHANNEL_GROUP_STATUS = "status"; public static final String CHANNEL_GROUP_RANGE = "range"; @@ -117,7 +115,20 @@ public String toString() { public static final String CHECK_CONTROL = "check-control"; public static final String LAST_UPDATE = "last-update"; - public static final String CHARGING_STATUS = "charging-status"; + public static final String CHARGE_STATUS = "status"; + public static final String CHARGE_PROFILE_CLIMATE = "profile-climate"; + public static final String CHARGE_PROFILE_MODE = "profile-mode"; + public static final String CHARGE_WINDOW_START = "window-start"; + public static final String CHARGE_WINDOW_END = "window-end"; + public static final String CHARGE_TIMER1_DEPARTURE = "timer1-departure"; + public static final String CHARGE_TIMER1_DAYS = "timer1-days"; + public static final String CHARGE_TIMER1_ENABLED = "timer1-enabled"; + public static final String CHARGE_TIMER2_DEPARTURE = "timer2-departure"; + public static final String CHARGE_TIMER2_DAYS = "timer2-days"; + public static final String CHARGE_TIMER2_ENABLED = "timer2-enabled"; + public static final String CHARGE_TIMER3_DEPARTURE = "timer3-departure"; + public static final String CHARGE_TIMER3_ENABLED = "timer3-days"; + public static final String CHARGE_TIMER3_DAYS = "timer3-enabled"; // Range public static final String MILEAGE = "mileage"; @@ -126,6 +137,9 @@ public String toString() { public static final String SOC = "soc"; public static final String RANGE_FUEL = "fuel"; public static final String REMAINING_FUEL = "remaining-fuel"; + public static final String RANGE_RADIUS_ELECTRIC = "radius-electric"; + public static final String RANGE_RADIUS_FUEL = "radius-fuel"; + public static final String RANGE_RADIUS_HYBRID = "radius-hybrid"; // Lifetime public static final String AVG_CONSUMPTION = "average-consumption"; @@ -140,9 +154,7 @@ public String toString() { // Lifetime public static final String LONGITUDE = "longitude"; public static final String LATITUDE = "latitude"; - public static final String LATLONG = "latlong"; public static final String HEADING = "heading"; - public static final String RANGE_RADIUS = "radius"; // Image public static final String IMAGE = "png"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java index 2992fc7347f71..706fa399dd26e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java @@ -82,11 +82,11 @@ public void onResponse(VehiclesContainer container) { String servicesSupported = getObject(vehicle, Constants.SUPPORTED); String servicesNotSupported = getObject(vehicle, Constants.NOT_SUPPORTED); if (vehicle.statisticsAvailable) { - servicesSupported += "Statistics"; + servicesSupported += Constants.STATISTICS; } else { - servicesNotSupported += "Statistics"; + servicesNotSupported += Constants.STATISTICS; } - properties.put("Services Supported", servicesSupported); + properties.put(Constants.SERVICES_SUPPORTED, servicesSupported); properties.put("Services Not Supported", servicesNotSupported); properties.put("Support Breakdown Number", vehicle.breakdownNumber); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java index 9c8169d6fa62e..e8f4b5d4f6957 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java @@ -22,14 +22,14 @@ * @author Bernd Weymann - Initial contribution */ public class Destination { - public float lat;// ": 50.55577087402344, - public float lon;// ": 8.495763778686523, - public String country;// ": "DEUTSCHLAND", - public String city;// ": "WETZLAR", - public String street;// ": "UFERSTRASSE", - public String streetNumber;// ": "4", - public String type;// ": "DESTINATION", - public String createdAt;// ": "2020-08-16T12:52:58+0000" + public float lat; + public float lon; + public String country; + public String city; + public String street; + public String streetNumber; + public String type; + public String createdAt; public String getAddress() { StringBuffer buf = new StringBuffer(); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/NetworkError.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/NetworkError.java index 037878ca44a5d..778f8ac00b637 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/NetworkError.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/NetworkError.java @@ -13,6 +13,7 @@ package org.openhab.binding.bmwconnecteddrive.internal.dto; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; /** * The {@link NetworkError} Data Transfer Object @@ -29,4 +30,8 @@ public String toString() { return new StringBuffer(url).append(Constants.HYPHEN).append(status).append(Constants.HYPHEN).append(reason) .toString(); } + + public String toJson() { + return Converter.getGson().toJson(this); + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Vehicle.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Vehicle.java index bebb26e662686..df515dffb4e14 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Vehicle.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Vehicle.java @@ -12,7 +12,6 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.dto.discovery; -import java.util.ArrayList; import java.util.List; /** @@ -35,8 +34,7 @@ public class Vehicle { public String breakdownNumber; public List supportedChargingModes; - public List activatedServices = new ArrayList(); - public List notActivatedServices = new ArrayList(); + // Remote Services public String vehicleFinder; // ACTIVATED public String hornBlow; // ACTIVATED public String lightFlash; // ACTIVATED @@ -45,8 +43,6 @@ public class Vehicle { public String climateNow; // ACTIVATED public String sendPoi; // ACTIVATED - public List supportedServices = new ArrayList(); - public List notSupportedServices = new ArrayList(); public String remote360; // SUPPORTED public String climateControl; // SUPPORTED public String chargeNow; // SUPPORTED diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java index 56b3112ea1bf5..9287115af7e16 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarChannelHandler.java @@ -35,7 +35,7 @@ public class ConnectedCarChannelHandler extends BaseThingHandler { protected ChannelUID lock; protected ChannelUID service; protected ChannelUID checkControl; - protected ChannelUID chargingStatus; + protected ChannelUID lastUpdate; // Range channels protected ChannelUID mileage; @@ -44,7 +44,9 @@ public class ConnectedCarChannelHandler extends BaseThingHandler { protected ChannelUID remainingSoc; protected ChannelUID remainingRangeFuel; protected ChannelUID remainingFuel; - protected ChannelUID lastUpdate; + protected ChannelUID rangeRadiusElectric; + protected ChannelUID rangeRadiusFuel; + protected ChannelUID rangeRadiusHybrid; // Lifetime Efficiency Channels protected ChannelUID lifeTimeAverageConsumption; @@ -61,12 +63,7 @@ public class ConnectedCarChannelHandler extends BaseThingHandler { // Location Channels protected ChannelUID longitude; protected ChannelUID latitude; - protected ChannelUID latlong; protected ChannelUID heading; - protected ChannelUID rangeRadius; - - // Image - protected ChannelUID imageChannel; // Remote Services protected ChannelUID remoteLightChannel; @@ -88,9 +85,28 @@ public class ConnectedCarChannelHandler extends BaseThingHandler { protected ChannelUID destinationLat3; protected ChannelUID destinationLon3; + // Charging + protected ChannelUID chargingStatus; + protected ChannelUID chargeProfileClimate; + protected ChannelUID chargeProfileChargeMode; + protected ChannelUID chargeWindowStart; + protected ChannelUID chargeWindowEnd; + protected ChannelUID timer1Departure; + protected ChannelUID timer1Enabled; + protected ChannelUID timer1Days; + protected ChannelUID timer2Departure; + protected ChannelUID timer2Enabled; + protected ChannelUID timer2Days; + protected ChannelUID timer3Departure; + protected ChannelUID timer3Enabled; + protected ChannelUID timer3Days; + // Troubleshooting protected ChannelUID vehicleFingerPrint; + // Image + protected ChannelUID imageChannel; + public ConnectedCarChannelHandler(Thing thing) { super(thing); @@ -102,17 +118,16 @@ public ConnectedCarChannelHandler(Thing thing) { checkControl = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, CHECK_CONTROL); lastUpdate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, LAST_UPDATE); - // Charge Channels - chargingStatus = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGING_STATUS); - // range Channels mileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, MILEAGE); remainingRangeHybrid = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, RANGE_HYBRID); remainingRangeElectric = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, RANGE_ELECTRIC); - remainingSoc = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, SOC); remainingRangeFuel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, RANGE_FUEL); + remainingSoc = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, SOC); remainingFuel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_FUEL); - rangeRadius = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, RANGE_RADIUS); + rangeRadiusElectric = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, RANGE_RADIUS_ELECTRIC); + rangeRadiusFuel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, RANGE_RADIUS_FUEL); + rangeRadiusHybrid = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, RANGE_RADIUS_HYBRID); // Last Trip Channels tripDistance = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, DISTANCE); @@ -130,10 +145,23 @@ public ConnectedCarChannelHandler(Thing thing) { // Location Channels longitude = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, LONGITUDE); latitude = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, LATITUDE); - latlong = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, LATLONG); heading = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, HEADING); - imageChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CAR_IMAGE, IMAGE); + // Charge Channels + chargingStatus = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_STATUS); + chargeProfileClimate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_PROFILE_CLIMATE); + chargeProfileChargeMode = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_PROFILE_MODE); + chargeWindowStart = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_WINDOW_START); + chargeWindowEnd = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_WINDOW_END); + timer1Departure = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DEPARTURE); + timer1Enabled = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_ENABLED); + timer1Days = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DAYS); + timer2Departure = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DEPARTURE); + timer2Enabled = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_ENABLED); + timer2Days = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DAYS); + timer3Departure = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DEPARTURE); + timer3Enabled = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAYS); + timer3Days = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_ENABLED); remoteLightChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_LIGHT_FLASH); remoteFinderChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_VEHICLE_FINDER); @@ -153,6 +181,8 @@ public ConnectedCarChannelHandler(Thing thing) { destinationLat3 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_LAT_3); destinationLon3 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_LON_3); + imageChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CAR_IMAGE, IMAGE); + vehicleFingerPrint = new ChannelUID(thing.getUID(), CHANNEL_GROUP_TROUBLESHOOT, VEHICLE_FINGERPRINT); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java index bedeabf8ecaf0..9d840099e9c64 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedCarHandler.java @@ -15,6 +15,7 @@ import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; import java.time.LocalDateTime; +import java.util.List; import java.util.Optional; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -45,6 +46,10 @@ import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CarType; import org.openhab.binding.bmwconnecteddrive.internal.dto.DestinationContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; +import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.ChargeProfile; +import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.ChargingWindow; +import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.Timer; +import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.WeeklyPlanner; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTrips; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTripsContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTrip; @@ -61,8 +66,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.gson.Gson; - /** * The {@link ConnectedCarHandler} is responsible for handling commands, which are * sent to one of the channels. @@ -73,11 +76,11 @@ public class ConnectedCarHandler extends ConnectedCarChannelHandler { private final Logger logger = LoggerFactory.getLogger(ConnectedCarHandler.class); - static final Gson GSON = new Gson(); - private Optional proxy = Optional.empty(); private Optional remote = Optional.empty(); private Optional configuration = Optional.empty(); + private Optional bridgeHandler = Optional.empty(); + private Optional> refreshJob = Optional.empty(); private boolean imperial = false; private boolean hasFuel = false; @@ -101,9 +104,6 @@ public class ConnectedCarHandler extends ConnectedCarChannelHandler { private Optional rangeMapCache = Optional.empty(); private Optional destinationCache = Optional.empty(); - private Optional bridgeHandler = Optional.empty(); - protected Optional> refreshJob = Optional.empty(); - public ConnectedCarHandler(Thing thing, HttpClient hc, String type, boolean imperial) { super(thing); this.imperial = imperial; @@ -112,7 +112,6 @@ public ConnectedCarHandler(Thing thing, HttpClient hc, String type, boolean impe isElectric = type.equals(CarType.PLUGIN_HYBRID.toString()) || type.equals(CarType.ELECTRIC_REX.toString()) || type.equals(CarType.ELECTRIC.toString()); isHybrid = hasFuel && isElectric; - logger.debug("DriveTrain {} isElectric {} hasFuel {} Imperial {}", type, isElectric, hasFuel, imperial); } @Override @@ -178,11 +177,15 @@ public void handleCommand(ChannelUID channelUID, Command command) { logger.info("Trigger Vehicle Fingerprint"); if (command instanceof OnOffType) { if (command.equals(OnOffType.ON)) { - logger.warn("BMW ConnectedDrive Binding - Car Data Troubleshoot fingerprint - BEGIN"); + logger.warn( + "###### BMW ConnectedDrive Binding - Vehicle Troubleshoot Fingerprint Data - BEGIN ######"); + logger.warn("### Discovery Result ###"); + logger.warn("{}", bridgeHandler.get().getDiscoveryFingerprint()); if (vehicleStatusCache.isPresent()) { logger.warn("### Vehicle Status ###"); + // Anonymous data for VIN and Position - VehicleStatusContainer container = GSON.fromJson(vehicleStatusCache.get(), + VehicleStatusContainer container = Converter.getGson().fromJson(vehicleStatusCache.get(), VehicleStatusContainer.class); VehicleStatus status = container.vehicleStatus; status.vin = Constants.ANONYMOUS; @@ -190,7 +193,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { status.position.lat = -1; status.position.lon = -1; status.position.heading = -1; - logger.warn("{}", GSON.toJson(container)); + logger.warn("{}", Converter.getGson().toJson(container)); } } else { logger.warn("### Vehicle Status Empty ###"); @@ -218,6 +221,26 @@ public void handleCommand(ChannelUID channelUID, Command command) { logger.warn("### Charge Profile Empty ###"); } } + if (destinationCache.isPresent()) { + logger.warn("### Charge Profile ###"); + DestinationContainer container = Converter.getGson().fromJson(destinationCache.get(), + DestinationContainer.class); + if (container.destinations != null) { + container.destinations.forEach(entry -> { + entry.lat = 0; + entry.lon = 0; + entry.city = Constants.ANONYMOUS; + entry.street = Constants.ANONYMOUS; + entry.streetNumber = Constants.ANONYMOUS; + entry.country = Constants.ANONYMOUS; + }); + logger.warn("{}", Converter.getGson().toJson(container)); + } else { + logger.warn("### Destinations Empty ###"); + } + } else { + logger.warn("### Charge Profile Empty ###"); + } if (rangeMapCache.isPresent()) { logger.warn("### Range Map ###"); logger.warn("{}", @@ -225,7 +248,8 @@ public void handleCommand(ChannelUID channelUID, Command command) { } else { logger.warn("### Range Map Empty ###"); } - logger.warn("BMW ConnectedDrive Binding - Car Data Troubleshoot fingerprint - END"); + logger.warn( + "###### BMW ConnectedDrive Binding - Vehicle Troubleshoot Fingerprint Data - END ######"); } // Switch back to off immediately updateState(channelUID, OnOffType.OFF); @@ -325,18 +349,42 @@ public void dispose() { public void getData() { if (proxy.isPresent() && configuration.isPresent()) { proxy.get().requestVehcileStatus(configuration.get(), vehicleStatusCallback); - if (isElectric) { + if (isSupported(Constants.STATISTICS)) { proxy.get().requestLastTrip(configuration.get(), lastTripCallback); proxy.get().requestAllTrips(configuration.get(), allTripsCallback); + } + if (isSupported(Constants.LAST_DESTINATIONS)) { + proxy.get().requestDestinations(configuration.get(), destinationCallback); + } + if (isElectric) { proxy.get().requestChargingProfile(configuration.get(), chargeProfileCallback); } - proxy.get().requestDestinations(configuration.get(), destinationCallback); } else { logger.warn("ConnectedDrive Proxy isn't present"); } } - void requestRangeMap(Position p) { + /** + * Don't stress ConnectedDrive with unnecessary requests. One call at the beginning is done to check the response. + * After cache has e.g. a proper error response it will be shown in the fingerprint + * + * @return + */ + private boolean isSupported(String service) { + if (thing.getProperties().containsKey(Constants.SERVICES_SUPPORTED)) { + if (thing.getProperties().get(Constants.SERVICES_SUPPORTED).contains(Constants.STATISTICS)) { + return true; + } + } + // if cache is empty give it a try one time to collected Troubleshoot data + if (!lastTripCache.isPresent() || !allTripsCache.isPresent() || !destinationCache.isPresent()) { + return true; + } else { + return false; + } + } + + private void requestRangeMap(Position p) { // format_string = '%Y-%m-%dT%H:%M:%S' // timestamp = datetime.datetime.now().strftime(format_string) // params = { @@ -344,7 +392,7 @@ void requestRangeMap(Position p) { // 'dlat': self._vehicle.observer_latitude, // 'dlon': self._vehicle.observer_longitude, // } - double diff = Converter.measure(p.lat, p.lon, currentPosition.lat, currentPosition.lon); + double diff = Converter.measureDistance(p.lat, p.lon, currentPosition.lat, currentPosition.lon); if (diff > 1000) { logger.info("Difference between old {} and new Position {} = {}", currentPosition.toString(), p.toString(), diff); @@ -382,11 +430,51 @@ public ScheduledExecutorService getScheduler() { * @author Bernd Weymann * */ - @NonNullByDefault + @NonNullByDefault({}) public class ChargeProfilesCallback implements StringResponseCallback { @Override public void onResponse(Optional content) { chargeProfileCache = content; + if (content.isPresent()) { + ChargeProfile cp = Converter.getGson().fromJson(content.get(), ChargeProfile.class); + WeeklyPlanner planner = cp.weeklyPlanner; + updateState(chargeProfileClimate, OnOffType.from(planner.climatizationEnabled)); + updateState(chargeProfileChargeMode, StringType.valueOf(planner.chargingMode)); + + ChargingWindow cw = planner.preferredChargingWindow; + updateState(chargeWindowStart, StringType.valueOf(cw.startTime)); + updateState(chargeWindowEnd, StringType.valueOf(cw.endTime)); + + Timer t1 = planner.timer1; + updateState(timer1Departure, StringType.valueOf(t1.departureTime)); + updateState(timer1Enabled, OnOffType.from(t1.timerEnabled)); + updateState(timer1Days, StringType.valueOf(getDays(t1.weekdays))); + + Timer t2 = planner.timer2; + updateState(timer2Departure, StringType.valueOf(t2.departureTime)); + updateState(timer2Enabled, OnOffType.from(t2.timerEnabled)); + updateState(timer2Days, StringType.valueOf(getDays(t2.weekdays))); + + Timer t3 = planner.timer3; + updateState(timer3Departure, StringType.valueOf(t3.departureTime)); + updateState(timer3Enabled, OnOffType.from(t3.timerEnabled)); + updateState(timer3Days, StringType.valueOf(getDays(t3.weekdays))); + } + } + + private String getDays(List l) { + if (l == null) { + return Converter.toTitleCase(Constants.UNKNOWN); + } + StringBuffer days = new StringBuffer(); + l.forEach(entry -> { + if (days.length() == 0) { + days.append(entry); + } else { + days.append(Constants.COMMA).append(entry); + } + }); + return days.toString(); } /** @@ -395,11 +483,11 @@ public void onResponse(Optional content) { @Override public void onError(NetworkError error) { logger.debug("{}", error.toString()); - chargeProfileCache = Optional.of(GSON.toJson(error)); + chargeProfileCache = Optional.of(Converter.getGson().toJson(error)); } } - @NonNullByDefault + @NonNullByDefault({}) public class RangeMapCallback implements StringResponseCallback { @Override public void onResponse(Optional content) { @@ -412,17 +500,17 @@ public void onResponse(Optional content) { @Override public void onError(NetworkError error) { logger.debug("{}", error.toString()); - rangeMapCache = Optional.of(GSON.toJson(error)); + rangeMapCache = Optional.of(Converter.getGson().toJson(error)); } } - @NonNullByDefault + @NonNullByDefault({}) public class DestinationsCallback implements StringResponseCallback { @Override public void onResponse(Optional content) { destinationCache = content; if (content.isPresent()) { - DestinationContainer dc = GSON.fromJson(content.get(), DestinationContainer.class); + DestinationContainer dc = Converter.getGson().fromJson(content.get(), DestinationContainer.class); if (dc.destinations != null) { if (!dc.destinations.isEmpty()) { @@ -450,11 +538,11 @@ public void onResponse(Optional content) { @Override public void onError(NetworkError error) { logger.debug("{}", error.toString()); - destinationCache = Optional.of(GSON.toJson(error)); + destinationCache = Optional.of(Converter.getGson().toJson(error)); } } - @NonNullByDefault + @NonNullByDefault({}) public class ImageCallback implements ByteResponseCallback { @Override public void onResponse(Optional content) { @@ -473,13 +561,13 @@ public void onError(NetworkError error) { } } - @NonNullByDefault + @NonNullByDefault({}) public class AllTripsCallback implements StringResponseCallback { @Override public void onResponse(Optional content) { if (content.isPresent()) { allTripsCache = content; - AllTripsContainer at = GSON.fromJson(content.get(), AllTripsContainer.class); + AllTripsContainer at = Converter.getGson().fromJson(content.get(), AllTripsContainer.class); AllTrips c = at.allTrips; if (c == null) { return; @@ -503,17 +591,17 @@ public void onResponse(Optional content) { @Override public void onError(NetworkError error) { logger.debug("{}", error.toString()); - allTripsCache = Optional.of(GSON.toJson(error)); + allTripsCache = Optional.of(Converter.getGson().toJson(error)); } } - @NonNullByDefault + @NonNullByDefault({}) public class LastTripCallback implements StringResponseCallback { @Override public void onResponse(Optional content) { if (content.isPresent()) { lastTripCache = content; - LastTripContainer lt = GSON.fromJson(content.get(), LastTripContainer.class); + LastTripContainer lt = Converter.getGson().fromJson(content.get(), LastTripContainer.class); LastTrip trip = lt.lastTrip; if (trip == null) { return; @@ -535,14 +623,14 @@ public void onResponse(Optional content) { @Override public void onError(NetworkError error) { logger.debug("{}", error.toString()); - lastTripCache = Optional.of(GSON.toJson(error)); + lastTripCache = Optional.of(Converter.getGson().toJson(error)); } } /** * The VehicleStatus is supported by all Car Types so it's used to reflect the Thing Status */ - @NonNullByDefault + @NonNullByDefault({}) public class VehicleStatusCallback implements StringResponseCallback { private ThingStatus thingStatus = ThingStatus.UNKNOWN; @@ -565,7 +653,8 @@ public void onResponse(Optional content) { if (content.isPresent()) { setThingStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE, Constants.EMPTY); vehicleStatusCache = content; - VehicleStatusContainer status = GSON.fromJson(content.get(), VehicleStatusContainer.class); + VehicleStatusContainer status = Converter.getGson().fromJson(content.get(), + VehicleStatusContainer.class); VehicleStatus vStatus = status.vehicleStatus; if (vStatus == null) { return; @@ -573,9 +662,9 @@ public void onResponse(Optional content) { // Vehilce Status updateState(lock, StringType.valueOf(Converter.toTitleCase(vStatus.doorLockState))); - Doors doorState = GSON.fromJson(GSON.toJson(vStatus), Doors.class); + Doors doorState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Doors.class); updateState(doors, StringType.valueOf(VehicleStatus.checkClosed(doorState))); - Windows windowState = GSON.fromJson(GSON.toJson(vStatus), Windows.class); + Windows windowState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Windows.class); updateState(windows, StringType.valueOf(VehicleStatus.checkClosed(windowState))); updateState(checkControl, StringType.valueOf(vStatus.getCheckControl())); updateState(service, StringType.valueOf(vStatus.getNextService(imperial))); @@ -589,18 +678,24 @@ public void onResponse(Optional content) { totalRange += vStatus.remainingRangeElectric; updateState(remainingRangeElectric, QuantityType.valueOf(vStatus.remainingRangeElectric, MetricPrefix.KILO(SIUnits.METRE))); + updateState(rangeRadiusElectric, + QuantityType.valueOf(Converter.guessRangeRadius(vStatus.remainingRangeElectric), + MetricPrefix.KILO(SIUnits.METRE))); } if (hasFuel) { totalRange += vStatus.remainingRangeFuel; updateState(remainingRangeFuel, QuantityType.valueOf(vStatus.remainingRangeFuel, MetricPrefix.KILO(SIUnits.METRE))); + updateState(rangeRadiusFuel, + QuantityType.valueOf(Converter.guessRangeRadius(vStatus.remainingRangeFuel), + MetricPrefix.KILO(SIUnits.METRE))); } if (isHybrid) { updateState(remainingRangeHybrid, QuantityType.valueOf(Converter.round(totalRange), MetricPrefix.KILO(SIUnits.METRE))); + updateState(rangeRadiusHybrid, QuantityType.valueOf(Converter.guessRangeRadius(totalRange), + MetricPrefix.KILO(SIUnits.METRE))); } - updateState(rangeRadius, - QuantityType.valueOf(Converter.guessRange(totalRange), MetricPrefix.KILO(SIUnits.METRE))); } else { updateState(mileage, QuantityType.valueOf(vStatus.mileage, ImperialUnits.MILE)); float totalRange = 0; @@ -608,18 +703,22 @@ public void onResponse(Optional content) { totalRange += vStatus.remainingRangeElectricMls; updateState(remainingRangeElectric, QuantityType.valueOf(vStatus.remainingRangeElectricMls, ImperialUnits.MILE)); + updateState(rangeRadiusElectric, QuantityType.valueOf( + Converter.guessRangeRadius(vStatus.remainingRangeElectricMls), ImperialUnits.MILE)); } if (hasFuel) { totalRange += vStatus.remainingRangeFuelMls; updateState(remainingRangeFuel, QuantityType.valueOf(vStatus.remainingRangeFuelMls, ImperialUnits.MILE)); + updateState(rangeRadiusFuel, QuantityType.valueOf( + Converter.guessRangeRadius(vStatus.remainingRangeFuelMls), ImperialUnits.MILE)); } if (isHybrid) { updateState(remainingRangeHybrid, QuantityType.valueOf(Converter.round(totalRange), ImperialUnits.MILE)); + updateState(rangeRadiusHybrid, + QuantityType.valueOf(Converter.guessRangeRadius(totalRange), ImperialUnits.MILE)); } - updateState(rangeRadius, - QuantityType.valueOf(Converter.guessRange(totalRange), ImperialUnits.MILE)); } if (isElectric) { updateState(remainingSoc, QuantityType.valueOf(vStatus.chargingLevelHv, SmartHomeUnits.PERCENT)); @@ -651,7 +750,6 @@ public void onResponse(Optional content) { Position p = vStatus.position; updateState(latitude, new DecimalType(p.lat)); updateState(longitude, new DecimalType(p.lon)); - updateState(latlong, StringType.valueOf(p.toString())); updateState(heading, QuantityType.valueOf(p.heading, SmartHomeUnits.DEGREE_ANGLE)); requestRangeMap(p); } @@ -660,7 +758,7 @@ public void onResponse(Optional content) { @Override public void onError(NetworkError error) { logger.debug("{}", error.toString()); - vehicleStatusCache = Optional.of(GSON.toJson(error)); + vehicleStatusCache = Optional.of(Converter.getGson().toJson(error)); setThingStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, error.reason); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java index 3b09f42e33354..041052426204f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java @@ -12,7 +12,6 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.handler; -import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.DISCOVERY_FINGERPRINT; import static org.openhab.binding.bmwconnecteddrive.internal.utils.Constants.ANONYMOUS; import java.util.Hashtable; @@ -23,7 +22,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jetty.client.HttpClient; import org.eclipse.smarthome.config.discovery.DiscoveryService; -import org.eclipse.smarthome.core.library.types.OnOffType; import org.eclipse.smarthome.core.thing.Bridge; import org.eclipse.smarthome.core.thing.ChannelUID; import org.eclipse.smarthome.core.thing.ThingStatus; @@ -35,13 +33,13 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; import org.openhab.binding.bmwconnecteddrive.internal.dto.discovery.Dealer; import org.openhab.binding.bmwconnecteddrive.internal.dto.discovery.VehiclesContainer; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.gson.Gson; - /** * The {@link ConnectedDriveBridgeHandler} is responsible for handling commands, which are * sent to one of the channels. @@ -51,7 +49,6 @@ @NonNullByDefault public class ConnectedDriveBridgeHandler extends BaseBridgeHandler implements StringResponseCallback { private final Logger logger = LoggerFactory.getLogger(ConnectedDriveBridgeHandler.class); - private static final Gson GSON = new Gson(); private HttpClient httpClient; private BundleContext bundleContext; private ConnectedCarDiscovery discoveryService; @@ -61,8 +58,6 @@ public class ConnectedDriveBridgeHandler extends BaseBridgeHandler implements St private Optional> refreshJob = Optional.empty(); private Optional troubleshootFingerprint = Optional.empty(); - private ChannelUID discoveryfingerPrint; - public ConnectedDriveBridgeHandler(Bridge bridge, HttpClient hc, BundleContext bc) { super(bridge); httpClient = hc; @@ -70,27 +65,10 @@ public ConnectedDriveBridgeHandler(Bridge bridge, HttpClient hc, BundleContext b discoveryService = new ConnectedCarDiscovery(this); discoveryServiceRegstration = bundleContext.registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<>()); - discoveryfingerPrint = new ChannelUID(thing.getUID(), DISCOVERY_FINGERPRINT); } @Override public void handleCommand(ChannelUID channelUID, Command command) { - if (command instanceof OnOffType) { - if (command.equals(OnOffType.ON)) { - if (channelUID.getIdWithoutGroup().equals(DISCOVERY_FINGERPRINT)) { - if (troubleshootFingerprint.isPresent()) { - logger.warn("BMW ConnectedDrive Binding - Discovery Troubleshoot fingerprint - BEGIN"); - logger.warn("{}", troubleshootFingerprint.get()); - logger.warn("BMW ConnectedDrive Binding - Discovery Troubleshoot fingerprint - END"); - } else { - logger.warn( - "BMW ConnectedDrive Binding - No Discovery Troubleshoot fingerprint available. Please check for valid username and password Settings for proper connection towards ConnectDrive"); - } - // Switch back to off immediately - updateState(discoveryfingerPrint, OnOffType.OFF); - } - } - } } @Override @@ -104,7 +82,6 @@ public void initialize() { } else { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR); } - updateState(discoveryfingerPrint, OnOffType.OFF); } @Override @@ -120,18 +97,13 @@ public void requestVehicles() { } } - /** - * There's only the Vehicles response available - */ - @Override - public void onResponse(Optional response) { - if (response.isPresent()) { - VehiclesContainer container = GSON.fromJson(response.get(), VehiclesContainer.class); - discoveryService.onResponse(container); - updateStatus(ThingStatus.ONLINE); + public String getDiscoveryFingerprint() { + if (troubleshootFingerprint.isPresent()) { + VehiclesContainer container = Converter.getGson().fromJson(troubleshootFingerprint.get(), + VehiclesContainer.class); if (container.vehicles != null) { if (container.vehicles.isEmpty()) { - troubleshootFingerprint = Optional.of("No Cars found in your ConnectedDrive Account"); + return Constants.EMPTY_VEHICLES; } else { container.vehicles.forEach(entry -> { entry.vin = ANONYMOUS; @@ -146,16 +118,51 @@ public void onResponse(Optional response) { d.street = ANONYMOUS; } }); - troubleshootFingerprint = Optional.of(GSON.toJson(container)); + return Converter.getGson().toJson(container); } + } else { + // Vehicles is empty so deliver fingerprint as it is + return troubleshootFingerprint.get(); + } + } else { + return Constants.INVALID; + } + } + + /** + * There's only the Vehicles response available + */ + @Override + public void onResponse(Optional response) { + if (response.isPresent()) { + troubleshootFingerprint = response; + VehiclesContainer container = Converter.getGson().fromJson(response.get(), VehiclesContainer.class); + updateStatus(ThingStatus.ONLINE); + if (container.vehicles != null) { + discoveryService.onResponse(container); + container.vehicles.forEach(entry -> { + entry.vin = ANONYMOUS; + entry.breakdownNumber = ANONYMOUS; + if (entry.dealer != null) { + Dealer d = entry.dealer; + d.city = ANONYMOUS; + d.country = ANONYMOUS; + d.name = ANONYMOUS; + d.phone = ANONYMOUS; + d.postalCode = ANONYMOUS; + d.street = ANONYMOUS; + } + }); + troubleshootFingerprint = Optional.of(Converter.getGson().toJson(container)); } } else { - logger.info("No Vehciles found"); + troubleshootFingerprint = Optional.of(Constants.EMPTY_VEHICLES); } } @Override public void onError(NetworkError error) { + troubleshootFingerprint = Optional.of(error.toJson()); updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, error.reason); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java index 3f9e22accf595..74cff9eda8ac8 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -30,6 +30,7 @@ import org.eclipse.jetty.util.UrlEncoded; import org.openhab.binding.bmwconnecteddrive.internal.dto.remote.ExecutionStatus; import org.openhab.binding.bmwconnecteddrive.internal.dto.remote.ExecutionStatusContainer; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -181,7 +182,7 @@ public void getState() { } else { String state = contentResponse.getContentAsString(); logger.info("Executed {}, Response {}", serviceExecuting.get(), state); - ExecutionStatusContainer esc = ConnectedCarHandler.GSON.fromJson(state, ExecutionStatusContainer.class); + ExecutionStatusContainer esc = Converter.getGson().fromJson(state, ExecutionStatusContainer.class); ExecutionStatus execStatus = esc.executionStatus; handler.updateRemoteExecutionStatus(serviceExecuting.get(), execStatus.status); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java index d1a2b027c9bae..69b5f55d76b94 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java @@ -26,6 +26,7 @@ * * @author Bernd Weymann - Initial contribution */ +@SuppressWarnings("serial") @NonNullByDefault public class BimmerConstants { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java index 5861a5d77b08b..f78bb8002f4e6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -32,6 +32,11 @@ public class Constants { public static final String MILES_SHORT = "mi"; public static final String KM_SHORT = "km"; + // Services to query + public static final String SERVICES_SUPPORTED = "Services Supported"; + public static final String STATISTICS = "Statistics"; + public static final String LAST_DESTINATIONS = "LastDestinations"; + // Services in Discovery public static final String ACTIVATED = "ACTIVATED"; public static final String SUPPORTED = "SUPPORTED"; @@ -47,4 +52,5 @@ public class Constants { public static final String ANONYMOUS = "ANONYMOUS"; public static final int MILES_TO_FEET_FACTOR = 5280; + public static final String EMPTY_VEHICLES = "{}"; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java index aa9d68f48b90c..33f108e28fdb5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java @@ -18,6 +18,9 @@ import java.time.format.DateTimeFormatter; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +import com.google.gson.Gson; /** * The {@link Converter} Data Transfer Object @@ -34,12 +37,14 @@ public class Converter { .ofPattern("yyyy-MM-dd'T'HH:mm:ssZ"); private static final DateTimeFormatter DATE_OUTPUT_PATTERN = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); + private static final Gson GSON = new Gson(); + public static double round(double value) { double scale = Math.pow(10, 1); return Math.round(value * scale) / scale; } - public static String getLocalDateTime(String input) { + public static String getLocalDateTime(@Nullable String input) { if (input == null) { return Converter.toTitleCase(Constants.UNKNOWN); } @@ -50,7 +55,7 @@ public static String getLocalDateTime(String input) { return zdtLZ.format(Converter.DATE_OUTPUT_PATTERN); } - public static String getZonedDateTime(String input) { + public static String getZonedDateTime(@Nullable String input) { if (input == null) { return Converter.toTitleCase(Constants.UNKNOWN); } @@ -60,7 +65,7 @@ public static String getZonedDateTime(String input) { return zdtLZ.format(Converter.DATE_OUTPUT_PATTERN); } - public static String toTitleCase(String input) { + public static String toTitleCase(@Nullable String input) { if (input == null) { return Converter.toTitleCase(Constants.UNKNOWN); } else { @@ -78,23 +83,48 @@ public static String capitalizeFirst(String str) { return str.substring(0, 1).toUpperCase() + str.substring(1); } - public static double measure(float lat1, float lon1, float lat2, float lon2) { + /** + * Measure distance between 2 coordinates + * + * @param sourceLatitude + * @param sourceLongitude + * @param destinationLatitude + * @param destinationLongitude + * @return distance + */ + public static double measureDistance(float sourceLatitude, float sourceLongitude, float destinationLatitude, + float destinationLongitude) { double earthRadius = 6378.137; // Radius of earth in KM - double dLat = lat2 * Math.PI / 180 - lat1 * Math.PI / 180; - double dLon = lon2 * Math.PI / 180 - lon1 * Math.PI / 180; - double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat1 * Math.PI / 180) - * Math.cos(lat2 * Math.PI / 180) * Math.sin(dLon / 2) * Math.sin(dLon / 2); + double dLat = destinationLatitude * Math.PI / 180 - sourceLatitude * Math.PI / 180; + double dLon = destinationLongitude * Math.PI / 180 - sourceLongitude * Math.PI / 180; + double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(sourceLatitude * Math.PI / 180) + * Math.cos(destinationLatitude * Math.PI / 180) * Math.sin(dLon / 2) * Math.sin(dLon / 2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - double d = earthRadius * c; - return d * 1000; // meters + return earthRadius * c; } - public static double guessRange(float totalRange) { - // Simple guess right now - if (totalRange < 20) { - return totalRange * 0.8; - } else { - return totalRange * 0.7; - } + /** + * Easy function but there's some measures behind: + * Guessing the range of the Vehicle on Map. If you can drive x kilometers with your car it's not feasible to + * project this x km Radius on Map. The roads to be taken are causing some overhead because they are not a straight + * line from Location A to B. + * I've taken some measurements to calculate the overhead factor based on Google Maps + * Berlin - Dresden: Road Distance: 193 air-line Distance 167 = Factor 87% + * Kassel - Frankfurt: Road Distance: 199 air-line Distance 143 = Factor 72% + * After measuring more distances you'll find out that the outcome is between 70% and 90%. So + * + * This depends also on the roads of a concrete route but this is only a guess without any Route Navigation behind + * + * In future it's foreseen to replace this with BMW RangeMap Service which isn't running at the moment. + * + * @param range + * @return mapping from air-line distance to "real road" distance + */ + public static double guessRangeRadius(float range) { + return range * 0.8; + } + + public static Gson getGson() { + return GSON; } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_be.properties b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_be.properties index 7bd1569f77d77..fcc030b42a881 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_be.properties +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_be.properties @@ -1,17 +1,131 @@ -# FIXME: please substitute the xx_XX with a proper locale, ie. de_DE -# FIXME: please do not add the file to the repo if you add or change no content -# binding -binding.bmwconnecteddrive.name = -binding.bmwconnecteddrive.description = +# Binding +binding.bmwconnecteddrive.name = BMW ConnectedDrive +binding.bmwconnecteddrive.description = Zeigt die Fahrzeugdaten über das BMW ConnectedDrive Portal + +# bridge types +bridge-type.bmwconnecteddrive.account.label = BMW ConnectedDrive Benutzerkonto +bridge-type.bmwconnecteddrive.account.description = Zugriff auf das BMW ConnectedDrive Portal für einen Benutzer +bridge-type.config.bmwconnecteddrive.account.userName = Benutzername für das ConnectedDrive Portal +bridge-type.config.bmwconnecteddrive.account.password = Passwort für das ConnectedDrive Portal +bridge-type.config.bmwconnecteddrive.account.region = Auswahl Ihrer Region zur Verbindung mit dem korrekten BMW Server +bridge-type.config.bmwconnecteddrive.account.region.option.NORTH_AMERICA = Nordamerika +bridge-type.config.bmwconnecteddrive.account.region.option.CHINA = China +bridge-type.config.bmwconnecteddrive.account.region.option.ROW = Rest der Welt # thing types -thing-type.bmwconnecteddrive.sample.label = -thing-type.bmwconnecteddrive.sample.description = +thing-type.bmwconnecteddrive.BEV_REX.label = BMW Elektrofahrzeug mit REX +thing-type.bmwconnecteddrive.BEV_REX.description = BMW Elektrofahrzeug mit Range Extender +thing-type.config.bmwconnecteddrive.BEV_REX.vin.label = Fahrzeug Identifikationsnummer (VIN) +thing-type.config.bmwconnecteddrive.BEV_REX.vin.description = VIN des BMW Fahrzeugs +thing-type.config.bmwconnecteddrive.BEV_REX.refreshInterval.label = Datenaktualisierung in Minuten +thing-type.config.bmwconnecteddrive.BEV_REX.refreshInterval.description = Rate der Datenaktualisierung Ihres Fahrzeugs +thing-type.config.bmwconnecteddrive.BEV_REX.units.label = Einheiten +thing-type.config.bmwconnecteddrive.BEV_REX.units.description = Automatische oder direkte Auswahl der Einheiten +thing-type.config.bmwconnecteddrive.BEV_REX.units.option.AUTODETECT = +thing-type.config.bmwconnecteddrive.BEV_REX.units.option.IMPERIAL = +thing-type.config.bmwconnecteddrive.BEV_REX.units.option.METRIC = +thing-type.config.bmwconnecteddrive.BEV_REX.imageSize.label = Bildgröße +thing-type.config.bmwconnecteddrive.BEV_REX.imageSize.description = Bildgröße des Fahrzeugs für Länge und Breite +thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.label = Bild Ansicht +thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.description = Auswahl der Ansicht für das Fahrzeug +thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.option.FRONT = Vorderansicht +thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.option.REAR = Rückansicht +thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.option.SIDE = Seitenansicht +thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.option.DASHBOARD = Innenansicht Armaturen +thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.option.DRIVERDOOR = Seitenansicht Fahrertür + +# Channel Groups +channel-group-type.bmwconnecteddrive.charge-values.label = Elektrisches Laden +channel-group-type.bmwconnecteddrive.charge-values.description = Ladezustand und Ladeprofile des Fahrzeugs +channel-group-type.bmwconnecteddrive.ev-lifetime-values.label = Gesamtlaufzeit Statistik +channel-group-type.bmwconnecteddrive.ev-lifetime-values.description = Verbrauchswerte und zurück gelegte Strecken über die Fahrzeug Gesamtlaufzeit +channel-group-type.bmwconnecteddrive.ev-last-trip-values.label = Statistik der letzten Fahrt +channel-group-type.bmwconnecteddrive.ev-last-trip-values.description = Verbrauchswerte und zurück gelegte Strecke der letzten Fahrt +channel-group-type.bmwconnecteddrive.electric-range-values.label = Elektrische Reichweite +channel-group-type.bmwconnecteddrive.electric-range-values.description = Tachostand, Reichweite und Ladestand des Fahrzeugs +channel-group-type.bmwconnecteddrive.conv-range-values.label = Reichweite +channel-group-type.bmwconnecteddrive.conv-range-values.description = Tachostand, Reichweite und Tankfüllung des Fahrzeugs +channel-group-type.bmwconnecteddrive.hybrid-range-values.label = Hybride Reichweite +channel-group-type.bmwconnecteddrive.hybrid-range-values.description = Tachostand, Reichweite, Ladezustand und Tankfüllung des Fahrzeugs +channel-group-type.bmwconnecteddrive.image-values.label = Fahrzeug Bild +channel-group-type.bmwconnecteddrive.image-values.description = Bild des Fahrzeug basierend auf der Ansicht in der Konfiguration +channel-group-type.bmwconnecteddrive.remote-services.label = Fahrzeug Fernsteuerung +channel-group-type.bmwconnecteddrive.remote-services.description = Fernsteuerung des Fahrzeugs über den BMW Server wie Türen schließen / öffnen, Klimasteuerung und mehr +channel-group-type.bmwconnecteddrive.vehicle-status.label = Fahrzeug Zustand +channel-group-type.bmwconnecteddrive.vehicle-status.description = Zustand des Fahrzeugs über Türen, Fenster, abgeschlossen, anstehende Wartung und aktive Warnungen +channel-group-type.bmwconnecteddrive.location-values.label = Fahrzeug Standort +channel-group-type.bmwconnecteddrive.location-values.description = Koordinaten und Ausrichtung des Fahrzeugs +channel-group-type.bmwconnecteddrive.destination-values.label = Ziele +channel-group-type.bmwconnecteddrive.destination-values.description = Zeigt die letzten 3 Ziele des Fahrzeugs +channel-group-type.bmwconnecteddrive.troubleshoot-control.label = Fehlerbehebung +channel-group-type.bmwconnecteddrive.troubleshoot-control.description = Generiert Daten zur Fehlerbehebung eines Problems + +# Channel Types +channel-type.bmwconnecteddrive.doors-channel.label = Zustand der Türen +channel-type.bmwconnecteddrive.windows-channel.label = Zustand der Fenster +channel-type.bmwconnecteddrive.lock-channel.label = Fahrzeug abgeschlossen +channel-type.bmwconnecteddrive.service-channel.label = Nächster Service +channel-type.bmwconnecteddrive.check-control-channel.label = Aktuelle Warnung +channel-type.bmwconnecteddrive.last-update-channel.label = Letzte Aktualisierung + +channel-type.bmwconnecteddrive.mileage-channel.label = Tachostand +channel-type.bmwconnecteddrive.range-hybrid-channel.label = Hybride Reichweite +channel-type.bmwconnecteddrive.range-electric-channel.label = Elektrische Reichweite +channel-type.bmwconnecteddrive.soc-channel.label = Batterie Ladestand +channel-type.bmwconnecteddrive.range-fuel-channel.label = Verbrenner Reichweite +channel-type.bmwconnecteddrive.remaining-fuel-channel.label = Tankstand +channel-type.bmwconnecteddrive.range-radius-electric-channel.label = Elektrischer Reichweite-Radius +channel-type.bmwconnecteddrive.range-radius-fuel-channel.label = Verbrenner Reichweite-Radius +channel-type.bmwconnecteddrive.range-radius-hybrid-channel.label = Hybrider Reichweite-Radius + +channel-type.bmwconnecteddrive.charging-status-channel.label = Ladezustand +channel-type.bmwconnecteddrive.profile-climate-channel.label = Klimatisierung bei Abfahrt +channel-type.bmwconnecteddrive.profile-mode-channel.label = Ladeprofil Einstellung +channel-type.bmwconnecteddrive.window-start-channel.label = Startzeit Ladefenster +channel-type.bmwconnecteddrive.window-end-channel.label = Endzeit Ladefenster +channel-type.bmwconnecteddrive.timer1-departure-channel.label = Zeitprofil 1 - Abfahrtszeit +channel-type.bmwconnecteddrive.timer1-days-channel.label = Zeitprofil 1 - Tage +channel-type.bmwconnecteddrive.timer1-enabled-channel.label = Zeitprofil 1 - Aktiviert +channel-type.bmwconnecteddrive.timer2-departure-channel.label = Zeitprofil 2 - Abfahrtszeit +channel-type.bmwconnecteddrive.timer2-days-channel.label = Zeitprofil 2 - Tage +channel-type.bmwconnecteddrive.timer2-enabled-channel.label = Zeitprofil 2 - Aktiviert +channel-type.bmwconnecteddrive.timer3-departure-channel.label = Zeitprofil 3 - Abfahrtszeit +channel-type.bmwconnecteddrive.timer3-days-channel.label = Zeitprofil 3 - Tage +channel-type.bmwconnecteddrive.timer3-enabled-channel.label = Zeitprofil 3 - Aktiviert + +channel-type.bmwconnecteddrive.name-1-channel.label = Letztes Ziel +channel-type.bmwconnecteddrive.lat-1-channel.label = Letztes Ziel Breitengrad +channel-type.bmwconnecteddrive.lon-1-channel.label = Letztes Ziel Längengrad +channel-type.bmwconnecteddrive.name-2-channel.label = Vorletztes Ziel +channel-type.bmwconnecteddrive.lat-2-channel.label = Vorletztes Ziel Breitengrad +channel-type.bmwconnecteddrive.lon-2-channel.label = Vorletztes Ziel Längengrad +channel-type.bmwconnecteddrive.name-3-channel.label = Drittletztes Ziel +channel-type.bmwconnecteddrive.lat-3-channel.label = Drittletztes Ziel Breitengrad +channel-type.bmwconnecteddrive.lon-3-channel.label = Drittletztes Ziel Längengrad + +channel-type.bmwconnecteddrive.longitude-channel.label = Fahrzeug Standort Längengrad +channel-type.bmwconnecteddrive.latitude-channel.label = Fahrzeug Standort Breitengrad +channel-type.bmwconnecteddrive.heading-channel.label = Fahrzeug Ausrichtung + +channel-type.bmwconnecteddrive.distance-channel.label = Distanz der letzten Fahr +channel-type.bmwconnecteddrive.distance-since-charging-channel.label = Distanz seit letzter Ladung +channel-type.bmwconnecteddrive.average-consumption-channel.label = kw/h Verbrauch über 100 km der letzten Fahrt +channel-type.bmwconnecteddrive.average-recuperation-channel.label = kw/h Rekuperation über 100 km der letzten Fahrt + +channel-type.bmwconnecteddrive.average-consumption-channel".label = kw/h Verbrauch über 100 km während der Gesamtlaufzeit +channel-type.bmwconnecteddrive.average-recuperation-channel.label = kw/h Rekuperation über 100 km während der Gesamtlaufzeit +channel-type.bmwconnecteddrive.cumulated-driven-distance-channel.label = Elektrisch gefahrene Distanz +channel-type.bmwconnecteddrive.single-longest-distance-channel.label = Längste Fahrt mit einer Ladung + +channel-type.bmwconnecteddrive.remote-light-channel.label = Lichthupe ausführen +channel-type.bmwconnecteddrive.remote-finder-channel.label = Fahrzeug lokalisieren +channel-type.bmwconnecteddrive.remote-lock-channel.label = Fahrzeug abschließen +channel-type.bmwconnecteddrive.remote-unlock-channel.label = Fahrzug aufschließen +channel-type.bmwconnecteddrive.remote-horn-channel.label = Hupen aktivieren +channel-type.bmwconnecteddrive.remote-climate-channel.label = Klimatisierung ausführen +channel-type.bmwconnecteddrive.remote-state-channel.label = Ausführungszustand -# thing type config description -thing-type.config.bmwconnecteddrive.sample.config1.label = -thing-type.config.bmwconnecteddrive.sample.config1.description = +channel-type.bmwconnecteddrive.png-channel.label = Fahrzeug Bild -# channel types -channel-type.bmwconnecteddrive.sample-channel.label = -channel-type.bmwconnecteddrive.sample-channel.description = +channel-type.bmwconnecteddrive.vehicle-fingerprint-channel.label = Fahrzeug Fingerabdruck + \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml index 0a5cd5d4b80ff..d21279ec81589 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml @@ -9,18 +9,14 @@ Access to BMW ConnectedDrive Portal for a specific user - - - - - BMW Connected Drive Username + BMW ConnectedDrive Username - BMW Connected Drive Password + BMW ConnectedDrive Password @@ -34,11 +30,4 @@ - - - Switch - - Forcing a log entry to analyze Discovery Problems - - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-groups.xml index 1bf6a391fdec2..fad8209665efb 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-groups.xml @@ -4,10 +4,23 @@ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - + Charge Status and Charge Profiles of Vehicle - + + + + + + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-types.xml index 426c0222c805a..d1ca4372c5a25 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-types.xml @@ -7,4 +7,56 @@ String + + Switch + + + + String + + + + String + + + + String + + + + String + + + + String + + + + Switch + + + + String + + + + String + + + + Switch + + + + String + + + + String + + + + Switch + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/conv-range-channel-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/conv-range-channel-group.xml index d964fc43194b1..df8b118b2a4e1 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/conv-range-channel-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/conv-range-channel-group.xml @@ -10,7 +10,7 @@ - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-group.xml index 36cc1a2de0154..2132ff98e6268 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-group.xml @@ -4,7 +4,7 @@ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - + EV Consumption Values and Distances for the Last Trip diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-group.xml index 1c32dd2edfc96..f4ac0bf14f729 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-group.xml @@ -4,8 +4,8 @@ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - - EV Consumption Values and Distances over Lifetime + + Consumption Values and Distances over Lifetime diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-group.xml index 0458e304109d9..cbf4fed4966c5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-group.xml @@ -4,13 +4,13 @@ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - + Provides Mileage, remaining range and charge level values - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-range-channel-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-range-channel-group.xml index d4751ee9115d7..a260df0b9f6b2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-range-channel-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-range-channel-group.xml @@ -4,7 +4,7 @@ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - + Provides Mileage, remaining range and fuel and charge level values @@ -13,7 +13,8 @@ - + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-group.xml index c010e75a4c445..a802fcc6b89b3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-group.xml @@ -4,8 +4,8 @@ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - - Provides an Image of your Car based on the Configuration ViewPort + + Provides an Image of your Vehicle based on the Configuration ViewPort diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/location-channel-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/location-channel-group.xml index 2f4f8039d9177..a9c3b0b1990e8 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/location-channel-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/location-channel-group.xml @@ -4,8 +4,8 @@ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - - All values needed to locate your Car on a Map + + Coordinates and Heading of the Vehcile diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml index c2198e6151cfd..0348e34d616cd 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml @@ -13,7 +13,7 @@ Number:Length - + Number:Dimensionless @@ -27,8 +27,16 @@ Number:Volume - + Number:Length - + + + + Number:Length + + + + Number:Length + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml index b82c11b26d972..007ae975c60b2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml @@ -52,13 +52,11 @@ Viewport of Car Image - - - - - - - + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml index 394243244fd53..d89ddac853749 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml @@ -46,20 +46,17 @@ - Car Image size for width and length + Vehicle Image size for width and length Viewport of Car Image - - - - - - - - + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml index 59fdaee313266..55196ddb5d9ac 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml @@ -49,14 +49,11 @@ Viewport of Car Image - - - - - - - - + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml index 74768385bf6d9..16a74ca826dc4 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml @@ -50,16 +50,13 @@ - Viewport of Car Image + Viewport of Vehicle Image - - - - - - - - + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml index 14467e56a6886..2d5a220029184 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml @@ -5,6 +5,6 @@ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> Switch - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml index 2087c1d3ff187..c2a213c271c50 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml @@ -27,8 +27,4 @@ String - - String - - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-group.xml index 872d1b7c17104..2052309b5f157 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-group.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - Provides Status of Doors, Lock State, Service and Check Control Messages + Provides Status of Doors, Windows, Lock State, Service and Check Control Messages diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java index f04c34155fe93..3eda5d7def3ba 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java @@ -12,6 +12,7 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.discovery; +import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.*; import java.util.List; @@ -59,9 +60,9 @@ public void testDiscovery() { discovery.onResponse(container); verify(listener, times(1)).thingDiscovered(services.capture(), discoveries.capture()); List results = discoveries.getAllValues(); - results.forEach(entry -> { - logger.info("{}", entry.toString()); - }); + assertEquals("Found Vehicles", 1, results.size()); + DiscoveryResult result = results.get(0); + assertEquals("Thing UID", "bmwconnecteddrive:BEV_REX:MY_REAL_VIN", result.getThingUID().getAsString()); } @Test diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ChargeProfileTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ChargeProfileTest.java new file mode 100644 index 0000000000000..6396e49989ecf --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ChargeProfileTest.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; + +import static org.junit.Assert.*; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.junit.Test; +import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.ChargeProfile; +import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; + +/** + * The {@link ChargeProfileTest} Test json responses from ConnectedDrive Portal + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class ChargeProfileTest { + private final Logger logger = LoggerFactory.getLogger(ChargeProfileTest.class); + private static final Gson GSON = new Gson(); + + @Test + public void testChargeProfile() { + String resource1 = FileReader.readFileInString("src/test/resources/webapi/charging-profile.json"); + ChargeProfile cp = GSON.fromJson(resource1, ChargeProfile.class); + assertNotNull(cp.weeklyPlanner); + assertNotNull(cp.weeklyPlanner.timer1); + assertFalse(cp.weeklyPlanner.timer1.timerEnabled); + assertNotNull(cp.weeklyPlanner.timer1.weekdays); + assertEquals("Days", 5, cp.weeklyPlanner.timer1.weekdays.size()); + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java index c08eb658979d5..604a241ac471f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java @@ -41,17 +41,11 @@ public void testUserInfo() { List vehicles = container.vehicles; assertEquals("Number of Vehicles", 1, vehicles.size()); Vehicle v = vehicles.get(0); - // assertEquals("VIN", "WBY1Z81040V905639", v.getVin()); - // assertEquals("Model", "i3 94 (+ REX)", v.getModel()); - // assertEquals("DriveTrain", "BEV_REX", v.getDriveTrain()); - // assertEquals("Brand", "BMW_I", v.getBrand()); - // assertEquals("Year of Construction", 2017, v.getYearOfConstruction()); - // System.out.println(v.getDealer()); - // System.out.println(v.getBodytype()); - // System.out.println(v.getSupportedServices()); - // System.out.println(v.getNotSupportedServices()); - // System.out.println(v.getActivatedServices()); - // System.out.println(v.getNotActivatedServices()); + assertEquals("VIN", "MY_REAL_VIN", v.vin); + assertEquals("Model", "i3 94 (+ REX)", v.model); + assertEquals("DriveTrain", "BEV_REX", v.driveTrain); + assertEquals("Brand", "BMW_I", v.brand); + assertEquals("Year of Construction", 2017, v.yearOfConstruction); } @Test diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LastTripTest.java similarity index 83% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripTest.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LastTripTest.java index cf00243fae0d9..c14afdcc6664b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LastTripTest.java @@ -10,12 +10,14 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.bmwconnecteddrive.internal.dto.statistics; +package org.openhab.binding.bmwconnecteddrive.internal.dto; import static org.junit.Assert.*; import org.eclipse.jdt.annotation.NonNullByDefault; import org.junit.Test; +import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTrip; +import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTripContainer; import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; import com.google.gson.Gson; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/RemoteStatusTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/RemoteStatusTest.java similarity index 85% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/RemoteStatusTest.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/RemoteStatusTest.java index 16a36f0e9b59a..3bd51e2778b2d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/RemoteStatusTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/RemoteStatusTest.java @@ -10,12 +10,14 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.bmwconnecteddrive.internal.dto.remote; +package org.openhab.binding.bmwconnecteddrive.internal.dto; import static org.junit.Assert.assertEquals; import org.eclipse.jdt.annotation.NonNullByDefault; import org.junit.Test; +import org.openhab.binding.bmwconnecteddrive.internal.dto.remote.ExecutionStatus; +import org.openhab.binding.bmwconnecteddrive.internal.dto.remote.ExecutionStatusContainer; import org.openhab.binding.bmwconnecteddrive.internal.handler.RemoteServiceHandler.ExecutionState; import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java similarity index 81% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/StatusWrapper.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index 9b46fd763bc69..42603dedb782c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -10,7 +10,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.bmwconnecteddrive.internal.dto.status; +package org.openhab.binding.bmwconnecteddrive.internal.dto; import static org.junit.Assert.*; import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; @@ -18,6 +18,7 @@ import java.util.List; import javax.measure.Unit; +import javax.measure.quantity.Length; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -31,6 +32,10 @@ import org.eclipse.smarthome.core.thing.ChannelUID; import org.eclipse.smarthome.core.types.State; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CarType; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Doors; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Windows; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; @@ -44,7 +49,7 @@ @NonNullByDefault public class StatusWrapper { private static final Gson GSON = new Gson(); - private static final Unit KILOMETRE = MetricPrefix.KILO(SIUnits.METRE); + private static final Unit KILOMETRE = MetricPrefix.KILO(SIUnits.METRE); private VehicleStatus vStatus; private boolean imperial; @@ -52,7 +57,7 @@ public class StatusWrapper { private boolean hasFuel; private boolean isHybrid; - public StatusWrapper(@Nullable String type, boolean imperial, @Nullable String statusJson) { + public StatusWrapper(String type, boolean imperial, String statusJson) { this.imperial = imperial; hasFuel = type.equals(CarType.CONVENTIONAL.toString()) || type.equals(CarType.PLUGIN_HYBRID.toString()) || type.equals(CarType.ELECTRIC_REX.toString()); @@ -77,7 +82,7 @@ public boolean checkResults(@Nullable List channels, @Nullable List< private void checkResult(ChannelUID channelUID, State state) { String cUid = channelUID.getIdWithoutGroup(); - QuantityType qt; + QuantityType qt; StringType st; DecimalType dt; switch (cUid) { @@ -175,7 +180,7 @@ private void checkResult(ChannelUID channelUID, State state) { st = (StringType) state; assertEquals("Next Service", vStatus.getNextService(imperial), st.toString()); break; - case CHARGING_STATUS: + case CHARGE_STATUS: assertTrue("Is Eelctric", isElectric); assertTrue(state instanceof StringType); st = (StringType) state; @@ -214,32 +219,44 @@ private void checkResult(ChannelUID channelUID, State state) { assertNotNull(vStatus.position); assertEquals("Heading", vStatus.position.heading, qt.intValue(), 0.01); break; - case LATLONG: - assertTrue(state instanceof StringType); - st = ((StringType) state); - assertNotNull(vStatus.position); - assertEquals("Lat/Long", vStatus.position.lat + "," + vStatus.position.lon, st.toString()); + case RANGE_RADIUS_ELECTRIC: + assertTrue(state instanceof QuantityType); + assertTrue(isElectric); + qt = (QuantityType) state; + if (imperial) { + assertEquals("Range Radius Electric mi", + Converter.guessRangeRadius(vStatus.remainingRangeElectricMls), qt.floatValue(), 0.1); + } else { + assertEquals("Range Radius Electric km", Converter.guessRangeRadius(vStatus.remainingRangeElectric), + qt.floatValue(), 0.1); + } + break; + case RANGE_RADIUS_FUEL: + assertTrue(state instanceof QuantityType); + assertTrue(hasFuel); + qt = (QuantityType) state; + if (imperial) { + assertEquals("Range Radius Fuel mi", Converter.guessRangeRadius(vStatus.remainingRangeFuelMls), + qt.floatValue(), 0.1); + } else { + assertEquals("Range Radius Fuel km", Converter.guessRangeRadius(vStatus.remainingRangeFuel), + qt.floatValue(), 0.1); + } break; - case RANGE_RADIUS: + case RANGE_RADIUS_HYBRID: assertTrue(state instanceof QuantityType); + assertTrue(isHybrid); qt = (QuantityType) state; - int totalRange = 0; if (imperial) { - if (isElectric) { - totalRange += vStatus.remainingRangeElectricMls; - } - if (hasFuel) { - totalRange += vStatus.remainingRangeFuelMls; - } + assertEquals("Range Radius Hybrid mi", + Converter.guessRangeRadius( + vStatus.remainingRangeElectricMls + vStatus.remainingRangeFuelMls), + qt.floatValue(), 0.1); } else { - if (isElectric) { - totalRange += vStatus.remainingRangeElectric; - } - if (hasFuel) { - totalRange += vStatus.remainingRangeFuel; - } + assertEquals("Range Radius Hybrid km", + Converter.guessRangeRadius(vStatus.remainingRangeElectric + vStatus.remainingRangeFuel), + qt.floatValue(), 0.1); } - assertEquals("Range Circle", Converter.guessRange(totalRange), qt.floatValue(), 0.1); break; default: // fail in case of unknown update diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleStatusTest.java similarity index 82% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusTest.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleStatusTest.java index ed3dc5ccbeec0..1923dac4f56b2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleStatusTest.java @@ -10,12 +10,15 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.openhab.binding.bmwconnecteddrive.internal.dto.status; +package org.openhab.binding.bmwconnecteddrive.internal.dto; import static org.junit.Assert.assertEquals; import org.eclipse.jdt.annotation.NonNullByDefault; import org.junit.Test; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Position; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; import com.google.gson.Gson; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java index c0e3da6940c3f..87a35335c4579 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/CarTests.java @@ -29,8 +29,9 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CarType; -import org.openhab.binding.bmwconnecteddrive.internal.dto.status.StatusWrapper; +import org.openhab.binding.bmwconnecteddrive.internal.dto.StatusWrapper; import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,7 +44,10 @@ @NonNullByDefault public class CarTests { private final Logger logger = LoggerFactory.getLogger(ConnectedCarHandler.class); - // ConnectedCarHandler cch = new Co + + private final int HYBRID_CALL_TIMES = 19; + private final int CONV_CALL_TIMES = 13; + private final int EV_CALL_TIMES = 14; @Nullable ArgumentCaptor channelCaptor; @@ -57,8 +61,7 @@ public class CarTests { List allChannels; @Nullable List allStates; - @Nullable - String driveTrain; + String driveTrain = Constants.EMPTY; boolean imperial; /** @@ -77,7 +80,7 @@ public void setup(String type, boolean imperial) { stateCaptor = ArgumentCaptor.forClass(State.class); } - private boolean testCar(@Nullable String statusContent, int callbacksExpected) { + private boolean testCar(String statusContent, int callbacksExpected) { assertNotNull(statusContent); cch.vehicleStatusCallback.onResponse(Optional.of(statusContent)); @@ -123,7 +126,7 @@ public void testMyi3Rex() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(CarType.ELECTRIC_REX.toString(), false); String content = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); - assertTrue(testCar(content, 18)); + assertTrue(testCar(content, HYBRID_CALL_TIMES)); } /** @@ -151,7 +154,7 @@ public void testMyi3RexMiles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(CarType.ELECTRIC_REX.toString(), true); String content = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); - assertTrue(testCar(content, 18)); + assertTrue(testCar(content, HYBRID_CALL_TIMES)); } /** @@ -175,7 +178,7 @@ public void testF15() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(CarType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F15/status.json"); - assertTrue(testCar(content, 14)); + assertTrue(testCar(content, CONV_CALL_TIMES)); } @Test @@ -183,7 +186,7 @@ public void testF15Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(CarType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F15/status.json"); - assertTrue(testCar(content, 14)); + assertTrue(testCar(content, CONV_CALL_TIMES)); } /** @@ -207,7 +210,7 @@ public void testF31() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(CarType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F31/status.json"); - assertTrue(testCar(content, 14)); + assertTrue(testCar(content, CONV_CALL_TIMES)); } @Test @@ -215,7 +218,7 @@ public void testF31Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(CarType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F31/status.json"); - assertTrue(testCar(content, 14)); + assertTrue(testCar(content, CONV_CALL_TIMES)); } @Test @@ -223,7 +226,7 @@ public void testF35() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(CarType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F35/status.json"); - assertTrue(testCar(content, 14)); + assertTrue(testCar(content, CONV_CALL_TIMES)); } @Test @@ -231,7 +234,7 @@ public void testF35Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(CarType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F35/status.json"); - assertTrue(testCar(content, 14)); + assertTrue(testCar(content, CONV_CALL_TIMES)); } @Test @@ -239,7 +242,7 @@ public void testF45() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(CarType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F45/status.json"); - assertTrue(testCar(content, 14)); + assertTrue(testCar(content, CONV_CALL_TIMES)); } @Test @@ -247,7 +250,7 @@ public void testF45Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(CarType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F45/status.json"); - assertTrue(testCar(content, 14)); + assertTrue(testCar(content, CONV_CALL_TIMES)); } @Test @@ -255,7 +258,7 @@ public void testF48() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(CarType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F48/status.json"); - assertTrue(testCar(content, 14)); + assertTrue(testCar(content, CONV_CALL_TIMES)); } @Test @@ -263,7 +266,7 @@ public void testF48Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(CarType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F48/status.json"); - assertTrue(testCar(content, 14)); + assertTrue(testCar(content, CONV_CALL_TIMES)); } @Test @@ -271,7 +274,7 @@ public void testG31NBTEvo() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(CarType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/G31_NBTevo/status.json"); - assertTrue(testCar(content, 14)); + assertTrue(testCar(content, CONV_CALL_TIMES)); } @Test @@ -279,7 +282,7 @@ public void testG31NBTEvoMiles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(CarType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/G31_NBTevo/status.json"); - assertTrue(testCar(content, 14)); + assertTrue(testCar(content, CONV_CALL_TIMES)); } @Test @@ -287,7 +290,7 @@ public void testI01NoRex() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(CarType.ELECTRIC.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/I01_NOREX/status.json"); - assertTrue(testCar(content, 15)); + assertTrue(testCar(content, EV_CALL_TIMES)); } @Test @@ -295,7 +298,7 @@ public void testI01NoRexMiles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(CarType.ELECTRIC.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/I01_NOREX/status.json"); - assertTrue(testCar(content, 15)); + assertTrue(testCar(content, EV_CALL_TIMES)); } @Test @@ -303,7 +306,7 @@ public void testI01Rex() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(CarType.ELECTRIC_REX.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/I01_REX/status.json"); - assertTrue(testCar(content, 18)); + assertTrue(testCar(content, HYBRID_CALL_TIMES)); } @Test @@ -311,6 +314,6 @@ public void testI01RexMiles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(CarType.ELECTRIC_REX.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/I01_REX/status.json"); - assertTrue(testCar(content, 18)); + assertTrue(testCar(content, HYBRID_CALL_TIMES)); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java new file mode 100644 index 0000000000000..87fc28f6e5462 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.*; + +import java.util.List; +import java.util.Optional; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.smarthome.core.thing.ChannelUID; +import org.eclipse.smarthome.core.thing.Thing; +import org.eclipse.smarthome.core.thing.ThingUID; +import org.eclipse.smarthome.core.thing.binding.ThingHandlerCallback; +import org.eclipse.smarthome.core.types.State; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.CarType; +import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link ChargeProfileTest} is responsible for handling commands, which are + * sent to one of the channels. + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class ChargeProfileTest { + private final Logger logger = LoggerFactory.getLogger(ConnectedCarHandler.class); + + private final int PROFILE_CALLBACK_NUMBER = 13; + + @Nullable + ArgumentCaptor channelCaptor; + @Nullable + ArgumentCaptor stateCaptor; + @Nullable + ThingHandlerCallback tc; + @Nullable + ConnectedCarHandler cch; + @Nullable + List allChannels; + @Nullable + List allStates; + String driveTrain = Constants.EMPTY; + boolean imperial; + + /** + * Prepare environment for Vehicle Status Updates + */ + public void setup(String type, boolean imperial) { + driveTrain = type; + this.imperial = imperial; + Thing thing = mock(Thing.class); + when(thing.getUID()).thenReturn(new ThingUID("testbinding", "test")); + HttpClient hc = mock(HttpClient.class); + cch = new ConnectedCarHandler(thing, hc, type, imperial); + tc = mock(ThingHandlerCallback.class); + cch.setCallback(tc); + channelCaptor = ArgumentCaptor.forClass(ChannelUID.class); + stateCaptor = ArgumentCaptor.forClass(State.class); + } + + private boolean testProfile(String statusContent, int callbacksExpected) { + assertNotNull(statusContent); + + cch.chargeProfileCallback.onResponse(Optional.of(statusContent)); + verify(tc, times(callbacksExpected)).stateUpdated(channelCaptor.capture(), stateCaptor.capture()); + allChannels = channelCaptor.getAllValues(); + allStates = stateCaptor.getAllValues(); + + assertNotNull(driveTrain); + trace(); + return true; + } + + private void trace() { + for (int i = 0; i < allChannels.size(); i++) { + logger.info("Channel {} {}", allChannels.get(i), allStates.get(i)); + } + } + + /** + * Channel testbinding::test:charge#profile-climate ON + * Channel testbinding::test:charge#profile-mode IMMEDIATE_CHARGING + * Channel testbinding::test:charge#window-start 11:00 + * Channel testbinding::test:charge#window-end 17:00 + * Channel testbinding::test:charge#timer1-departure 05:00 + * Channel testbinding::test:charge#timer1-enabled OFF + * Channel testbinding::test:charge#timer1-days MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY + * Channel testbinding::test:charge#timer2-departure 12:00 + * Channel testbinding::test:charge#timer2-enabled ON + * Channel testbinding::test:charge#timer2-days SATURDAY + * Channel testbinding::test:charge#timer3-departure 00:00 + * Channel testbinding::test:charge#timer3-enabled OFF + * Channel testbinding::test:charge#timer3-days + */ + @Test + public void testChargingProfile() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(CarType.ELECTRIC_REX.toString(), false); + String content = FileReader.readFileInString("src/test/resources/webapi/charging-profile.json"); + testProfile(content, PROFILE_CALLBACK_NUMBER); + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/FingerprintTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/FingerprintTest.java new file mode 100644 index 0000000000000..d7c52fe931fe9 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/FingerprintTest.java @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import java.util.Optional; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.smarthome.core.thing.Bridge; +import org.eclipse.smarthome.core.thing.ThingUID; +import org.junit.Test; +import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; +import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link FingerprintTest} Test Discovery Results + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class FingerprintTest { + private final Logger logger = LoggerFactory.getLogger(FingerprintTest.class); + + @Test + public void testDiscoveryFingerprint() { + Bridge b = mock(Bridge.class); + when(b.getUID()).thenReturn(new ThingUID("testbinding", "test")); + HttpClient hc = mock(HttpClient.class); + BundleContext bc = mock(BundleContext.class); + ConnectedDriveBridgeHandler bh = new ConnectedDriveBridgeHandler(b, hc, bc); + // when(bh.getThing()).thenReturn(b); + + bh.onResponse(Optional.of(Constants.EMPTY_VEHICLES)); + assertEquals("Empty Response", Constants.EMPTY_VEHICLES, bh.getDiscoveryFingerprint()); + + bh.onResponse(Optional.empty()); + assertEquals("Empty Response", Constants.EMPTY_VEHICLES, bh.getDiscoveryFingerprint()); + + String content = FileReader.readFileInString("src/test/resources/webapi/connected-drive-account-info.json"); + bh.onResponse(Optional.of(content)); + String fingerprint = bh.getDiscoveryFingerprint(); + logger.info("{}", fingerprint); + assertFalse("Anonymous Fingerprint", fingerprint.contains("My Real")); + assertFalse("Anonymous Fingerprint", fingerprint.contains("MY_REAL_VIN")); + + NetworkError err = new NetworkError(); + err.url = "Some URL"; + err.status = 500; + err.reason = "Internal Server Error"; + bh.onError(err); + assertEquals("Empty Response", err.toJson(), bh.getDiscoveryFingerprint()); + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/FileReader.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/FileReader.java index d806270cb76b4..1669a575495f4 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/FileReader.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/FileReader.java @@ -20,7 +20,7 @@ import java.io.InputStreamReader; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; /** * The {@link FileReader} Helper Util to read test resource files @@ -30,7 +30,7 @@ @NonNullByDefault public class FileReader { - public static @Nullable String readFileInString(String filename) { + public static String readFileInString(String filename) { try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filename), "CP1252"));) { StringBuffer buf = new StringBuffer(); String sCurrentLine; @@ -43,6 +43,6 @@ public class FileReader { // fail if file cannot be read assertTrue(false); } - return null; + return Constants.UNKNOWN; } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java index 7383773d084f8..a5874d28f391b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java @@ -15,6 +15,7 @@ import static org.junit.Assert.*; import java.time.LocalDate; +import java.time.LocalTime; import java.util.Locale; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -66,4 +67,11 @@ public void testTimeZoneDateTime() { String pattern = "2018-07-16T21:47:46+0000"; assertEquals("ZonedDateTime", "16.07.2018 23:47", Converter.getZonedDateTime(pattern)); } + + @Test + public void testLocalTime() { + String time = "05:23"; + LocalTime t = LocalTime.parse(time); + assertEquals("Time", "05:23", t.toString()); + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/connected-drive-account-info.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/connected-drive-account-info.json index 91674a046db1e..73b594678ba3b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/connected-drive-account-info.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/connected-drive-account-info.json @@ -1,7 +1,7 @@ { "vehicles": [ { - "vin": "WBY1Z81040V905639", + "vin": "MY_REAL_VIN", "model": "i3 94 (+ REX)", "bodytype": "I01", "driveTrain": "BEV_REX", @@ -14,14 +14,14 @@ "hub": "HUB_ECE", "hasAlarmSystem": true, "dealer": { - "name": "Andreas Ehrl Potsdam GmbH & Co. KG", - "street": "Fritz-Zubeil-Str. 95", - "postalCode": "14482", - "city": "Potsdam", + "name": "My Real Dealer Name", + "street": "My Real Dealer Address", + "postalCode": "4711", + "city": "My Real Dealer City", "country": "DE", - "phone": "+49 331 888888" + "phone": "My Real Dealer Phone" }, - "breakdownNumber": "+4989358957103", + "breakdownNumber": "Real Phone Number", "countryCode": "V6", "egoVehiclePath": "", "chargingUpdateMode": "NORMAL_PROGNOSE_BASED", diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/destinations.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/destinations.json index 0e993d22f7ebb..2c63438a22b50 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/destinations.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/destinations.json @@ -1,89 +1,92 @@ { "destinations": [ { - "lat": 50.55577087402344, - "lon": 8.495763778686523, + "lat": 47.11, + "lon": 47.11, "country": "DEUTSCHLAND", - "city": "WETZLAR", - "street": "UFERSTRASSE", - "streetNumber": "4", + "city": "My Real City", + "street": "My Real Street", + "streetNumber": "My Real Number", "type": "DESTINATION", "createdAt": "2020-08-16T12:52:58+0000" }, { - "lat": 50.539329528808594, - "lon": 8.25927734375, - "country": "DEUTSCHLAND", - "city": "LÖHNBERG", - "street": "RINGSTRASSE", - "streetNumber": "2", + "lat": 47.11, + "lon": 47.11, + "country": "DEUTSCHLAND", + "city": "My Real City", + "street": "My Real Street", + "streetNumber": "My Real Number", "type": "DESTINATION", "createdAt": "2020-08-12T17:03:35+0000" }, { - "lat": 50.22248840332031, - "lon": 8.548190116882324, - "country": "DEUTSCHLAND", - "city": "OBERURSEL (TAUNUS)", - "street": "FORSTHAUSWEG", - "streetNumber": "15", + "lat": 47.11, + "lon": 47.11, + "country": "DEUTSCHLAND", + "city": "My Real City", + "street": "My Real Street", + "streetNumber": "My Real Number", "type": "DESTINATION", "createdAt": "2020-08-03T08:15:20+0000" }, { - "lat": 51.48691940307617, - "lon": 9.385430335998535, - "country": "DEUTSCHLAND", - "city": "34369 HOFGEISMAR", - "street": "KELZER WEG", - "streetNumber": "22", + "lat": 47.11, + "lon": 47.11, + "country": "DEUTSCHLAND", + "city": "My Real City", + "street": "My Real Street", + "streetNumber": "My Real Number", "type": "DESTINATION", "createdAt": "2020-07-31T13:09:15+0000" }, { - "lat": 50.555870056152344, - "lon": 8.495736122131348, - "country": "DEUTSCHLAND", - "city": "WETZLAR", - "street": "UFERSTRASSE", - "streetNumber": "4", + "lat": 47.11, + "lon": 47.11, + "country": "DEUTSCHLAND", + "city": "My Real City", + "street": "My Real Street", + "streetNumber": "My Real Number", "type": "DESTINATION", "createdAt": "2020-07-25T11:20:18+0000" }, { - "lat": 50.78496170043945, - "lon": 8.761188507080078, - "country": "DEUTSCHLAND", - "city": "MARBURG", - "street": "BAHNHAUS", - "streetNumber": "1", + "lat": 47.11, + "lon": 47.11, + "country": "DEUTSCHLAND", + "city": "My Real City", + "street": "My Real Street", + "streetNumber": "My Real Number", "type": "DESTINATION", "createdAt": "2020-07-18T11:22:37+0000" }, { - "lat": 50.56787872314453, - "lon": 8.661417007446289, - "country": "DEUTSCHLAND", - "city": "GIESSEN", - "street": "CARL-FRANZ-STRASSE", + "lat": 47.11, + "lon": 47.11, + "country": "DEUTSCHLAND", + "city": "My Real City", + "street": "My Real Street", + "streetNumber": "My Real Number", "type": "DESTINATION", "createdAt": "2020-02-08T11:06:52+0000" }, { - "lat": 50.555763244628906, - "lon": 8.4972562789917, - "country": "DEUTSCHLAND", - "city": "WETZLAR", - "street": "HAARPLATZ", + "lat": 47.11, + "lon": 47.11, + "country": "DEUTSCHLAND", + "city": "My Real City", + "street": "My Real Street", + "streetNumber": "My Real Number", "type": "DESTINATION", "createdAt": "2020-02-02T14:07:54+0000" }, { - "lat": 50.44765853881836, - "lon": 8.516128540039062, - "country": "DEUTSCHLAND", - "city": "WALDSOLMS", - "street": "OBERGASSE", + "lat": 47.11, + "lon": 47.11, + "country": "DEUTSCHLAND", + "city": "My Real City", + "street": "My Real Street", + "streetNumber": "My Real Number", "type": "DESTINATION", "createdAt": "2020-02-02T13:24:36+0000" } From 1123aefe9c2ca2dedd14facc01092e2243fb0234 Mon Sep 17 00:00:00 2001 From: Bernd Date: Sat, 5 Sep 2020 22:55:04 +0200 Subject: [PATCH 019/176] added all account variables to dto Signed-off-by: Bernd (cherry picked from commit b014d5f838a70c1862af16b82d83cfa5c9e4eae2) Signed-off-by: Bernd --- .../internal/discovery/ConnectedCarDiscovery.java | 3 +++ .../bmwconnecteddrive/internal/dto/discovery/Vehicle.java | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java index 706fa399dd26e..a911660aafe17 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/ConnectedCarDiscovery.java @@ -109,6 +109,9 @@ public void onResponse(VehiclesContainer container) { properties.put("Vehicle Construction Year", Short.toString(vehicle.yearOfConstruction)); properties.put("Vehicle Drive Train", vehicle.driveTrain); properties.put("Vehicle Model", vehicle.model); + if (vehicle.chargingControl != null) { + properties.put("Vehicle Charge Control", Converter.toTitleCase(vehicle.model)); + } // Check now if a thing with the same VIN exists final AtomicBoolean foundVehicle = new AtomicBoolean(false); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Vehicle.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Vehicle.java index df515dffb4e14..e176b6939c88f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Vehicle.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Vehicle.java @@ -33,6 +33,7 @@ public class Vehicle { public Dealer dealer; public String breakdownNumber; public List supportedChargingModes; + public String chargingControl;// ": "WEEKLY_PLANNER", // Remote Services public String vehicleFinder; // ACTIVATED @@ -49,4 +50,10 @@ public class Vehicle { public String lastDestinations; // SUPPORTED public String carCloud; // SUPPORTED public String remoteSoftwareUpgrade; // SUPPORTED + + public String climateNowRES;// ": "NOT_SUPPORTED", + public String climateControlRES;// ": "NOT_SUPPORTED", + public String smartSolution;// ": "NOT_SUPPORTED", + public String ipa;// ": "NOT_SUPPORTED", + } From 22a665605fdf88f3d586494454eb0fcf401ec949 Mon Sep 17 00:00:00 2001 From: Bernd Date: Sun, 6 Sep 2020 21:54:00 +0200 Subject: [PATCH 020/176] consistent Vehicle naming Signed-off-by: Bernd (cherry picked from commit 6999d70c65f4834d6c068068991d8ac4f1f77e5a) Signed-off-by: Bernd --- .../README.md | 155 ++++++++++++------ .../internal/ConnectedDriveConstants.java | 38 +++-- .../ConnectedDriveHandlerFactory.java | 16 +- ...uration.java => VehicleConfiguration.java} | 4 +- ...arDiscovery.java => VehicleDiscovery.java} | 20 +-- .../internal/dto/discovery/Vehicle.java | 1 - .../handler/ConnectedDriveBridgeHandler.java | 22 ++- .../internal/handler/ConnectedDriveProxy.java | 43 +++-- .../handler/RemoteServiceHandler.java | 11 +- ...andler.java => VehicleChannelHandler.java} | 8 +- ...tedCarHandler.java => VehicleHandler.java} | 32 ++-- .../internal/utils/Converter.java | 2 +- .../ESH-INF/thing/bridge-connected-drive.xml | 15 +- .../resources/ESH-INF/thing/thing-bev.xml | 14 +- .../resources/ESH-INF/thing/thing-bev_rex.xml | 6 +- .../resources/ESH-INF/thing/thing-conv.xml | 8 +- .../resources/ESH-INF/thing/thing-phev.xml | 8 +- .../internal/discovery/DiscoveryTest.java | 4 +- .../internal/dto/ConnectedDriveTest.java | 4 +- .../internal/dto/StatusWrapper.java | 10 +- .../internal/handler/AuthTest.java | 2 +- .../internal/handler/ChargeProfileTest.java | 10 +- .../internal/handler/ErrorResponseTest.java | 27 +-- .../{CarTests.java => VehicleTests.java} | 86 +++++----- .../internal/util/LocaleTest.java | 8 +- 25 files changed, 311 insertions(+), 243 deletions(-) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/{ConnectedCarConfiguration.java => VehicleConfiguration.java} (92%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/{ConnectedCarDiscovery.java => VehicleDiscovery.java} (91%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/{ConnectedCarChannelHandler.java => VehicleChannelHandler.java} (97%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/{ConnectedCarHandler.java => VehicleHandler.java} (96%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/{CarTests.java => VehicleTests.java} (82%) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 2e323a1d0f7c5..b1ab49954e53c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -3,7 +3,7 @@ The Binding connects your BMW Vehicles which are registered in the _Garage_ of your BMW ConnectedDrive Portal. -Due to the high variety of Cars and Online Services you need to check which Channels are applicable to your Vehicle. +Due to the high variety of Vehicles and Online Services you need to check which Channels are applicable to your Vehicle. The Discovery Service recognizes your Vehicle with the correct type * Conventional Fuel Vehicle @@ -12,7 +12,7 @@ The Discovery Service recognizes your Vehicle with the correct type * Battery Electric Vehicle In addition Properties are attached to the Vehicle Thing to observe the Supported & Activated Services. -Different Channel Groups are available so you are able to cross-check which group is supported by your Car. +Different Channel Groups are available so you are able to cross-check which group is supported by your Vehicle. Please note **this isn't a _real-time_ Binding**. If you open the Door the state isn't transmitted immediately and shown in your GUI. @@ -37,10 +37,10 @@ For Hybrid Vehicles _fuel range_ and _electric range_ is provided and in additio | Name | Thing Type ID | Supported Channel Groups | |-------------------------------------|---------------|------------------------------------------------------------| -| BMW Electric Vehicle | BEV | status, range, last-trip, all-trips, charge-profile, image, troubeshoot | -| BMW Electric Vehicle with REX | BEV_REX | status, range, last-trip, all-trips, charge-profile, image, troubeshoot | -| BMW Plug-In-Hybrid Electric Vehicle | PHEV | status, range, last-trip, all-trips, image, troubeshoot | -| BMW Conventional Vehicle | CONV | status, range, last-trip, all-trips, image, troubeshoot | +| BMW Electric Vehicle | BEV | status, range, last-trip, all-trips, charge-profile, image, troubleshoot | +| BMW Electric Vehicle with REX | BEV_REX | status, range, last-trip, all-trips, charge-profile, image, troubleshoot | +| BMW Plug-In-Hybrid Electric Vehicle | PHEV | status, range, last-trip, all-trips, image, troubleshoot | +| BMW Conventional Vehicle | CONV | status, range, last-trip, all-trips, image, troubleshoot | #### Properties @@ -96,18 +96,18 @@ All Things are needing the same Configuration Data The units can be configured in 3 ways -* _AUTODETECT_ selects Miles for US & UK, Kilometre otherwise +* _AUTODETECT_ selects Miles for US & UK, Kilometer otherwise * _METRIC_ selects directly Kilometers * _IMPERIAL_ selects directly Miles -The imageVieport allows you to show your Car from different angels. +The imageVieport allows you to show your Vehicle from different angels. Possible values are FRONT, REAR, SIDE, DASHBOARD or DRIVERDOOR ## Channels There are many Channels available for each Vehicle. For better overview they are clustered in different Channel Groups. -The Channel Groups are different for the Car Types but also depends on the build in Sensors of your Car. +The Channel Groups are different for the Vehicle Types but also depends on the build in Sensors of your Vehicle. This means also the Construction Year is relevant if some Channels are supported or not. ### Bridge Channels @@ -134,7 +134,7 @@ Available for all Vehicles. #### Channel Group _Range Data_ Based on Vehicle Type (Thing Type ID) some Channels are presented or not. -For Conventional Fuel Cars the _Electric Range_ isn't presented while for Battery Electric Vehicles _Range Fuel_ isn't valid. +For Conventional Fuel Vehicles the _Electric Range_ isn't presented while for Battery Electric Vehicles _Range Fuel_ isn't valid. Hybrid Vehicles have both and in addition _Hybrid Range_ | Channel Label | Channel Group ID | Channel ID | Type | Valid for | Description | @@ -246,7 +246,7 @@ I've done my best to eliminate any private data from these Fingerprints. Following data is replaced with ANONYMOUS data * Dealer Properties -* Vehcile Identification Number (VIN) +* Vehicle Identification Number (VIN) * Location Latitude / Longitude is set to 0 After you've generated the corresponding Fingerprint please [follow the instructions to raise an Issue](https://community.openhab.org/t/how-to-file-an-issue/68464) and attach the Fingerprint data! @@ -293,36 +293,37 @@ Bridge bmwconnecteddrive:account:user "BMW ConnectedDrive Account" [userName=" ### Items ``` -Number:Length i3Mileage "Odometer" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#mileage" } -Number:Length i3Range "Hybrid Range" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-range-hybrid"} -Number:Length i3RangeElectric "Electric Range" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-range-electric"} -Number:Length i3RangeFuel "Fuel Range" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-range-fuel"} -Number:Dimensionless i3BatterySoc "Battery Charged" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-soc"} -Number:Dimensionless i3Fuel "Fuel Charged" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-fuel"} -String i3LastUpdate "Updated" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#last-update"} - -String i3DoorStatus "Door Status" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#doors" } -String i3WindowStatus "Window Status" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#windows" } -String i3LockStatus "Locked Status" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#lock" } -String i3ServiceStatus "Service" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#service" } -String i3CheckControl "Check Control" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#check-control" } -String i3ChargingStatus "Charging" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#charging-status" } - -Number:Length i3TripDistance "Distance" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance" } -Number:Length i3TripDistanceSinceCharge "Driven Since last Charge" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance-since-charging" } -Number:Energy i3AvgTripConsumption "Average Consumption" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-consumption" } -Number:Energy i3AvgTripRecuperation "Average Recuperation" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-recuperation" } - -Number:Length i3CumulatedElectric "Eletric Driven Distance" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#cumulated-driven-distance" } -Number:Length i3LongestEVTrip "Longest Eletric Trip" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#single-longest-distance" } +Number:Length i3Mileage "Odometer" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#mileage" } +Number:Length i3Range "Hybrid Range" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#hybrid"} +Number:Length i3RangeElectric "Electric Range" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#electric"} +Number:Length i3RangeFuel "Fuel Range" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#fuel"} +Number:Dimensionless i3BatterySoc "Battery Charged" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#soc"} +Number:Volume i3Fuel "Fuel Charged" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-fuel"} +Number:Length i3RadiusElectric "Range Radius Electric" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#radius-electric" } +Number:Length i3RadiusHybrid "Range Radius Hybrid" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#radius-hybrid" } + +String i3DoorStatus "Door Status" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#doors" } +String i3WindowStatus "Window Status" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#windows" } +String i3LockStatus "Locked Status" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#lock" } +String i3ServiceStatus "Service" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#service" } +String i3CheckControl "Check Control" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#check-control" } +String i3LastUpdate "Updated" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#last-update"} + +String i3ChargingStatus "Charging" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:charge#charging-status" } + +Number:Length i3TripDistance "Distance" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance" } +Number:Length i3TripDistanceSinceCharge "Driven Since last Charge" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance-since-charging" } +Number:Energy i3AvgTripConsumption "Average Consumption" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-consumption" } +Number:Energy i3AvgTripRecuperation "Average Recuperation" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-recuperation" } + +Number:Length i3CumulatedElectric "Electric Driven Distance" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#cumulated-driven-distance" } +Number:Length i3LongestEVTrip "Longest Electric Trip" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#single-longest-distance" } Number:Energy i3AvgConsumption "Average Consumption" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#average-consumption" } Number:Energy i3AvgRecuperation "Average Recuperation" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#average-recuperation" } Number i3Longitude "Location Longitude" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:location#longitude" } Number i3Latitude "Location Latitude" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:location#latitude" } -String i3LatLong "Location as String" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:location#latlong" } Number:Angle i3Heading "Vehicle Heading" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:location#heading" } -Number i3RangeRadius "Range Radius" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:location#range-radius" } Switch i3RemoteFlash "Remote Flashlight" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#light" } Switch i3RemoteFinder "Remote Flashlight" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#finder" } @@ -332,10 +333,35 @@ Switch i3RemoteHorn "Remote Flashlight" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#climate" } String i3RemoteState "Remote Flashlight" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#state" } -Image i3Image "Car Image" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:image#rendered" } - -Switch i3Troubleshoot "Force Fingerprint Log" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:troubleshoot#cardata-fingerprint" } -Switch i3DiscoveryFinger "Discovery Fingerprint" (i3) {channel="bmwconnecteddrive:account:user:discovery-fingerprint"} +String i3Dest1Name "Destination Name" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#name-1" } +Number i3Dest1Lat "Destination Longitude" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lat-1" } +Number i3Dest1Lon "Destination Latitude" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lon-1" } +String i3Dest2Name "Destination Name" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#name-2" } +Number i3Dest2Lat "Destination Longitude" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lat-2" } +Number i3Dest2Lon "Destination Latitude" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lon-2" } +String i3Dest3Name "Destination Name" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#name-3" } +Number i3Dest3Lat "Destination Longitude" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lat-3" } +Number i3Dest3Lon "Destination Latitude" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lon-3" } + +String i3ChargingStatus "Charge Status" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:charge#status" } +Switch i3ChargeProfileClimate "Charge Profile Climatisation" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:charge#profile-climate" } +String i3ChargeProfileMode "Charge Profile Mode" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:charge#profile-mode" } +String i3ChargeWindowStart "Charge Window Start" - + String - + + + + String + + + + String + String diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-group.xml index 2052309b5f157..25791027ec6dd 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-group.xml @@ -10,7 +10,9 @@ - + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index 116d96b039198..728ad7a4c1f79 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -175,10 +175,27 @@ private void checkResult(ChannelUID channelUID, State state) { st = (StringType) state; assertEquals("Check Control", vStatus.getCheckControl(), st.toString()); break; - case SERVICE: + case SERVICE_DATE: assertTrue(state instanceof StringType); st = (StringType) state; - assertEquals("Next Service", vStatus.getNextService(imperial), st.toString()); + assertEquals("Next Service", vStatus.getNextService(imperial).getDueDate(), st.toString()); + break; + case SERVICE_MILEAGE: + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + if (imperial) { + assertEquals("Miles", ImperialUnits.MILE, qt.getUnit()); + assertEquals("Mileage", vStatus.getNextService(imperial).cbsRemainingMileage, qt.intValue()); + } else { + assertEquals("KM", KILOMETRE, qt.getUnit()); + assertEquals("Mileage", vStatus.getNextService(imperial).cbsRemainingMileage, qt.intValue()); + } + break; + case SERVICE_NAME: + assertTrue(state instanceof StringType); + st = (StringType) state; + assertEquals("Next Service", Converter.toTitleCase(vStatus.getNextService(imperial).getType()), + st.toString()); break; case CHARGE_STATUS: assertTrue("Is Eelctric", isElectric); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java index f883117ac522f..036929158599a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java @@ -45,9 +45,9 @@ public class VehicleTests { private final Logger logger = LoggerFactory.getLogger(VehicleHandler.class); - private final int HYBRID_CALL_TIMES = 19; - private final int CONV_CALL_TIMES = 13; - private final int EV_CALL_TIMES = 14; + private final int HYBRID_CALL_TIMES = 21; + private final int CONV_CALL_TIMES = 15; + private final int EV_CALL_TIMES = 16; @Nullable ArgumentCaptor channelCaptor; From 1c610e018e67d85d9764e7707e4b68fa2f9e1e8f Mon Sep 17 00:00:00 2001 From: Bernd Date: Mon, 7 Sep 2020 16:53:56 +0200 Subject: [PATCH 023/176] hard-coded checks for StatusWrapper Signed-off-by: Bernd (cherry picked from commit 975064fa6a6021ba5593e1eed37e4e99fe803a65) Signed-off-by: Bernd --- .../internal/ConnectedDriveConstants.java | 4 ++ .../ConnectedDriveHandlerFactory.java | 6 +- .../internal/VehicleConfiguration.java | 11 ++-- .../internal/discovery/VehicleDiscovery.java | 32 ++++++---- .../internal/dto/status/CBSMessage.java | 6 ++ .../internal/dto/status/VehicleStatus.java | 18 ++---- .../handler/ConnectedDriveBridgeHandler.java | 8 +-- .../internal/handler/ConnectedDriveProxy.java | 1 - .../internal/handler/Token.java | 5 +- .../internal/dto/StatusWrapper.java | 46 +++++++++++++-- .../internal/handler/VehicleTests.java | 59 ++++++++++++------- 11 files changed, 127 insertions(+), 69 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 8a31ff383feb7..c23d889917212 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -35,6 +35,10 @@ public class ConnectedDriveConstants { public static final String UNITS_IMPERIAL = "IMPERIAL"; public static final String UNITS_METRIC = "METRIC"; + public static final int DEFAULT_IMAGE_SIZE = 600; + public static final int DEFAULT_REFRESH_INTERVAL = 5; + public static final String DEFAULT_IMAGE_VIEWPORT = "FRONT"; + // See constants from bimmer-connected // https://github.com/bimmerconnected/bimmer_connected/blob/master/bimmer_connected/vehicle.py public enum VehicleType { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java index 3f68e646f722b..7627f33fc13b1 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java @@ -64,10 +64,10 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { if (THING_TYPE_CONNECTED_DRIVE_ACCOUNT.equals(thingTypeUID)) { return new ConnectedDriveBridgeHandler((Bridge) thing, httpClientFactory, bundleContext); } else if (SUPPORTED_THING_SET.contains(thingTypeUID)) { - VehicleHandler cch = new VehicleHandler(thing, httpClientFactory.getCommonHttpClient(), + VehicleHandler vh = new VehicleHandler(thing, httpClientFactory.getCommonHttpClient(), thingTypeUID.getId(), imperial); - VEHICLE_HANDLER_REGISTRY.add(cch); - return cch; + VEHICLE_HANDLER_REGISTRY.add(vh); + return vh; } return null; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/VehicleConfiguration.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/VehicleConfiguration.java index fec158661e311..3a1dfc1347843 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/VehicleConfiguration.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/VehicleConfiguration.java @@ -30,7 +30,7 @@ public class VehicleConfiguration { /** * Data refresh rate in minutes */ - public int refreshInterval = 15; + public int refreshInterval = ConnectedDriveConstants.DEFAULT_IMAGE_SIZE; /** * Either Auto Detect Miles units (UK & US) or select Format directly @@ -38,23 +38,20 @@ public class VehicleConfiguration { * * */ - public String units = "AUTODETECT"; + public String units = ConnectedDriveConstants.UNITS_AUTODETECT; /** * image size - width & length (square) */ - public int imageSize = 300; + public int imageSize = ConnectedDriveConstants.DEFAULT_IMAGE_SIZE; /** * image viewport defined as options in thing xml - * * - * * * * * - * */ - public String imageViewport = "FRONT"; + public String imageViewport = ConnectedDriveConstants.DEFAULT_IMAGE_VIEWPORT; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java index ce45ec20d8511..cb28206a19902 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java @@ -26,6 +26,7 @@ import org.eclipse.smarthome.config.discovery.DiscoveryResultBuilder; import org.eclipse.smarthome.core.thing.Thing; import org.eclipse.smarthome.core.thing.ThingUID; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveHandlerFactory; import org.openhab.binding.bmwconnecteddrive.internal.dto.discovery.Vehicle; import org.openhab.binding.bmwconnecteddrive.internal.dto.discovery.VehiclesContainer; @@ -37,7 +38,7 @@ import org.slf4j.LoggerFactory; /** - * The {@link VehicleDiscovery} decodes the initial query from ConnectedDrive and is creating + * The {@link VehicleDiscovery} requests data from ConnectedDrive and is identifying the Vehicles after response * * @author Bernd Weymann - Initial contribution */ @@ -135,10 +136,10 @@ public void onResponse(VehiclesContainer container) { if (!foundVehicle.get()) { // Properties needed for functional THing properties.put("vin", vehicle.vin); - properties.put("refreshInterval", Integer.toString(15)); - properties.put("units", "AUTODETECT"); - properties.put("imageSize", Integer.toString(500)); - properties.put("imageViewport", "FRONT"); + properties.put("refreshInterval", Integer.toString(5)); + properties.put("units", ConnectedDriveConstants.UNITS_AUTODETECT); + properties.put("imageSize", Integer.toString(ConnectedDriveConstants.DEFAULT_IMAGE_SIZE)); + properties.put("imageViewport", ConnectedDriveConstants.DEFAULT_IMAGE_VIEWPORT); String vehicleLabel = vehicle.brand + " " + vehicle.model; logger.debug("Thing {} discovered", vehicleLabel); @@ -149,23 +150,30 @@ public void onResponse(VehiclesContainer container) { } } }); - }); } - public String getObject(Object obj, String compare) { + /** + * Get all field names from a DTO with a specific value + * Used to get e.g. all services which are "ACTIVATED" + * + * @param DTO Object + * @param compare String which needs to map with the value + * @return String with all field names matching this value separated with Spaces + */ + public String getObject(Object dto, String compare) { StringBuffer buf = new StringBuffer(); - for (Field field : obj.getClass().getDeclaredFields()) { + for (Field field : dto.getClass().getDeclaredFields()) { try { - if (field.get(obj) != null) { - if (field.get(obj).equals(compare)) { + if (field.get(dto) != null) { + if (field.get(dto).equals(compare)) { buf.append(Converter.capitalizeFirst(field.getName()) + Constants.SPACE); } } } catch (IllegalArgumentException e) { - logger.warn("Field {} not found {}", compare, e.getMessage()); + logger.debug("Field {} not found {}", compare, e.getMessage()); } catch (IllegalAccessException e) { - logger.warn("Field {} not found {}", compare, e.getMessage()); + logger.debug("Field {} not found {}", compare, e.getMessage()); } } return buf.toString(); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java index 8ac055a7cc795..23a77254c49af 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java @@ -41,4 +41,10 @@ public String getType() { return cbsType; } } + + @Override + public String toString() { + return new StringBuffer(cbsDueDate).append(Constants.HYPHEN).append(cbsRemainingMileage) + .append(Constants.HYPHEN).append(cbsType).toString(); + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java index 2c784a6e14553..889ef89fce99b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java @@ -89,38 +89,28 @@ public CBSMessage getNextService(boolean imperial) { } else { int serviceMileage = Integer.MAX_VALUE; LocalDate serviceDate = LocalDate.now().plusYears(100); - String service = null; for (int i = 0; i < cbsData.size(); i++) { CBSMessage entry = cbsData.get(i); - String serviceDescription = Converter.toTitleCase(entry.cbsType); if (entry.cbsRemainingMileage != 0 && entry.cbsDueDate != null) { LocalDate d = LocalDate.parse(entry.cbsDueDate + APPENDIX_DAY, Converter.SERVICE_DATE_INPUT_PATTERN); if ((entry.cbsRemainingMileage < serviceMileage) || (d.isBefore(serviceDate))) { + serviceDate = d; + serviceMileage = entry.cbsRemainingMileage; cbs = entry; - // serviceDate = d; - // serviceMileage = entry.cbsRemainingMileage; - // service = new StringBuffer(serviceDate.format(Converter.SERVICE_DATE_OUTPUT_PATTERN)) - // .append(" or in ").append(serviceMileage).append(" ").append(getUnit(imperial)) - // .append(" - ").append(serviceDescription).toString(); } } else if (entry.cbsRemainingMileage != 0) { if (entry.cbsRemainingMileage < serviceMileage) { + serviceMileage = entry.cbsRemainingMileage; cbs = entry; - // serviceMileage = entry.cbsRemainingMileage; - // service = new StringBuffer("In ").append(serviceMileage).append(" - // ").append(getUnit(imperial)) - // .append(" - ").append(serviceDescription).toString(); } } else if (entry.cbsDueDate != null) { LocalDate d = LocalDate.parse(entry.cbsDueDate + APPENDIX_DAY, Converter.SERVICE_DATE_INPUT_PATTERN); if (d.isBefore(serviceDate)) { + serviceDate = d; cbs = entry; - // serviceDate = d; - // service = new StringBuffer(serviceDate.format(Converter.SERVICE_DATE_OUTPUT_PATTERN)) - // .append(" - ").append(serviceDescription).toString(); } } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java index 3e6254116f3c9..45c8ed9f15435 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java @@ -30,7 +30,6 @@ import org.eclipse.smarthome.core.types.Command; import org.eclipse.smarthome.io.net.http.HttpClientFactory; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConfiguration; -import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants; import org.openhab.binding.bmwconnecteddrive.internal.discovery.VehicleDiscovery; import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; import org.openhab.binding.bmwconnecteddrive.internal.dto.discovery.Dealer; @@ -59,6 +58,8 @@ public class ConnectedDriveBridgeHandler extends BaseBridgeHandler implements St private Optional configuration = Optional.empty(); private Optional> refreshJob = Optional.empty(); private Optional troubleshootFingerprint = Optional.empty(); + + private static final String DISCOVERY_FINGERPRINT = "discovery-fingerprint"; private ChannelUID discoveryFingerprintChannel; public ConnectedDriveBridgeHandler(Bridge bridge, HttpClientFactory hcf, BundleContext bc) { @@ -68,13 +69,12 @@ public ConnectedDriveBridgeHandler(Bridge bridge, HttpClientFactory hcf, BundleC discoveryService = new VehicleDiscovery(this); discoveryServiceRegstration = bundleContext.registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<>()); - discoveryFingerprintChannel = new ChannelUID(bridge.getUID(), ConnectedDriveConstants.DISCOVERY_FINGERPRINT); + discoveryFingerprintChannel = new ChannelUID(bridge.getUID(), DISCOVERY_FINGERPRINT); } @Override public void handleCommand(ChannelUID channelUID, Command command) { - if (ConnectedDriveConstants.DISCOVERY_FINGERPRINT.equals(channelUID.getIdWithoutGroup()) - && command instanceof OnOffType) { + if (DISCOVERY_FINGERPRINT.equals(channelUID.getIdWithoutGroup()) && command instanceof OnOffType) { if (command.equals(OnOffType.ON)) { logger.warn( "###### BMW ConnectedDrive Binding - Discovery Troubleshoot Fingerprint Data - BEGIN ######"); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index edae4dc7e91ed..7802be4ac8a3a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -249,7 +249,6 @@ public synchronized Token getNewToken() { return new Token(); } - @SuppressWarnings("null") public Token getTokenFromUrl(String encodedUrl) { MultiMap tokenMap = new MultiMap(); UrlEncoded.decodeTo(encodedUrl, tokenMap, StandardCharsets.US_ASCII); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java index b18391af78631..2a99efde9a8da 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java @@ -38,8 +38,11 @@ public void setExpiration(int expiration) { this.expiration = System.currentTimeMillis() / 1000 + expiration; } + /** + * @return true if Token expires in less than 1 second + */ public boolean isExpired() { - return (expiration - System.currentTimeMillis() / 1000) < 2; + return (expiration - System.currentTimeMillis() / 1000) < 1; } public void setType(String type) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index 728ad7a4c1f79..d6f606d722103 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -15,7 +15,9 @@ import static org.junit.Assert.*; import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.measure.Unit; import javax.measure.quantity.Length; @@ -57,6 +59,8 @@ public class StatusWrapper { private boolean hasFuel; private boolean isHybrid; + private Map specialHandlingMap = new HashMap(); + public StatusWrapper(String type, boolean imperial, String statusJson) { this.imperial = imperial; hasFuel = type.equals(VehicleType.CONVENTIONAL.toString()) || type.equals(VehicleType.PLUGIN_HYBRID.toString()) @@ -70,6 +74,13 @@ public StatusWrapper(String type, boolean imperial, String statusJson) { vStatus = container.vehicleStatus; } + /** + * Test results auctomatically against json values + * + * @param channels + * @param states + * @return + */ public boolean checkResults(@Nullable List channels, @Nullable List states) { assertNotNull(channels); assertNotNull(states); @@ -80,6 +91,17 @@ public boolean checkResults(@Nullable List channels, @Nullable List< return true; } + /** + * Add a specific check for a value e.g. hard coded "Upcoming Service" in order to check the right ordering + * + * @param specialHand + * @return + */ + public StatusWrapper append(Map compareMap) { + specialHandlingMap.putAll(compareMap); + return this; + } + private void checkResult(ChannelUID channelUID, State state) { String cUid = channelUID.getIdWithoutGroup(); QuantityType qt; @@ -173,29 +195,41 @@ private void checkResult(ChannelUID channelUID, State state) { case CHECK_CONTROL: assertTrue(state instanceof StringType); st = (StringType) state; - assertEquals("Check Control", vStatus.getCheckControl(), st.toString()); + if (specialHandlingMap.containsKey(CHECK_CONTROL)) { + assertEquals("Next Service", specialHandlingMap.get(CHECK_CONTROL).toString(), st.toString()); + } else { + assertEquals("Check Control", vStatus.getCheckControl(), st.toString()); + } break; case SERVICE_DATE: assertTrue(state instanceof StringType); st = (StringType) state; - assertEquals("Next Service", vStatus.getNextService(imperial).getDueDate(), st.toString()); + if (specialHandlingMap.containsKey(SERVICE_DATE)) { + assertEquals("Next Service", specialHandlingMap.get(SERVICE_DATE).toString(), st.toString()); + } else { + assertEquals("Next Service", vStatus.getNextService(imperial).getDueDate(), st.toString()); + } break; case SERVICE_MILEAGE: assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); if (imperial) { - assertEquals("Miles", ImperialUnits.MILE, qt.getUnit()); + assertEquals("Next Service Miles", ImperialUnits.MILE, qt.getUnit()); assertEquals("Mileage", vStatus.getNextService(imperial).cbsRemainingMileage, qt.intValue()); } else { - assertEquals("KM", KILOMETRE, qt.getUnit()); + assertEquals("Next Service KM", KILOMETRE, qt.getUnit()); assertEquals("Mileage", vStatus.getNextService(imperial).cbsRemainingMileage, qt.intValue()); } break; case SERVICE_NAME: assertTrue(state instanceof StringType); st = (StringType) state; - assertEquals("Next Service", Converter.toTitleCase(vStatus.getNextService(imperial).getType()), - st.toString()); + if (specialHandlingMap.containsKey(SERVICE_NAME)) { + assertEquals("Next Service Name", specialHandlingMap.get(SERVICE_NAME).toString(), st.toString()); + } else { + assertEquals("Next Service Name", Converter.toTitleCase(vStatus.getNextService(imperial).getType()), + st.toString()); + } break; case CHARGE_STATUS: assertTrue("Is Eelctric", isElectric); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java index 036929158599a..bb37ced88f4a5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java @@ -15,12 +15,15 @@ import static org.junit.Assert.*; import static org.mockito.Mockito.*; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jetty.client.HttpClient; +import org.eclipse.smarthome.core.library.types.StringType; import org.eclipse.smarthome.core.thing.ChannelUID; import org.eclipse.smarthome.core.thing.Thing; import org.eclipse.smarthome.core.thing.ThingUID; @@ -28,6 +31,7 @@ import org.eclipse.smarthome.core.types.State; import org.junit.Test; import org.mockito.ArgumentCaptor; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; import org.openhab.binding.bmwconnecteddrive.internal.dto.StatusWrapper; import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; @@ -80,9 +84,9 @@ public void setup(String type, boolean imperial) { stateCaptor = ArgumentCaptor.forClass(State.class); } - private boolean testVehicle(String statusContent, int callbacksExpected) { + private boolean testVehicle(String statusContent, int callbacksExpected, + Optional> concreteChecks) { assertNotNull(statusContent); - cch.vehicleStatusCallback.onResponse(Optional.of(statusContent)); verify(tc, times(callbacksExpected)).stateUpdated(channelCaptor.capture(), stateCaptor.capture()); allChannels = channelCaptor.getAllValues(); @@ -91,7 +95,11 @@ private boolean testVehicle(String statusContent, int callbacksExpected) { assertNotNull(driveTrain); StatusWrapper checker = new StatusWrapper(driveTrain, imperial, statusContent); trace(); - return checker.checkResults(allChannels, allStates); + if (concreteChecks.isPresent()) { + return checker.append(concreteChecks.get()).checkResults(allChannels, allStates); + } else { + return checker.checkResults(allChannels, allStates); + } } private void trace() { @@ -126,7 +134,7 @@ public void testMyi3Rex() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC_REX.toString(), false); String content = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES)); + assertTrue(testVehicle(content, HYBRID_CALL_TIMES, Optional.empty())); } /** @@ -154,7 +162,7 @@ public void testMyi3RexMiles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC_REX.toString(), true); String content = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES)); + assertTrue(testVehicle(content, HYBRID_CALL_TIMES, Optional.empty())); } /** @@ -178,7 +186,10 @@ public void testF15() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F15/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES)); + // Check earliest Service by hard + Map m = new HashMap(); + m.put(ConnectedDriveConstants.SERVICE_DATE, StringType.valueOf("2018-06")); + assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.of(m))); } @Test @@ -186,7 +197,10 @@ public void testF15Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F15/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES)); + // Check earliest Service by hard + Map m = new HashMap(); + m.put(ConnectedDriveConstants.SERVICE_DATE, StringType.valueOf("2018-06")); + assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.of(m))); } /** @@ -210,7 +224,7 @@ public void testF31() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F31/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES)); + assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); } @Test @@ -218,7 +232,7 @@ public void testF31Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F31/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES)); + assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); } @Test @@ -226,7 +240,7 @@ public void testF35() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F35/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES)); + assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); } @Test @@ -234,7 +248,7 @@ public void testF35Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F35/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES)); + assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); } @Test @@ -242,7 +256,7 @@ public void testF45() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F45/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES)); + assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); } @Test @@ -250,7 +264,7 @@ public void testF45Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F45/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES)); + assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); } @Test @@ -258,7 +272,10 @@ public void testF48() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F48/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES)); + // Check earliest Service by hard + Map m = new HashMap(); + m.put(ConnectedDriveConstants.CHECK_CONTROL, StringType.valueOf("Tyre Pressure Notification")); + assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.of(m))); } @Test @@ -266,7 +283,7 @@ public void testF48Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F48/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES)); + assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); } @Test @@ -274,7 +291,7 @@ public void testG31NBTEvo() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/G31_NBTevo/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES)); + assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); } @Test @@ -282,7 +299,7 @@ public void testG31NBTEvoMiles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/G31_NBTevo/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES)); + assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); } @Test @@ -290,7 +307,7 @@ public void testI01NoRex() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/I01_NOREX/status.json"); - assertTrue(testVehicle(content, EV_CALL_TIMES)); + assertTrue(testVehicle(content, EV_CALL_TIMES, Optional.empty())); } @Test @@ -298,7 +315,7 @@ public void testI01NoRexMiles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/I01_NOREX/status.json"); - assertTrue(testVehicle(content, EV_CALL_TIMES)); + assertTrue(testVehicle(content, EV_CALL_TIMES, Optional.empty())); } @Test @@ -306,7 +323,7 @@ public void testI01Rex() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC_REX.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/I01_REX/status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES)); + assertTrue(testVehicle(content, HYBRID_CALL_TIMES, Optional.empty())); } @Test @@ -314,6 +331,6 @@ public void testI01RexMiles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC_REX.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/I01_REX/status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES)); + assertTrue(testVehicle(content, HYBRID_CALL_TIMES, Optional.empty())); } } From 3f0bd53d7eadf5d8e43fa877d6312167b7556455 Mon Sep 17 00:00:00 2001 From: Bernd Date: Thu, 10 Sep 2020 15:41:57 +0200 Subject: [PATCH 024/176] date time corrections Signed-off-by: Bernd (cherry picked from commit d983c7989465e85188a30f019c9ead6dba20e973) Signed-off-by: Bernd --- .../README.md | 142 ++++++++++++++---- .../doc/panel.png | Bin 0 -> 1317196 bytes .../ConnectedDriveHandlerFactory.java | 4 +- .../internal/dto/charge/Timer.java | 1 - .../internal/dto/status/CBSMessage.java | 4 +- .../internal/dto/status/VehicleStatus.java | 25 ++- .../internal/handler/VehicleHandler.java | 11 +- .../internal/utils/Constants.java | 5 +- .../internal/utils/Converter.java | 28 +++- .../i18n/bmwconnecteddrive_be.properties | 104 ++++++++++--- .../ESH-INF/thing/bridge-connected-drive.xml | 2 +- .../ESH-INF/thing/ev-last-trip-group.xml | 2 +- .../resources/ESH-INF/thing/thing-bev.xml | 6 +- .../resources/ESH-INF/thing/thing-bev_rex.xml | 4 +- .../resources/ESH-INF/thing/thing-conv.xml | 4 +- .../resources/ESH-INF/thing/thing-phev.xml | 6 +- .../thing/troubleshoot-channel-types.xml | 2 +- .../internal/dto/StatusWrapper.java | 23 +-- .../internal/handler/VehicleTests.java | 5 +- .../internal/util/LocaleTest.java | 24 +-- 20 files changed, 293 insertions(+), 109 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/doc/panel.png diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index b1ab49954e53c..7d8174f44c1f8 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -2,8 +2,8 @@ -The Binding connects your BMW Vehicles which are registered in the _Garage_ of your BMW ConnectedDrive Portal. -Due to the high variety of Vehicles and Online Services you need to check which Channels are applicable to your Vehicle. +The Binding connects your Vehicles listed in BMWs ConnectedDrive Portal with openHAB. +Due to the high range of Vehicles BMW provides you need to check which Channels are applicable. The Discovery Service recognizes your Vehicle with the correct type * Conventional Fuel Vehicle @@ -37,11 +37,12 @@ For Hybrid Vehicles _fuel range_ and _electric range_ is provided and in additio | Name | Thing Type ID | Supported Channel Groups | |-------------------------------------|---------------|------------------------------------------------------------| -| BMW Electric Vehicle | BEV | status, range, last-trip, all-trips, charge-profile, image, troubleshoot | -| BMW Electric Vehicle with REX | BEV_REX | status, range, last-trip, all-trips, charge-profile, image, troubleshoot | -| BMW Plug-In-Hybrid Electric Vehicle | PHEV | status, range, last-trip, all-trips, image, troubleshoot | -| BMW Conventional Vehicle | CONV | status, range, last-trip, all-trips, image, troubleshoot | +| BMW Electric Vehicle | BEV | status, range, remote, location, destination, image, troubleshoot, charge, last-trip, lifetime | +| BMW Electric Vehicle with REX | BEV_REX | status, range, remote, location, destination, image, troubleshoot, charge, last-trip, lifetime | +| BMW Plug-In-Hybrid Electric Vehicle | PHEV | status, range, remote, location, destination, image, troubleshoot, charge | +| BMW Conventional Vehicle | CONV | status, range, remote, location, destination, image, troubleshoot | + #### Properties @@ -101,7 +102,13 @@ The units can be configured in 3 ways * _IMPERIAL_ selects directly Miles The imageVieport allows you to show your Vehicle from different angels. -Possible values are FRONT, REAR, SIDE, DASHBOARD or DRIVERDOOR +Possible values are + +* FRONT +* REAR +* SIDE +* DASHBOARD +* DRIVERDOOR ## Channels @@ -127,15 +134,16 @@ Available for all Vehicles. | Door Status | status | doors | String | Closed if all closed, else reports the Door which is still open | | Window Status | status | windows | String | Closed if all closed, else reports the Window which is still open | | Doors Locked | status | lock | String | Status if Doors are locked or unlocked | -| Upcoming Service | status | service | String | Upcoming Service either after certain Mileage, Date, or both | +| Upcoming Service | status | service-date | String | Date of Upcoming Service | +| Upcoming Service | status | service-mileage | Number:Length | Mileage till Upcoming Service | +| Upcoming Service | status | service-name | String | Description of Upcoming Service | | Check Control | status | check-control | String | Description of actual Check Control message, Ok if none is activated | - #### Channel Group _Range Data_ Based on Vehicle Type (Thing Type ID) some Channels are presented or not. -For Conventional Fuel Vehicles the _Electric Range_ isn't presented while for Battery Electric Vehicles _Range Fuel_ isn't valid. -Hybrid Vehicles have both and in addition _Hybrid Range_ +For Conventional Fuel Vehicles the *Electric Range* isn't presented while for Battery Electric Vehicles *Range Fuel* isn't valid. +Hybrid Vehicles have both and in addition *Hybrid Range* | Channel Label | Channel Group ID | Channel ID | Type | Valid for | Description | |-----------------------|------------------|---------------------|----------------------|-------------------------|----------------------------------------| @@ -146,7 +154,29 @@ Hybrid Vehicles have both and in addition _Hybrid Range_ | Fuel Range | range | range-fuel | Number:Length | CONV PHEV BEV_REX | Fuel Range | | Remaining Fuel | range | remaining-fuel | Number:Volume | CONV PHEV BEV_REX | Remaining Fuel in Liters | -#### Channel Group _Vehicle Location_ +#### Channel Group _Electric Charging_ + +Valid for Electric and Hybrid Vehicles + +| Channel Label | Channel Group ID | Channel ID | Type | +|------------------------------------|------------------|---------------------|--------| +| Charging Status | charge | status | String | +| Air Conditioning at Departure Time | charge | profile-climate | Switch | +| Charging Mode for Profile | charge | profile-mode | String | +| Charging Window Start Time | charge | window-start | String | +| Charging Window End Time | charge | window-end | String | +| Timer 1: Departure Time | charge | timer1-departure | String | +| Timer 1: Scheduled Days | charge | timer1-days | String | +| Timer 1: Enabled | charge | timer1-enabled | Switch | +| Timer 2: Departure Time | charge | timer2-departure | String | +| Timer 2: Scheduled Days | charge | timer2-days | String | +| Timer 2: Enabled | charge | timer2-enabled | Switch | +| Timer 3: Departure Time | charge | timer3-departure | String | +| Timer 3: Scheduled Days | charge | timer3-days | String | +| Timer 3: Enabled | charge | timer3-enabled | Switch | + + +#### Channel Group _Location_ Available for all Vehicles. @@ -156,9 +186,12 @@ Available for all Vehicles. | Longitude | location | longitude | Number | | Heading | location | heading | Number:Angle | +#### Channel Group _Cha_ + + #### Channel Group _Last Trip_ -Check in your Vehicle Thing Properties if _Statistics_ is present in _Services Supported_ +Check in your Vehicle Thing Properties if *Statistics* is present in *Services Supported* | Channel Label | Channel Group ID | Channel ID | Type | Description | |-----------------------------|------------------|-------------------------|---------------|---------------------------------------------------| @@ -170,7 +203,7 @@ Check in your Vehicle Thing Properties if _Statistics_ is present in _Services S #### Channel Group _Lifetime Statistics_ -Check in your Vehicle Thing Properties if _Statistics_ is present in _Services Supported_ +Check in your Vehicle Thing Properties if *Statistics* is present in *Services Supported* | Channel Label | Channel Group ID | Channel ID | Type | Description | |------------------------------------|------------------|--------------------------|---------------|---------------------------------------------------| @@ -182,11 +215,11 @@ Check in your Vehicle Thing Properties if _Statistics_ is present in _Services S #### Channel Group _Remote Services_ -Check in your Vehicle Thing Properties _Services Activated_ which Remote Services are available +Check in your Vehicle Thing Properties *Services Activated* which Remote Services are available Only one Remote Service can be executed each Time. Parallel execution isn't supported. -The _Service Execution State_ Channel is reporting the state. -State _Executed_ is the final State when Execution is finished. +The *Service Execution State* Channel is reporting the state. +State *Executed* is the final State when Execution is finished. | Channel Label | Channel Group ID | Channel ID | Type | |-------------------------|------------------|---------------------|---------| @@ -200,7 +233,7 @@ State _Executed_ is the final State when Execution is finished. #### Channel Group _Destinations_ -Check in your Vehicle Thing Properties if _LastDestinations_ is present in _Services Supported_ +Check in your Vehicle Thing Properties if *LastDestinations* is present in *Services Supported* | Channel Label | Channel Group ID | Channel ID | Type | |--------------------------------------|------------------|---------------------|---------| @@ -234,24 +267,58 @@ Please check [TroubleShooting Section](#TroubleShooting) for further advice ## TroubleShooting -As stated at the beginning: BMW has a high bandwidth of Vehicles supported by BMWs ConnectedDrive. +As stated at the beginning: BMW has a high range of Vehicles supported by BMWs ConnectedDrive. In case of any issues you face with this Binding please help to resolve it! -Before raising an issue _Fingerprint_ data is needed in order to provide a proper analysis. -Two Fingerprints are available +Please perform the following Steps: + +* Can you login *[Here](https://www.bmw-connecteddrive.com/country-region-select/country-region-selection.html)* with your Credentials? _Please note this isn't the BMW Customer Portal - it's the ConnectedDrive Portal_ +* Is your Vehicle listed in your Account? _There's a one-to-one dependency from User to Vehicle_ + +If the access to the Portal and listing of the Vehicle is checked some debug data is needed in order to identify the issue. +The [Example Sitemap](#Sitemap) contains the necessary items to generate Debug Data. + +### My Vehicle isn't found automatically! -* Discovery - Your Vehicle isn't found automatically -* Vehicle - You have issue with the delivered Vehicle values +The Vehicle isn't recognized or a predefined Vehicle doesn't show the right properties? +For this the *Discovery Fingerprint* is needed. +Short press on the Switch will force some logging entries which can be [normally found in your logs here](http://openhab:9001/) -I've done my best to eliminate any private data from these Fingerprints. -Following data is replaced with ANONYMOUS data +### My VEhicle shows wrong data or data is missing! + +Now the *Vehicle Fingerprint* is needed. +Proceed like before, shortly press the Switch and the log contains the data. + +Personal Data is eliminated from thes log entries so it should be possible to share them in public. +Data like * Dealer Properties * Vehicle Identification Number (VIN) -* Location Latitude / Longitude is set to 0 +* Location Latitude / Longitude + +are anonymized. After you've generated the corresponding Fingerprint please [follow the instructions to raise an Issue](https://community.openhab.org/t/how-to-file-an-issue/68464) and attach the Fingerprint data! Your feedback is highly appreciated! +Here an example of Debug Fingerprint Data from a BEV_REX Vehicle + +``` +2020-09-07 17:27:21.101 [WARN ] [rive.internal.handler.VehicleHandler] - ###### BMW ConnectedDrive Binding - Vehicle Troubleshoot Fingerprint Data - BEGIN ###### +2020-09-07 17:27:21.105 [WARN ] [rive.internal.handler.VehicleHandler] - ### Discovery Result ### +2020-09-07 17:27:21.116 [WARN ] [rive.internal.handler.VehicleHandler] - {"vehicles":[{"vin":"ANONYMOUS","model":"i3 94 (+ REX)","driveTrain":"BEV_REX","brand":"BMW_I","yearOfConstruction":2017,"bodytype":"I01","color":"CAPPARISWEISS MIT AKZENT BMW I BLAU","statisticsCommunityEnabled":false,"statisticsAvailable":true,"hasAlarmSystem":true,"dealer":{"name":"ANONYMOUS","street":"ANONYMOUS","postalCode":"ANONYMOUS","city":"ANONYMOUS","country":"ANONYMOUS","phone":"ANONYMOUS"},"breakdownNumber":"ANONYMOUS","supportedChargingModes":["AC_LOW","DC"],"chargingControl":"WEEKLY_PLANNER","vehicleFinder":"ACTIVATED","hornBlow":"ACTIVATED","lightFlash":"ACTIVATED","doorLock":"ACTIVATED","doorUnlock":"ACTIVATED","climateNow":"ACTIVATED","sendPoi":"ACTIVATED","remote360":"NOT_SUPPORTED","climateControl":"NOT_SUPPORTED","chargeNow":"NOT_SUPPORTED","lastDestinations":"SUPPORTED","carCloud":"NOT_SUPPORTED","remoteSoftwareUpgrade":"NOT_SUPPORTED","climateNowRES":"NOT_SUPPORTED","climateControlRES":"NOT_SUPPORTED","smartSolution":"NOT_SUPPORTED","ipa":"NOT_SUPPORTED"}]} +2020-09-07 17:27:21.121 [WARN ] [rive.internal.handler.VehicleHandler] - ### Vehicle Status ### +2020-09-07 17:27:21.125 [WARN ] [rive.internal.handler.VehicleHandler] - {"vehicleStatus":{"mileage":17708,"remainingFuel":4.0,"remainingRangeElectric":146.0,"remainingRangeElectricMls":90.0,"remainingRangeFuel":65.0,"remainingRangeFuelMls":40.0,"maxRangeElectric":203.0,"maxRangeElectricMls":126.0,"maxFuel":8.5,"chargingLevelHv":74.0,"vin":"ANONYMOUS","updateReason":"VEHICLE_SECURED","updateTime":"2020-09-07T12:47:08+0000","doorDriverFront":"CLOSED","doorDriverRear":"CLOSED","doorPassengerFront":"CLOSED","doorPassengerRear":"CLOSED","windowDriverFront":"CLOSED","windowDriverRear":"CLOSED","windowPassengerFront":"CLOSED","windowPassengerRear":"CLOSED","sunroof":"CLOSED","trunk":"CLOSED","rearWindow":"INVALID","hood":"OPEN","doorLockState":"SECURED","parkingLight":"OFF","positionLight":"ON","connectionStatus":"DISCONNECTED","chargingStatus":"INVALID","lastChargingEndReason":"END_REQUESTED_BY_DRIVER","lastChargingEndResult":"SUCCESS","position":{"lat":-1.0,"lon":-1.0,"heading":-1,"status":"OK"},"internalDataTimeUTC":"2020-09-07T12:47:08","singleImmediateCharging":false,"chargingConnectionType":"CONDUCTIVE","chargingInductivePositioning":"NOT_POSITIONED","vehicleCountry":"DE","DCS_CCH_Activation":"NA","DCS_CCH_Ongoing":false,"checkControlMessages":[],"cbsData":[{"cbsType":"BRAKE_FLUID","cbsState":"OK","cbsDueDate":"2021-11","cbsDescription":"Next change due at the latest by the stated date.","cbsRemainingMileage":0},{"cbsType":"VEHICLE_CHECK","cbsState":"OK","cbsDueDate":"2021-11","cbsDescription":"Next visual inspection due when the stated distance has been covered or by the stated date.","cbsRemainingMileage":0},{"cbsType":"OIL","cbsState":"OK","cbsDueDate":"2021-11","cbsDescription":"Next change due when the stated distance has been covered or by the specified date.","cbsRemainingMileage":0},{"cbsType":"VEHICLE_TUV","cbsState":"OK","cbsDueDate":"2021-11","cbsDescription":"Next statutory vehicle inspection due by the stated date.","cbsRemainingMileage":0}]}} +2020-09-07 17:27:21.130 [WARN ] [rive.internal.handler.VehicleHandler] - ### Last Trip ### +2020-09-07 17:27:21.133 [WARN ] [rive.internal.handler.VehicleHandler] - {"lastTrip":{"efficiencyValue":0.8,"totalDistance":14,"electricDistance":14,"avgElectricConsumption":13.7,"avgRecuperation":3,"drivingModeValue":1,"accelerationValue":0.27,"anticipationValue":0.87,"totalConsumptionValue":0.98,"auxiliaryConsumptionValue":0.89,"avgCombinedConsumption":0,"electricDistanceRatio":100,"savedFuel":0,"date":"2020-09-07T14:35:00+0000","duration":13}} +2020-09-07 17:27:21.135 [WARN ] [rive.internal.handler.VehicleHandler] - ### All Trips ### +2020-09-07 17:27:21.138 [WARN ] [rive.internal.handler.VehicleHandler] - {"allTrips":{"avgElectricConsumption":{"communityLow":11,"communityAverage":16.28,"communityHigh":22,"userAverage":16.46},"avgRecuperation":{"communityLow":0.47,"communityAverage":3.37,"communityHigh":11.51,"userAverage":4.53},"chargecycleRange":{"communityAverage":194.57,"communityHigh":270,"userAverage":57.28,"userHigh":185.48,"userCurrentChargeCycle":33},"totalElectricDistance":{"communityLow":58,"communityAverage":41269.29,"communityHigh":193882,"userTotal":17060.4},"avgCombinedConsumption":{"communityLow":0,"communityAverage":0.92,"communityHigh":4.44,"userAverage":0.64},"savedCO2":473.033,"savedCO2greenEnergy":2782.551,"totalSavedFuel":0,"resetDate":"2020-09-07T12:00:04+0000","batterySizeMax":33200}} +2020-09-07 17:27:21.140 [WARN ] [rive.internal.handler.VehicleHandler] - ### Charge Profile ### +2020-09-07 17:27:21.142 [WARN ] [rive.internal.handler.VehicleHandler] - {"weeklyPlanner":{"climatizationEnabled":false,"chargingMode":"DELAYED_CHARGING","chargingPreferences":"CHARGING_WINDOW","timer1":{"departureTime":"05:00","timerEnabled":true,"weekdays":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY"]},"timer2":{"departureTime":"12:00","timerEnabled":false,"weekdays":["SATURDAY"]},"timer3":{"departureTime":"00:00","timerEnabled":false,"weekdays":[]},"overrideTimer":{"departureTime":"05:00","timerEnabled":false,"weekdays":["TUESDAY"]},"preferredChargingWindow":{"startTime":"11:00","endTime":"17:00"}}} +2020-09-07 17:27:21.144 [WARN ] [rive.internal.handler.VehicleHandler] - ### Charge Profile ### +2020-09-07 17:27:21.151 [WARN ] [rive.internal.handler.VehicleHandler] - {"destinations":[{"lat":0.0,"lon":0.0,"country":"ANONYMOUS","city":"ANONYMOUS","street":"ANONYMOUS","streetNumber":"ANONYMOUS","type":"DESTINATION","createdAt":"2020-08-16T12:52:58+0000"},{"lat":0.0,"lon":0.0,"country":"ANONYMOUS","city":"ANONYMOUS","street":"ANONYMOUS","streetNumber":"ANONYMOUS","type":"DESTINATION","createdAt":"2020-08-12T17:03:35+0000"},{"lat":0.0,"lon":0.0,"country":"ANONYMOUS","city":"ANONYMOUS","street":"ANONYMOUS","streetNumber":"ANONYMOUS","type":"DESTINATION","createdAt":"2020-08-03T08:15:20+0000"},{"lat":0.0,"lon":0.0,"country":"ANONYMOUS","city":"ANONYMOUS","street":"ANONYMOUS","streetNumber":"ANONYMOUS","type":"DESTINATION","createdAt":"2020-07-31T13:09:15+0000"},{"lat":0.0,"lon":0.0,"country":"ANONYMOUS","city":"ANONYMOUS","street":"ANONYMOUS","streetNumber":"ANONYMOUS","type":"DESTINATION","createdAt":"2020-07-25T11:20:18+0000"},{"lat":0.0,"lon":0.0,"country":"ANONYMOUS","city":"ANONYMOUS","street":"ANONYMOUS","streetNumber":"ANONYMOUS","type":"DESTINATION","createdAt":"2020-07-18T11:22:37+0000"},{"lat":0.0,"lon":0.0,"country":"ANONYMOUS","city":"ANONYMOUS","street":"ANONYMOUS","streetNumber":"ANONYMOUS","type":"DESTINATION","createdAt":"2020-02-08T11:06:52+0000"},{"lat":0.0,"lon":0.0,"country":"ANONYMOUS","city":"ANONYMOUS","street":"ANONYMOUS","streetNumber":"ANONYMOUS","type":"DESTINATION","createdAt":"2020-02-02T14:07:54+0000"},{"lat":0.0,"lon":0.0,"country":"ANONYMOUS","city":"ANONYMOUS","street":"ANONYMOUS","streetNumber":"ANONYMOUS","type":"DESTINATION","createdAt":"2020-02-02T13:24:36+0000"}]} +2020-09-07 17:27:21.158 [WARN ] [rive.internal.handler.VehicleHandler] - ###### BMW ConnectedDrive Binding - Vehicle Troubleshoot Fingerprint Data - END ###### +``` + ### Discovery If your Vehicle isn't discovered correctly or you cannot find the correct Properties perform the following steps @@ -259,7 +326,7 @@ If your Vehicle isn't discovered correctly or you cannot find the correct Proper * Check if your Vehicle is attached correctly in ConnectedDrive. Only if it's attached to your ConnectedDrive Account it's possible to detect it. * In the below example Sitemap the Switch _Log Discovery Fingerprint_ can be executed. -Copy the the log which can be found in general at [http://openhab:9001/](http://openhab:9001/) and raise an issue as described before. +Copy the the log which can be found in general at [http://openhab:9001/]() and raise an issue as described before. ### Vehicle Data @@ -286,7 +353,7 @@ and you're ready to go! ``` Bridge bmwconnecteddrive:account:user "BMW ConnectedDrive Account" [userName="YOUR_USERNAME",password="YOUR_PASSWORD",region="ROW"] { - Thing BEV_REX i3 "BMW i3 94h REX" [ vin="VEHICLE_VIN",units="AUTODETECT",imageSize=2048,imageViewport="FRONT",refreshInterval=15] + Thing BEV_REX i3 "BMW i3 94h REX" [ vin="VEHICLE_VIN",units="AUTODETECT",imageSize=600,imageViewport="FRONT",refreshInterval=5] } ``` @@ -453,6 +520,25 @@ sitemap BMW label="BMW" { You're now able to receive your Vehicle Data in openHAB. Continue the work and combine this data with other Powerful openHAB Bindings and Widgets. +### Notification + +Beginning with a small rule which is quite handy if you aren't the _permanent Driver_ of the Car but you're somehow responsible for the Vehicle of your Kids / Wife / Parents. +As soon as a check control message is raised you'll be notified e.g. via Android App and you can work on a solution. +Here the short rule, just insert your Mail Adress which you are using for openHAB Cloud Connector + +``` +// App Notification if Check Control Message is active +rule "CheckControl" + when + System started or + Item i3CheckControl changed + then + if(i3CheckControl.state.toString != "Ok") { + sendNotification("YOUR_OPENHAB_CLOUD_EMAIL","BMW i3 Check Control: "+i3CheckControl.state) + } +end +``` + ### OpenstreetMap Widget ### OpenWeatherMap Binding and Widget diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/doc/panel.png b/bundles/org.openhab.binding.bmwconnecteddrive/doc/panel.png new file mode 100644 index 0000000000000000000000000000000000000000..efc3a61bc6513a2d11bbb24eb9dedb0e9545c42f GIT binary patch literal 1317196 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]#34>eEIEK$3DdkE2*g0KKkPASM&PLyy3 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π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

=LMV@|^q0UtPL!h(<)$9krqT+TDsJd5&M2v$G^Q z!|mwQ-Jermg+QBe^^6~1NE&Qvn^RNg7;uV~RYEg}!-*y9E83zpM3KYv`iiQ-%AIYl ztRR_`MasV&XF;-^t+kP!hK)OJLtF^|Ak2OcKvdlIHF7$V3Z;Sc=ooBDX8t2FAh=nq zwZbksp+Y6FG>D$N5+x=v@ z=T)}8H-V3p4+bf6fsyMa-4HJ|P(6^ENFb;pfN?41H;~V$%cwd&Yqk^Tlhc7^dp5Q$ zM`ftkL;EF5w=1_5E4}E^WfgQkL5PAHA(Yv|X}bB3$?EI|r06!5*3aWQI4gnDOP5v8 zBR!rXhk*TrmlA?H0)j|(H`hGu2E;IQQaHTFVCmQva61G)Ba&6a!d)zI$ZfWOs;JeC zZ932;ViU47{9oE(^T$3{(@-%Ks*S8azGGwW2d?WJ$HqU8$0k&})rNCIH0P$tJRRp{ zt3A;#n_sa=k_WhaQT{N0u*>tY4PxcS^|pHZr7d1%A`PG^FOyxnid-{($3^wm}I0;oM zBzA>%?YnKaDNr3dr-8x2-Jk^u0Va0O_q&{rjrFZZHC^>BkoZ;j^pJ{Z9NYUPgZCpE z;m66;<4Y+2ZFA1k!0_J9sI$5J$1G?&MQSpO$M3P9@MT@Aab%=YtLVPUtut_+r`-p0 zyT~Ug?ioxS!A4kc$i4sS$vPA0fAQeqM%w%@+RRo4@W27rn z7c!DoVM~3|bvt|P2Nqmmqn)V|!`Ta=BA{KkEuv^3nxxR2+hSzkR$-Z zGipt~33nA!FvXP^SYj;F7OOdj2S*$q#4ifcpibLc_VLItnxat!;&)!8nl`u%DN8X4 zjuPfdYT`2++rrd;+u<}XrBar#;4QkD)SSy48dPO3iVR!1^)xF^=8p%@1{^1hCnc-Q zXORRf!Zq!tJ{tp-5HO7-&K2; z`?fa!ODn^anNu0dW`cmP;aRi5W2?Z++U`G(;`V!MbV+RJ^8?>n(oGu`c^?oYwvhDZU82WK74g6Rd=J#?f*K^Ge|NhZjBDQr~ zJKg!fqVGMOa)oQ(4BrHL2NAxM8<%X|ErR%+?Czz*?{oMa4j_>U0+qU7^5ne_HU@9# zofWO3;T|-DGlbn2WUOynX870A1lF=*B@w`854xgJk4+JHM+oPBqMbqJiNyS<+lOx6 z+d=)8M#3(*2_GFxcFd3GoDb|6^+CeKfBkum&clyqi#^uh-?45fx#Xc*MUYSSyIr2| zy<#`+UWP%NncqFBB<03mD`v8f))RDm5?2Y#o5Z-!3pN4RT^z&Cm}!&7lU6bo6Qep} zsCCpi1wU(u{n6ubgy>L*9U0%0lH-^?S|sb!vy~jx3ZiT1dnbl7iY5<>%TH^CL>KDH z@YK_=8@~>7>Ao*M{@yyW-`cCoDrKuBYjGhxd5PylY5qDG8F(9nDK+j*|6yTnoj75r zO6wA>I%xZAveA@SoyexcYi@9#H$`aK*5>xNcncV1au$(>VTVKln;;Cq*Iny8I3;6= zrnqyzWD;W%f`GmrT(*PGtgIO~N26sYD3g?`DKS_VWQSEpC!H3eYRR=&th>r2J#OWy zOk;Om1kI!?cowdbCOeZn^Igc6M@!Z5T&^coPrM1YZ5{qasAf1BJ|GA|Fo;ZmpLp~X zYrJlm*_-w2km@IavYwnb6aaMi-)o|n$Rv>`(ry0lw4l5TXr~=YNL8E$?k$VHmo;n@ zj`&!2cB{sY(!_@ykGt{`z+JteZ*Qz=CYtin@{|@Zr!iJnBtM)Xhw+NvDktLMe6njo zGzJdYPebGpJui1l+Gn1R12BB2XW?KLI)7FLS=LH9^ZK)vZws;IQ)%cUlp2W!Uyh(} z#lP`gk*!~8@K|!Y5-h@>zUzeflW_(&Vl4s9H*PvGe_}Ww)uOmx;!h8!XxByT|C5NI zv?X6LoUz_ILbJq?6S5>c_+BLz_o)S<`wdM#1rw=$_BZF_SQMFQyDjsY?~A#h3dWEIH$l{T64$IQ@D@8{gf8q zx%*YXvZ*suWp@AcEgRVVK@>aC%pmY*a_ezz`7P3O7oGdzmE&VBR;|2Y$2tbjV~wtP z?tSZiE~V?8dBN*=Zx7f3?9{-0EqUvFXi~@LmQfb;-MMTBmP7Yue*DpcnQ`>J1b!U< zH`is?^883K1A` z%(@6JMeFOQl_&h`UJyPU6Eetd0aPqMG?yk&+o<9JbkEeYv z=G|-`)l5^$o7w%YY`e#60GnOMp!Ca{vh`ZwDP(d&K=-|`$vsHRFBhEA;7KUzBMFi1 z7J(nQQ(Ju%KUh0u-L@e5v5z>vhq$9B^jmL0d{HkvH0$l4J7-ddM2+{-EtkA`0YEIZ zG)1!WSI^1LqyAJ7_ zwRpY2n|?!9ZQK#P0UB4Hi^xFfqf7d=L?1O6D)##}K(|0%DmVp5m0D7O`;p({9D-uc zUXPY^(Q2c(eA|>xK4UT@vTQ3U8)bcwxW>P#?c1WvvmwMC)?ax$YX?AYcS>IWtwL6$ zdj;MoIsVR(kepazAb(hhw=`GixSgx7u~6lmL!(S*XvKBMaZOs4`2I05kU!b2xgO{cMRxeDk_5AE5RjgkZP=Eg5j2n%dh5HsQT!HfG)5pD} zh@i?yYb5D<7U&MX`y-7(Ku4ReUhiZ6YfQ)89WaJ1RbHO#{cMXg^al%&0*;W=`#xKT ziX2zq?!Eh|yr3i|(dwqk-HrCG{^R_Em$%!=%=XxRO6Tc3;n;}pxyo6Y(EVhEuV_yF zcCee<@yHLKKf8Hj`|Tcc3zP)vN*|MNdIrJY`CYeGzdnT5Q!F=K($Kvv>E`ftbubaT z$upH>278JrOSL7;M=|ByD73?UL-WFx%}7o~wew1>mY2kL3P*hlh1X)0k>Fd@@V#4q zA4Y2r1kI&v9eWH32)qyu{CrjADt(>0>e%HFxaJY(8F6(|)9`9h_Sj*D^490`+eRA8 z6FZf$Cm(V-a(9fuG+W&wtH(FasMoO$0ZcFhG^$b0*-Fx;OqxARO1!T;&#ql}EehC& z?26FY%i)4JHE6M%Q0>LiWDwww%%>8SzGO6tq$Y4Fhi1n}KX65picpIA=4EpwQQNRs zN@MRfPt{oukJ_^o^tnnUY;VDyOup-LEV$I>x5#ps1S*`g_vLnaQh5>Yu`dM~b$Jcq zq)6rQ)K46*4Jm2s>!IF}nee5^@NFCI>T#rCXCB{381n;~;Y&GUp2F-nlGnS~K~1Ph2z z)PoIch1HPP=y?}+Pw{)4Gu~}}w02>M;4SPx@kznO=6J3o?&6b^fK6RKC^u-)aj`E_ z+bN`7%l2%6HvdpFIjIe?dJXb2?#_e01sJ!T68j|auY0;MLURXfhKx@V)@ zU3W-@nRNLjtUYeA;c)N+x1_UovtvBM1MqP&X9F9F5DW(6y$b_Fk8WyS6rwT|kc~-! zf_fT1t38o}m2n`k!D9hw#1x`ImR~sazEUJ!<@|XIoKZH~3+n!~?Y=MD!bKziamDa) zkFJ#CyHn1W{<6YGz_P!(RXquIf!L9dIWAzse;J`#kc<`X^ioCquQK%?F_;|8<9ePL z=bsm(TnSp#W9eL$m$@LdSmwKhp?f%Z1ViQRTHk^{F1faWIXNHw-H&@8_wOkmvF%;J zlq;V>`)r?Q?R^F>uLtt0EstKW=i`oP&m+(md9N#htru|n`cXhmW&9Agug#iyZ{2ZhHaiMww zNFb5-yAlAS?KzEh9IF{7)_u^ySo>3kLcIhK@TFuMT+#c-nppw$O(oj|5VB1zOMye) zH_?A!8jWLxtAdBQl({$H46x%3a41w9C+&AYO4#<{@6~)}jjJuau6^!*-tiH;m5~~q zmYiSKx0wT)py0o`@$7teBkVk{iuE0V> zGd44sGC}~o61@R+=woJ|D&ggV*i)8f@HEB}bHVe4C#n6JLWjkva~W$N0MAZ6=9e|; z#T-;K=M-H`O=L;hASwQRDH|z^hqCCnjuD0SPXb6>I5RrzJdI7-Q=}JdQbxx?;!0+e zXF5YO>~wXaXtK+N8KEWv8f@t?4X06;$U}gTRpZfvbW?EEdYs_O1aVJ9Afe3%+aPF4mNT_1lHH_Xvl zxqhz0o^fI^x6-tzDJ6vtLX=%hNRMNgO-zca`7^j@wbUaefwgPHjK1&*8*0r=eFh3^ zfPNh-q)tH<%&|o3+Z#z0yeO@e!++Zm%r((k`2Ga8-46@OG2+piKF_VS-%WhC&(46p zz^@nEoaepJDZQ}BA-|9L?k)~pS~w%w=F4okj~8)%)dpUy17(^Fd(cFRT$K$toEj7I zy71?fDwBK^dGBI=-1dvoxSyAFKh?&Mu4ZdIyo6FmUcKM?=%98NaTpxo*(DhpG33FJZY)um9nv=Q|5z|znEKnoM`A+`V`wL) z{PCJCFTjL3urJhezm4{(*Z%#15VUZyn!3O}TupeX5(axs@b0xOcj*t<2;>Pah&~gk zPBRG}l>;42?Zr>dt-jovc%4r?-kw$#IX@iM^NeHS;F4BOR#z5vH{gAYjcs(EkM^$@ zIcGI$=4H$W1<-%L=W{i9_33N+xpPK3XB(N~XvmXy!??P`x@}OGkaQseYql?1dgD+6 z=e8F}*Fqjis+09ixV!#vM*Dr+9vVM`*r4c>Jd6I?7F{&ZP0H3K&FSJ&x+<^`rAQBN zR-0Y(A`j!*_gkjgN-N(=Gj8Cg&%v{5DPlq`U?yp*duixGPo#J8*bnLfK^;fp_%Yd% z$l5)n{EZbzkK^b2y0~g5X9c>scjl3g$QDL4hI_N`!3c$RmV<4Ih5*&k)%Xj#-YpaW z{*a~}&mvu8N2O}I8b+V3d6(hhcM-D4-)0L*(DPUM#xhW@9`JMlUdhAUpF@9B`G<7E zaBaMy*u1}-oy`%qXx7%_d3WV(c0XK(I{( zo(oZ!8qaaDn?Sy*;w27dl|E;V(PU*hQ2chCd0;1Ix9)osnRZZ~9yKc%M4Z6r_}{pj z+g~760p@op4UW@2DfKxT%In5iueaF(5DX4nM~F2l;d^B2dK=8elS&3l+ppPZIBxY!L~e%EdhHV zJ#QL?{Bsl-`2MkBTEs!^9j_6{?~}dnz6@mXYq>lOuYhe|6+cNVv3*tGrubb)t%Cbw z_XjfTX~t|MHGS+I{PvT!x^5|j=rzZ0iUkm2H5d|upV`Bh0|dc~k38E>9hcwtvAg-1 zw}(OqqmnGEF#NYX^uHn*@$+DeyB)6+!fs&ap-$7L4Zi0|p1j}X{IDDWm(QgM3DZ3C zTlfvU{>$yLd?vT&(S5i8XkOs?U|4`YeDC1k;H$t>3Nk_G)xc@Ns*aN4;2r5P|J$?t zVk_d{p;mOIz-zyoqc?Dl^wA&}Ra=)lYGFp4`pdL9dMZb=X|rK)MYDOD=l~|0xYaqY zu|!BE%$IIzR}QieHqF(~yJQ(Dw3;=Vqt@wy%dliyM(UzXCC-SZqKxMu{T8m%HJrDI zb*Iw|8NjT@lDW_Gr(Zo$O6@40SFqBqq2Y_S6S9)+SYl|>*h|uN$9Eys;UQMxXRs!t zTRy!J!P>1nkR~@bYpu-@KKzRK`WCxnm!3MAUqt7t8zX|kC7m|^#3f7V8VsHZ@T%3A z3x6v$Rb~!KB#xn(WZ8J(e*%3NU-9i6a8~gcDv?l06@DYvP7d^bpGwA)SQ$WAFp(GYV0>v(_hgo2{(Ptjzf%P9C0CFHi2{(=^TB=;SwE z)mF7S^i%|rklbetPki@k>YZiks+)Y(pzZ39##rW}?|*C$Z(LnN>i7^MqPj`Z3Gl*? zS6iw?e?hNZn8Bk%hiHjQm$H)#OO*<@dK zUbBjkn4|8hLSHn&0n}f~YEq1PXOIk=;|zX%PKwPi^X~d4X9k%`kSx2wcAp49s9Vgf z*r_TlqNNEhgd17>{R@p-(4VPFEgFYeXjDR5=2jIgSYbwpr1;!`vT#Y_q$)}WF&`&- zB8Z2CY7uGNN@U5njzHDrgyIVlX+)_0eYME@w`;9DP96yuQf z-p5C72HM{R+3`Ev7k7RI4vMiOzjU{n9{+V_H)V4ZRayqDY$us^-A(xWwVuaMmgs7S zKxBOJ86Gn83AjmXC*;Q=l!tTDVgX;q@AqMBSsve%!hH;D9$XGetZSuGpB}>m-mJ4?8VD)9I#2&$l*~ z;oixkn&{qPoRTq9h=?LBoTc$}YE6fSXMOm1=hc61O6$v%yuh^2<9Uw9!%u@Th+3RG z-Dvm^GS@H$-Sj8`}H9}Uj*E!O-k=KR0NGA?N75YU}%@Ai3q zc+1BkUE$r~ry>Zj>}_ScUg10daPIKa{+aWZ3EMh&nerIz+b;Zqd>4^tRMkzBV1 zQ@qNb?bty{&>?zH-3cCcYjHS;PnrhNYZt5T`sJ*e^WVQEnUX-q!4O+vRfi0cxb~{Cjx6JhR8c=ZEh$C=4v3234}-c37$jK6|4x_En%myQb%gt-AMy z6Ghvj8JZp(ThfhICU4k`MRWf_QZCh2lGR3!qP4{KZO|MCuU}*H#RUGqi!+^qlZi_% zmv)&vyH4#2J94PVj-P-yXui(C*mA`JkyA20Cl~c9{>5x!@IxvRb$~>8rfFwIgj4xi zzT?+Nk1$B1!HnMDPseHLuzJ!I-W&qu4z7%q!Vlv)IoDKt8WS-fw1cs5QTPq|qLpPe zM&{dJ_V_wNaVhY)_aXE z*)n{dt!g#X+(nEAF7tPKA+`ap;*ovWo^SwNk2gYl>GIyU$Y`(;p#d{J8Y;es`<=Hb z{7+t;J~S>2VG8I^ivXe7_V<(64`-sE<*$0`%SnW?q~GGg0XY1uDFkJKi~cI{$GLzy33l?c0dY(ZD6PU11!QZ3%cRy zV5{%0-FJG)7KzitaCMqe*!0}rlX`gV4J1v{89qh(?RJ=M%YbjDWzWtQm{l{2(|HuG z0IDfEtPm!4CdY&8c-!^tH9v>x-{t0|swu%%UZC*JcDKvz_T!}tJKxt?aT#Ib)v@pd z@f`4sJ!s0d6LK@jikR#Bxf@VrFyImBWihOQ`T}!q(vW8^TSx5sC?dG1uwytlyk*239e7&OK`Dt~dPhZFB+}$cgb4Cx9l4G9)5^TEu|0;;_-7ONUldW0HPMOYh+hl z#~_#tGlHNl)?E9T`-`Q*+$sxC$?iS-{!$=Ha5`?r;Ql}#lx4Hbpjww&mGiFpb}1VK zsSMkXG_EDXWXwD#9%Lfo&lG~`uZ8fAc>e7k#Z!)(N|3bnQ1!~7Ln-n1Z?aoV#T`Zh zQrP}{M>f)pOSX_Rlg?%E2DOS$E4w=>}=hOadkTZ*E4NxHy5)s&>G0j!}BBl zXIr(x>1a}a0LI?KwB3q3FMswNZEF8yAo!256;e>3?Bj8?8{?k=#0N|=xe*B5bp{Tv z7azw&$#2dtIc`q9Njit;_k0$NK0CT}e_hK00m;RE$}(#%y5F}#`cGlIsSzbHIK2av z@^YphoPr7LZX_(Bge4CyQ(sYh3NeUk;P%Qtnn!6zFE``FM#30_v5A&BWG@hTY_$ zo8>)Sr=HvmM#;{#jKO>M?g6)|X9Ma%h{_O6~ zHXQbN?5RJaO&q*?XXf{aOBaO29`B2M+a5_iJ^YZa7r3{oTddGBdbII$x1={qP158? zWgr!>52`3<9~>;UQY=*ClwXss-PG{Fa#Cw?D_gjjSVSdHhNovAHsX~} z`Cq>n31(#;CKT9&-NKiYZ8;KiQVbp+K2hTSu9~wO81JVV;u#hF(ZXmVcf%y7UqkoV zm+O3_?YCgBS)eVe70l;-BS(ZG_+``t+a^Xl_uvG~Z{Y8STZnoXP`(3EoUoz+98`gm zunntwdI(+BSqO$TqIjY7bl$?Er!M+Ue@rH#3wTN7M6DhhR}+7RQVLBgmy*%4m5NoG z{B9u*J0@JsQBTHvkZIjeTefx;s-U4c?Bm-XID+L~Ylj^sszT81u>$pub~PD%rw~r& zGf$N##Y4Rc8nOP02ajfUl5Z@eP$@Ab90EVCJ;VvFfy3^Aec;CsDDbXmVR+t~R^X#J zW$WutE>9mP``QW_J2nf_IAHp9MqW@aJ@MaGXnmSKCZq|Fu(9X^`pd1?*sNV9V zv4tCFnBw)j#@+UwCDFu3%JAg7^L|!U_jBLo*LnlT9c1q#zuA0@_HxA?{ipTrqUf2& zJgT+wl>8pQJFN?&S?OU=-t>jOa}<48#})U@B493GJ@pv*?d1#&Yw9@ZCcr=$^Zq4x zUEedf?-16l=RnOJz#C|wEbz5k{T%#2bJX?(?K|A+0-@|i`^T&Ws|~Wc@zxzx64J*L zV$#;^ldpZ?-^9X#dk?_pc6QkHYO9nopNKJ?N<((lN=hp$#iq$D35!&p?anHTEkmiZ zhYktnhXMM33LZ(})vjSVlY-d@mRoTk5Oy_r1N($G=2WfA_ zsw$?wCrVCI`Ta0gKsXsM@mIvFo7#KjTpW-brulG zaDTgMSc<0-?3?G1p2Zbt7&5q}_3rMmXFv?i1u4|ko(wpKCrC!TA9@A!y6c5myL214 zswH-M7!K#RPz-1Poxl?&Lbj5{ql{`+J@S06Q$K?B4o7H$4Ps-8HlkG~k5i({A761E z!>kw;6wMXvt$7%$kUxT;CR}ju9zv8XqNiUUr9+4?jhzT_^yl0cvAB555`Pp?CY@56 zD=Rsd{-|@DPu`ue*k5hg!ZI7o))`bS`!P8r(TS1RkXzVZZe*Vwod4GjIkELphpWe0 zvH*2CtH#EYv$lEU9)m`45h+5;-rq6FnyHdN-mHJK*1aj66-FP5JZ6S1$PsmI35`3y zS<%EPj+c3P7&Bx*N+NKV=vg?7uJX}|T4wnx{_0lE&jBcRBFn}l4_RQJd`RkYZMWPbl z0?8`1+;JdJ~vL$GP z4irNu69r99URVwq9=hb6^)+!CEAQ)N>wXznLQ{4o)_p9~QNSb#IZ@Z-gxs}gVnPd* zJ{2BZ$WuDg@TjO{b}VF_8=XWP#fX6DzZ`vzj~0LQe!uH(|I(>TCoKFm$M5|sL&tRh znd%byES4c9bQYVa3jf>c$7><*e#&w?JNWui#$gz5uX|d?BPaXbCg+-$kNtJx9Md zo8@9-b`EQ<{s0Xmslb@z)4FnVyRuo~O7)D|;(azuVOnX)1op$3^VymYcGw&o1&Ku5 z6l-j=5@sAK-$Z~!XPQosQcykyUACxOF4p1JaH(28!=HAr4wk`3-eR#z*H{)3$NU*Q`B4^Ms)Z-U)c2yEN}~p!id+80+DdLg z>W`Y*WQ3x56u0#v*SH}LnS$03^j^fnmvx&ZEjpHC6+rBZ%UbtYiTzODOBM5whNkU)$rv-i;3Yh(?@@ zxw^2NwWQ0?B-4gHCl|sjz8lINJrx?zk_0j?L9`P!{vd`Hb29wuR(h_}I%$iJAs;;IfEgvjZHM;9;epH7j9HlXPW1pxUq6)ifXhZ=geAeVo_r zH6Pu5pJgy1fiS2a9Rd2;C+Dgx_LcptdM@aGjK26|(^Vf8y0}gY4Sa8@dZs`~a5-&w zXvpGW+tcctJoiqi{bP3*{P_v=Ia6*xoymh;Tl3QhM(@6|pE~a-(@h5(%)4J2SJI8a zITB{Kvad_KfMd2F$W1M$$AN#oZM>*_sD-<;PMS@>UAKjIStpOo`OVF#)k4<9%$3Y19V@(9RI{;{NM#l~$*}hye8-WUtx&fWCm^`oY;(C=Dq-LD7zPr0UBoNQ z=#S7AcI2&|DmFDKB(aEEdUoK*vAip?Cz?T`>7bhkVpUQ)dsvqJm4R2A>br6fEuY%O z96&U*l(cFrEK0WFuCO>hu>wsd&scY7-WSU_1txk-fHR1 zjTfudU!xCkAjvC@Q#IHG0XJS%J#xKUwqBh!RrY~b-0SH6vh@SR5-e+AbkfB2*1eXLYhdVd6RSLPq?bxS3 zy)SOMc0p@imzL)ngxH&Ck{he8p2FJVpaUb51{8Vod3G_pzyX(3^Mp?uiH;i4*iLZ7 z?vO(gLy2YEK%D* zBNh3Y{2H4s7gW6&AE`kNG^SQxTRpAPIwIo%@30i69)WXTb=%K!Q@Lum$u#29#-S0V z;FtYq>47Y+{l}QPuOFgkyVg4&<+Zs0h^HBU?OvtK?^wrSILZ&yaCIs<-E^~CSrC|^ z3<=J5~emU##GrZl>L4rs7;pA55E= z$(j5BPKvlqLAg%6?Q>DLjvtsK+{90@z zu{W)sJHgAzK2#>PAyUGTQG-w+DblFGi%LPo)C>IkV_cXtX%~~&pbtl8es+#X)E}0g zC-ul%S*axsnO1GzSjM0NCq~xYXV+ij3zNPDmljSsMnb)iQ6{{+!>%SVJI&yb9`iX_Pt1h7tUAK4etHdOg_K3CB zG_@rdwOwUOxVeyoEKbd+NN~zkW3h}CCjh#8z2zM@d~49c2=4usCYMEpcz1MsgjuoY ztTNf|0R)&Aj(!gI6jrIwkxUCwT)?*>45!7z-hdMH5B7xAR|@z)M7>jRWnJ3^+8x_Q z$4++aj&0kvZQHidv2EMw*iO1*J7@R%{pXy!UAt;kt$8!Y8qdIk?x__emqYJ`5ON{; z?C$Q6l+1|6^KZi6#n#e7aF#73e{eUf9-xu^IjLXE-J$gD#AR)qR`RmHq{BK6r zp`&hrbMf~1K{MV;r-r1%*)1jMW{S-~rUB?h9-Y2`-A29Oo;y%sG|Fyzjj zjKY?vBmdDEJBYf0w+{(~Dc*wtm(k3j)@JFfeeC?+@V^rjh9Z{G%oe;xd_NG^E0VWd z*L3i-HL#xQFIhcolzJ#>Tpl=graZ-u8l{QiER|1>ECtCC8Z`4n84PGYoA)5ksdyF) zo=o(XKM!$EuhW{jJ4@usNfCqnlWcy{FrePBzxVL2D8Iw5RivjttUm(>QCRlo2%0}q4D&Poq{#}@!iB2Zv=d2ipyx7byNYzWvPX%A8O`MHy~D&#p2(m;liaH>%_)~d*E??+N*pDvc|@#!}-Z9SUQN>K>Ky#VD+ zCLp39U?}Qnx1`NJ-G&flKofFTzs5r>VO_muwGn?m*j>@n!5j zw3&vXPt!+HCUW#0L9W%ez<{{^TH|C7JtZb^;M21)pacIC^4d+ksvr0CIBRbJcu9_;^_eC_#GGww7)=72ZW5+I7@6S~ZT|%_7>o z{?%eXkBP>^&Uq(j-E?twt}&{)o~GmOeP2x-Ji8h74CQ+~vfJ@(yBIn=XKy`kJCPT& zb0$wXSZGOMSRx%c`Gc$jZ+L>70bd@dW-8PH<%AXQVJtLK`v#p<3!#M$b{1h1{VMFQ zu0>8b0;LD%J+c=D?2BBI|4xm=1^r!g4%;XUK4#7*+#n-Z!N{5w5F!Qz$dsszE#ndh zJK(w{iTj-5d7;eWAl%M`Xq}^fl7G^ zja4l}@fblr>BXXO`@}wEi7W(`^tvg3YB-o^sR{%dI6T(888R7$-!PSJH9E?R@6&+H5b2JsWvowDe+bL9L!G!_>Iw z{Zk}8e6TnN>>#2ixjGQW!W$d^$I&~PQR4gwlcA<8)(1#whe=EM3ETS9ro=A3BK{n*4%4?rd= z87$eY+PMXe&)TlY&ZN8o9&98^^9Jj}RtLpnjj zMCWF5oS6_H^1d+%o(TK=L`$&qW`JZ0XCm!eL8a(D-#xNh?uY!`li$K z9ywX74k%$q`X7DKX@zaD#Y|bbFx0XW?cAm8Us-sntOFN=%|*}ZaCiOMBTx-8Px~Am zRd{*;4%I#%%URpD!4oEHd_Egm`+deku&=mz-xGG8UMNvuZXx%sxxY^16rP9)cJy9H z*j1wgy$`PqvR_urpBg6p4iZf6AB~KR2;P@l3BQh9{T`09(p>Ca+UONK%|o1_H6dQA zbxzd6qK3Dn5bi72$mkX?{@mz#Y_+qFo(7JE@p>IDU3?CCeA@ZlB%(eOe12y-a~FU$ z+hv`(vuc#0m+;hr4a2*Fxk^X;YUnrXt8I{JlYJMgp?G>PoOox&?&+# z)shfijFHYjg%B7uchPFXd4~}THX83DH!iu&ZsX7iqVRAx#2i<&>)Na9O2AxF+(Kb( zoG`}*!U|)cdwX-L5z8ccaVQ6mbw<@PrT)*%9JTWW7$pXvnxJiu)3sG*0dG2Dth$@q zN!@JA%Uzs2(1FC93`HElnm5ptLa|P56c#nMTDYR+hE5&yyER?6j;nS-AU>ze{g+3c@+mpsw4)%}_AQb#+&K)e)gp{iXQ zrc#|p@2rX`%d{vaX(Xh`Sq2TL|2-p1Ko`@>%M0iN#&|%sNx4vc>c_l_nm6SUHBYJ^x!oKJk!DB@j!RAzQs2 z4pOxq@r!QLR{Y`$`y8gvX3%mUf#q`Ue+aJDIHts(vQN9Ngx$=@`IPr^Pw#weCToh9 zB-iLDd6F}&^Jca^ihYb$_y;VVO{Bh#tX4cY7){vO+cyz^{NX^&k)0%W&V^t?Wx!N> zD%2UM)59ymn*&Q9Yy*%bAZdu*t1cQv%68@u#xqU{p{WH6#bYAtf|3(3_NPZ^p=ei; zgh3ciLyX{WU`fE!5qgCJLePf{#%}}{+s3en!ui`YhQ;kqb%TQw661|+GL*0!<>6Bd zZWB0zPf49A*c71L#1dJFsI5jRN`L%Z?A~*KWB%0lE06|B6+ne6;1@X!k}C&_FRjWq zG*x)5CKYn%AUdX>+4|(&imVm8O#VMI;LEc0j@L6RB0+?MB} zq+ONGwjAec>#-zcpo9wT+f;Z;%gx9Wzuv3Anjt!LNGdS{wZ40+5$Zp;HW+VC9?|H% zeE4-gZN$CG+Gg3?;p49-y4pzI^I%_iFfDw9f87h^CLzK#Z?W6oZ}$x1dLr1KZu`kS z1$1&f?QFIC2|WdPc_Q*K*x&CJprS!-W8j`<=UrsyolVWO--Z+@wpX^q0E-)XQR#`& z;t-}}QWffB=;m#X9HMvE9#Sg2|6C(j&8%_H}M46~Pg_*pSMc9F7V;hHH9jG+NPea~*X}M*T zgC(d{Nk-sCpQD+@ABqBP?M!g0yJ-Y18V;LH;KmmA#znd+)eQy?9Xbw~+2?2~+!QOY zqD9th6PX$s0VY}}0$S4*SS}cqD=Fl@+x=b272#jY4go!PAY4nPjq3vsr^eCXr7{V0 zBB}V^<7#9}v!MOcnvIGKvh7vAUy1ToEwr6fMg-z?by1r)SW2{W*L$Wx2M>7e(rxV_ zVRLDGVS*r=9EbeK=Yr(tfvwVaYd!N-Hik;5#{qTwOZep1i&rLfiz?5-^IH3 z)v=WZO)W3PM+XFu@=>sY8LaF}k!G*6y!UY_{-#=A^gF#TcfR`&B`f=GSh5xG=UTvT zcfXIC&QEj0K;ihruhb}e0T@tIsRHq65J$2avDpe_^YI6al zw}~`|n~NGVvQcD zd@umFP{Yimu?#2Lz&^T5KECugxXIv_#^rB|^mM>l|1F^gb*i!S5em3B&vK-zpq3Th=tm3=Z1SH534p%o^$a>d25pAG)9`4NXNE|;A-v+Y%3b{EfQz&=BJ_;s$u9)gZ4*$Vga zgX^~g7i$_5emYOKS+V{|xc-nC9Z$r0H&$g-d}ToNh{KjY(P+Xa`iLN*rVun$+sM`} zC0ucYdZ-EXDRf5gOaBm(K8jVeO{OM}hmnkSMeH@ys52F<5Q#dY2xZVg2ii(gc%g_x z0+%&iDb6aSA$wJ%kl--MGC!oFU?>*j5XU1yC+12@vc;&FQ$bQd(`B&8Ljdy@s0e@% zt5fiXTE0YERZC|&-IpQ!p}G1CNr|nr-1&0rw4+yIj8HInGd(zH7~KZ z%MH1Uj)UKT)$Q$`w;5)y%gaqaxmkfZ5Buw9(W`R0gdWr+lF?tH8>V7!j_n1C!_y2x z+T~%>cr?*J#>lh<$4Qj;I>y$&0$p*gu7Bhi!7+QJf~A7`SNIq%9GkPWzU9nleg-j5>OsFR8Xj0X?rK-n z>SmM!1#Q5mBSuJ?RMk6i-W5*3J0lSTNvLVa99GoN0p$1X0iJ=^5Nr92driXxB`4-) zVdIGlSH$N7tVb!Dk;zNagBWCcHjSI;dVzRoz)wwhax8C)H2ruJ4h`rShr1+gHtm@( zsicB^_x$vTWYL87^ala%{C2_;(-#h`nCv)uU1X5YeJlaPlmd6~d0@|FN`*Ux)qE94 zCi>`cNCGx5bZ3$_3rXzpk;EFUx{Eyw@%uFngxskca%u@4f=gI4BYB!4ySy~UpqB;d z6%&$l{7wqBvL;Gv^uPt~8AqZzgR6m%(1NA@T zki0jcO`ccRzn=qmGs zvZNFzlW`&({yzI-;~rH`y+8kUHgqP>$;8Fhz{;aFYv|CdZgp=QUZ)$et?N)Yii|od zu+MiITiKH=2}0FoQFRSEJfhmxZn}2T?^z>^o1-gVQqF`2M?rfh)4DlNbhnk@Tv1F* zH71^DZ(LB6Vz{WVpet&PjgjsTCJ!WRPt{gf<*bialhjDio2jK?)uE+gl|5#aL2B9; zX64e2iB=o*ut;2DiqvSJQ+AbJ8$U`3d;D2RDKqLn@;5aYc9R5#mXoe#+c^KELWL2J zyx55b=~}2g!{>!#tY7dCKd(pEPhLWdf$&8l!IM-Pij4BX;os#G$uvBd7f|gy<9n9F zwJ;7s1c?)a;@_ormC-$*DPexns(@r736dgM;N_Q>0U%s>ft`aCpb34#hR!TZ%ttdb zZ7_|4!y0-90C{S-h$^{#0l@~8l!x%D7qa@aNdn4Z1Wd8@i6q+ucnc^wF-mZT28=O> zXloq=_)y!RK0p~b>pcCPZTlZJs~;gZf`a8CNYNvd%7HjWRg}gE<41J`Id~bJHh&9p zY7Wbs06KQD9Bo{is%}6#)gPeN0o1v@?owj5K+(Xr?F*fZ+W zp$B*Ji25#2;%I3LI(t=gt9d`!>7gproI5@yqA%<_Yj3*nw_xHV#)BPbpAxDqWS|rx zqiHW^R0>c)ickKwoL)oPK+FCJP1>XR6@F2cW|{FgP2 zEnw7KOqxoZ&^H@kthFowR*%C<8a!5jJUkR`q!MKnFA5wPMu;)w|K3#}Ois)dQbL)s zTtxz92e{W2lga*TiBetHZ*hA>E zd3qF=T^=+VREIJ{$n@JAgSHpAlvugmZ@6i{E!BRWu%2GvXyCte9`96wfdDP*cfD^H zGHyISH(RK---HiMp6y0^xYynMz7A(L)?56po|#*JfO_Ddv^HP(Pj$|mcXwKS@pOk> zy5W0``Rv#8k1|IT7$uSXIwpU0j2aw{j5GQ8`4?3^P97T#hDZgfQjvn2ukR#*tymr& zF)jpBF(LA>qMS$tenL@MfXSR=$Uf280ai?s1n576j4F@)ldT2tI+7&lbuZ)mdey2t!XfUdWc2a&VAMuPX2wqVCZ)6*qR~>q2CCsC1-g-Gmn@-4?dloolW~ z8Mj2@%)3dfoscf`>2kSd=}TfIGBqbUuUc zLcr^@%_!3@?1FHGp16ESiuC-vM;I07nZsSO)Q(r_4{<<1t7W9ioHa~!=`IULR-F(b z(z$XiVSlH+-#=5=YKS5ZIGjbrb?#FSBHm@^_J{6}-?(E{S|0(Wf0mK`U_Mx9T?iK% zc&RO(Hm~)(nO-C}y{FHg+u5rH7RsvA-PA6vP`omPi#~WT%S4@9H%>@53s_-u&n*Dm zz`#Eq@jrNYBX5L_MZu$VpF%f-v!LuKbEQ{ULPxq-*xp8$q4d0Pt$nGMs{+av$?vZx z8@j`Qm(J{<&Zd)EmTkTEy^*B=pk8tQY;x5GLtSew_}U!z)VvXbp&JT9P(Yq)r9;@+ zdtYr=T}22Pv9sR%_n$BM&(6!1-t*>(Uu~t8$$9V9oz6!dZ={ND@0Q-zz&NYei6F3Q z=OJK)TQ{@ker!Ia5p%|Pu2e)_9MVPLBtti)E~Hc2(@9#ZZy8XkgOnMnxGFf`p`*;* zE4BFVPz&M3K-t_Z!Y(&u7N^0*vhFg5!$krK#@Zu*%4F5CG<|xigaXsdRJdH(Zt0KI zk|*qsl^01iR5$RzoWc1|epg#X23TNua6ARgA8XkkV&~1efskjaQo`$DrJLquQc{wQ z!wF-0$t7f@P`s_hxnxM!3yI#Y5&_vAB&*5e1+kQM1~;-kA>@Jy(tuhFvyfZsn3biY z_XgsIin6mv1E}ak3FV&(!D^ey&xwl|GL;ZET(PFGRXuM_TfCc7m}#^& z8`IQ3FDhL{7#u0cB8a)|GCU3Zn%$dNTnY0yw517Xiyw~;!lFpJz1gZ@9pHcoO{NXm zH2(wG-2U`d_H{n?m2o}x)#OE%^y6`VJ^_~axyVxW6lEVX#9|S z%4JxJFZt9%bd^4ad$~LmPY)#{II|^xWY;xbk5hBFK_Y6}7kEawfU%G5H@T;u_N8Bw zakegv6C;3?#%;mq)W`{g1!(BkQ+9GQHzk~ zgi8yWqo4BK|1=##7P_Ydn$ik0Bj-DzQ2*A6*y9P=I-uy+*t4-jMnfP z2Vs^a<-s>6h(ur}EtQuoPHm<8)px;eVgDM)1P5WMIBZkOOPR{~uYo!N6FpLvw7djd zdlJXD$ZMN>aTf?=kHU)a9L#AkQH~AqakDb7QOuvWU0T$ytmM-1V&H$+4I$Y|uC z%H2#WGqQ9-eeJ9Lh7~c`S4WuK6;960>>M<*jZOkG{BW9SAdb_u_JfWkX|wRx?eP<2 zNL|bNga#^sm;DY`v(wwHUU!wX2x4Rz=XxVPY9C(cqWaW%ALm!zU#pKY1v4^xH8HtL zh;aD5yWf* zyNvaDdc+gfg?btv1;yVmtVvol+RAtd7=E{}-#1DBHXAAopj{e(Ay7F=CvPudaxCb3 z`KbiwCW?BOl5PNTU3NywuoGQjziXVH@q^c^>nDO5m$WHgFV=Frqo+LWp!ehN22ep> z|A19Nf;=m;Qts6kg8~#)1H%x+Sw1O0058|mrXu;eG@|%jfCZo)B(WxS%%etEviO@| zyPKL++bK>t#POlAL=M0rDN53?0wY{Syv%N#m7;iJxGo;PB7>0B9=l^R-mTcqyo`eD zECK@xC+b@b#q{fFMZt|FWj~<>_wNvlee@?vROvL58$}isX`b~$vuVP_G-g*NFWpwpRx1npARbv*4F!mstC%-n-} zk!geM)H%`x|Iu@Di1&e{cNiFHfBm!b#CKX0VScK$mcx?L^(vBGDS3U3)?Ed?P?pG| zRfO5obK&YP!jno%U3Sh5MN%O)>2}-k!kJmvsDmZeTO>TMkltGC)ccp+wn!!WsbJRhIte2xhydY$fTBDdq-s(vK1x!F_PXLPdX+1Bnlq zoyilgHj%ODEC?nxEKBjEk3^jKrn<5rQ<_hFo|`dqJ&R*?3u`~#?~Zl;;ksHLAXRu1 zG5CNP0?OzgfRYVr)UD0JtlCHWc30C&eqM*noI4uYrikEyNaV%)vWT0yAjR^mNr+@k z5Dz%G0eAl@aAY0mie^gDM#Cp0sF7z4XetL4#_0UIV7oE9RuC;CkZ}t8g1|T0bZys^1B;n zG!7}@-FK1DjA$B5V!c>|5kWD?#4~koPfN;duH_|{vesYBNO029$4|8)QA>|K@8nmrm_r4Z;p%{m&x&m@MqJgA)07YRC+RupmbdaX@E@qj-P12~s*XrAV?yC48!r+|!fyV`Fb4M7NKK2Pged zrM-as%YEAC20n$WHN2}Gj5801`+07zkel0i=iU8}=tr9khrjx8vb-(Jgz`MQ-%ds}pf+$L}6m4(K1hlIPmy#n zsm9rVsiPDj<)j{G(2P%n^sw zk{!63wG>aDfPsM%bSpY4P&dJ9K@RLTL>MT|#U@HX7CRmqibldV@o8dF{Q)em9%-BN zri!NlGoA4DK2yOFB;@!_0PR5>B@_|q)`gLYegNx8O+xXjZOna1j8Ky$)9{1D`dg8+ z)Syv{ec}EL%|T$wQS?+`daeKmN85tRs$mn8fTL06zMld6Cn{x-MfIJD}DkOTUBoPnEX36Yaon+CIkVD!$bu_UA?VcG{ymHh82E2B@(bp z(ylcAK|*=SalZ?QB2F^lcwCh!A}(P|pVF&V06aN*67((Zg^X&UTywME|1ft_zBochatA013 z^igvj_fpL4pPA z&3LZsdbHv9vF*jj#?-LB8To#~zx(0$eskP(!pjG>^ms#Wlbn4a|ZLhl5Cm*QJ zY)i%A1$fi;ny=7z@94BohP>&^=ga6QchbkYm6ZRFKJ^6ZyaQa0U~F21wX>_qI5WWA zAzEHRWu%(y1zfjv1I4U#F(hG?l2QbhUESS%*)&bIs7_4H4utyk(>l92U}qOxv`ciX zTa15E{l+hk{d>1tXcNC~ZyZC5?hFokwpOy^#MygS zv5_)vjy_Vxg~twZ#c$seSCPRwNEdM_(2rJ*;S}A2m$F4l+^NviL0S``!la24le%$V zW1fIGX+!%Ss4*IvI~EgaIy03yC{SrM#<5@oFY+g)@Q*Ug#E?7d{lzehh?B3$<4awk zD62NxbdhQo)8gz2WUydfJOL6cpq_zN<(k<^2YwQm?%=Ap8$2rPr9Xy`zPE2rnnJ5# z5BXacfvgfmNJk$jSN?DVo+dB+ZARV*2jj(LngYvUEmG}J+;5_{nPejTV(L6VFj3TV zL0@j-8?2*$C~4Y)m}C(JjS`>-M70ZLr+?;Q`PMf?C|j9*A4jm8Q3&4Bo0}Vc!nPg+ z1NnU+^~H>&V_&HP%Gpqy2|xom5sx~eua0C6xxzDuq`4@)7Sp6ZqO_*0A-#c+Fydi> zVv&dC=@&*SSL>1^S9zbOGeXQ=#5w{(}e~lVfaizlcngX>%bt zamFpBNmmEh(aD3+2_sT-9k???#JqsT@|>KrBd7Q?lqdsu(7uGD)Y*Y52v$J8>Q=Mi zhWV}3&gXBO`$vihQkB&2yO_FTMB{mgiW zz%de%M#T`$^8?Jirr;gOH09GnvoFJXSwAj7-usPW;SL^ldTq%8I^3@k!9o)%6%Z7G zIca%9Z`fS-VVNRZizZr#DODkhZDvRFPJ%~t6uqezV!lR$oDJSa~A(TFmX2AD{zL$N-ZT9eWHoQk;2m(82hpV(*iteJHoM=IvBRwmoJR>CG55xk{FtJY zWJqJ*1H!cK|L(So zTkV;!`|+B&{O86U)yomG{RRjE>{fqkm+~LlsOdtH61Xd&D~k65M_OP1v%m_BYgDxV z=SbbcG}*d*Dg6Kc=^g!-giqV$DW@RELN!qCN_VC2e!E1+gD+@`^EMW_b6NX1vXiY5 zcmgDAe@qf|`yc4!{7a71T6NiJcB*|mUcDbH$$gyg``1uC)z{a@b!hi`F3P0!o^)4M zcjIVCXHrh_`c1s3xW$#Rz1T4_j$2w>*~?HEC*g zm(b=c<|95tP#viEt{p7VtZCc4w|GbFa}ebEwdB!vfCC7leq`KOS*zEAqw$tq|0wyh zq~5CdIA$$8A1|L$g@`eKA?h@XzP9$}@)J$mna`{4Exf<0;>h5)(ZjsvMp@M(YkjzZ|2nS-55tsnwFmMB(X zC|wyDvlzb81`tzTqjwsWJODcWg9JGX%N&-XExGyuOOy@MFa|==8B9bx@gJ5;WSF2h za)z?VXhFQA&U7X?RFlzaCGlpYO!3lLE`kG5#T{ey{x`$MP|lTSygkc$v@XUNTuvJF zdazavh@i4o!B!yiW@7~w@xcbdE<9|&J(jUUr7#K-5oItMMluLlAR34=u{eg`VgqOT zUBzqemoYvx(M{0@Gh7fN=;O}>iMmyw?m%4;$%$H|C;P%!`{`GpDriItOwb4QeI%#h z!_0ChJ%Rd7uu%+KNXAb3{;?L#tP0C)AJEx{6Y3- zz@W&b7H+%?)x~4Tl_KmNeaSPkVe)`IFNPD&3k^AkDwHzHFwn+O^W)fo*@$5BqOk}l z33Om+Gh`SWm5q?F>x=i4zXvLJJKUicI-qz(A4f=&j!?DN`yj3Np*pU*-(F9l#inzn zWeM}s&ACq*xa1_0#UdSwVd#mNC6f~=rV)ts=i%qBZuHLHE z?tO+Cx3|&fz=fNj+m{`rpZ#*fd9mQvrRBzl{mKnwCnIpxM?p(%%;tGX#r7odl8ic?cw-nMC@SCZ)Q0dBI9CdtoWaeV$%%V`y_1s_zriu0v+6GL6eGgL*< zjMHn4mfiX!X@UA|>O~4{S!6TWS!JOG4(m2ZmWD0}ilWKd79;EfuLVgoFEk*a#XeGu zJqm2;Rqkh}lt^$g0$)T4fRM2!eU3YI*60H|#DH7cyxn^b)B_LBN(IME+5mrG$;qkf zTHT~;k)XbYJpgJ((Haws6*u}Q8LqQ%&7@(SLWe3g6jX^gyh5Oj94bh7+L2?}l(eyU zrSc>*)Ws7DIuNx;wtP-rAkVJJ-8{g5Y;z*$WHL{vKTr2HbyD@D?-Je4>&>gy?;8h6<{DE&!#gT zv2${^03M}e!ku~f;Ez7SOU$mNLtz}K$O{b z9qLlnO0FofP7VeQll)VxJxgVZTtT11tSJTJJYuc#N2-vAt^Dfm+y;cJ94uP@%SF3c z*pMWj9u}H?No_uH@Pno>W}tWtHNqr%ZzN5MKxUyhvY?DV$FVsZusSr(xF{4^^oKfl z#gH_a!KrV~U71QA1p07W!2#xLCRXxMo%IMhca5gPQnaL|b)i4f^|*c+&2my6Fm0q0 z@ufo|4iYbyZTJhKBvGzL)Onu93D9$zX0=*X!4FvoMN){~8%>FBP7EQrTpmU3DV`um znu;;9zhbE%L|$Km#c{4mt&2wjokeCOaILwrABurI-1j@%PmSJJBaVU609!Y zBFUlL2308wvKzPal^x!bFvg&9;#SbOZkX&go-$~+I22>03d}B8HmoqWUOgi!3j!J4 z6P?9!P6#AA5-4*gVAl>j-h|X>vXw!HkK;&=5%RP3`zcHv+3RB=6G4ey>c{&}AWFb3 z3li#veCn^#|4`+u7;^{+V^r+=;U%JfUq?%lZd)c1jUqCHcN~05C_?W{@A{*aES|+R zh=0T!-#}PHl3Z|nFLy|ox*rx8PtU5}WdKd0nhdz3C=MUPv?i<;{#Niu^ZjQyo?@Fp zITIn8wxEGJ?ZeGW($syzf;cy`Pg^>#vNS#|>E1nuytLr)%`H~8zHiP0C2fQ?{uL&M zj$%&{7dPRtP$m|!Lgn`yTr{a5K`O$P-A(&RX&`wzVgAkzw8l=Q-1haG{mV1h!H2#j z8E>@woj7X$q634wJ^Ol?$8F(zw4bfF0oB=f?O=Dy@wk2kXRUeg~l%!oT3 zep;MflEZKU4k&rdn(7_pIz@paCn-w_65On1a8PhR00#dZH-U+`&k&U*_6N67TeqSma3b1|0W-V6E<&fx<2YS(A@Z z?Yb79cih^^cx3zxjt8nf(5BcRBODq7eXthP$bwz`i#KZfTK;%r zdP&eAF9{+2d)wRcmJFE$fu<5j^?a%hLT@(>+~c08=xzeIl{ii+R=Q285L z;ZuxBQa#hUb{LhROBa5x59KmH&1_}Z+E)13jQS3bT0Zje1_`b#w z9d0KPez>0Df8%i3^mRX<#&6-a`7$!{R++b22eAcoCeiFE{*@Q&;89 z){b7%e`wiGJG9H+_VaZ=s+{+%yMH}ispfUqy_{a@_1*Lo0&~@S#~3y8@pm`KlM}1I zMH-`~Yk-ehK6&A?9jBb+ZhBxXH1$7tl)mtpxfW2ZYWX7A&_$fgNKTX0_Y5`T)gu$I z$3ErqRBFZG{1nW(Zt_m0H$BGqWk%Lsr3sAGaI_RV42095TwF82M$w7!Z2X>SZcLZ;B6$Lo=$q&~( z2mX{H(vNrdNLO-t=$NxcQVr`U+!%nGl=&?w;$omc4MU!&MhNfFXv(cJOs&%N0u5lI zj}F(AXys_ut;bOjl&fmVG_Mgz4YHywpH{q4mdi9`C&+#=P+sn4I!Ozus~A#dC9eD) zf_U1T9zEHKd@3JH3%T(JOQ9?aY6Dwzl^X-N=m*e%g;<%%2p(a0P@2jx{f#)iN^K7$ z)4!lJbbrY>u5TEfrkaClSc2Nsx&!McI^4rBD)zEp-_ZnJQ_83W$2HBje#qO1!IA`C zUINwOco=wM6ntj%^V}*36UIUVYir@8{5#%ijKw7+M_@b*k|#{3SM|<9MVx|R9W%7Z zpO=M+R;8m|BuyRREKsjD1o^8lXm~GJnM$+#rS*x_bV5R8l>U?otV)VV=6;eD=++m{ zR;%V=G35 zfK{;2MnE``e?V47`=wCn$vX0D@6v-1H)LoQfEaApU%WvI30`DnaO+UW!c6|RZ7fR= z(}Vc{ojfCQSSA`VM0D(XNC1t2hAa-Si!!McgHf1%{{Rc_a*>9&`+P~#AZIk)T-y|W z@4PJF`^-=op4!mw0q=<|+!_Y~na4?QaRp*d082W|6FDVJbifFh#66X?o6UDH86!1h zsLPW(piJ#*`ijQ9q%jS54G!nAY=WtWhY?9ZlLQH4k5e3%Ix5SQ1l)1imxkIPMGFij zbXZ{v-u872zt?@c3tgZ&)W;P?LJca~GF&1{7R2dUfU<1}1_>Gz)Y_3ygB zN|W>1qbJ~SI0epL2(0<;&EMvM1)^T(t2dB{KRS$NAGKU z=+kcPWqYe^+mJ^UO2$|q$tW@uuPYO4QO7zkpAl~M(}v5wgIKt_CZnyRQ zyuy@uHM)IT^sMyrQ^>|9DQE_IM^)Xq5hFf@uhGCH1sAS2L%FVS&4y~f48V(op1U_IRq zNo>`5Iybp;pOtIq%;wHue$d$^CFNIo-t)x%X+15_?tlCE^gaQ6u!P;$ z?Vr{ww%7`+4)BQ4c#y^u+skZ>|f-;)BSjNJr#tzpDTS zy(O>Oz8oS!^x!(bX6-&76J(!a2l21V8nruoy?2sb&kjx|oG24P=&5EBcL^zi_M)Y6 zI_2mYQ!q>o{i_%EGX@6sr)bsaGF<9we&3^hOpv^hJY7C)Hm-Q>d=4FiMS96*j=n~d z@T|us{ULda3DSuP8E7x<{@p+cvuTfJUeP=>DI2T8+>qj?sRHwvi`l%SjN7tVhd!D} z*3F_MRg>Sh=q=5vZvJa6*`fP6RDZ>awV;J?+0wNRMua z;txg^dYgHBrm-Y?iGNPL%4p(l!Ztt3xTcfDwbkT~L$BHWnz%a~Z5c22!S}(6K-kW4 zE|`A!kA~e;EKI!{Xm4eaUDm3}?=sgG*>XwmKK1s-0L@`)1#E01A_09v)+$N`bP23? zEQ?9_aY5pHb~fQ};KwL-n`M0fK*yC>bC? zCQTL~$0=5zY|BupFbvih5;us2(FaQw(9VAb`iM&)i?Fg9#^t2RMK#%g?WM!+ted!qh{X#(4G5N-DN!)>?-`qr5>wI*1Fc=# z)r$I9GCAOQ=8@RLnzT&cf&=BshYR{Yll>;KznnRV&9RiK?x5V(sqg8aF_57~)*dI8 z44^qPL8;0410ez`;E9ZhyJCgm(U9~)Ly^aa!}VpLC{=nVfJq8P*3(eA;}52|cdT#_ zts6x$^hdJkW2RWRkK&!rBz1j`aA^F5Qx1qPLv;uB6G1L9etu2?LQ`VnRAu;;SfOGq zi7`ti^b1;9d_XDCBY$x|WpDcV6GnTK&~PX-L4c#!5!eg6xTLXQ6YNQZ3Mb;+U+efI z<6%;pza|j+^rv$4pMh_Ae1kJNhNiJreOV-5^MW&0e#e?#`#J7Nfs8+`{|ytH+!plpQwORcg+DJ0=^&ZTs_%(E7kS}8#hz@Z0kvB z9DOW&U3(j`7<3PTQb{`bFd9!^B=4;GDs!kpUn#U1+S(rrt+0S6*brA&Pd#4O{CEyc zoS@1LI!EynIxA!i!~+_FY@1$99(D1@+xGa#6&&Sz8WqR+Jx?Fs49;=c|A(x146bZ} z+O1E=wv+Clla6iMwrzXINyoNr+qP}nw*BpMzW1W){!67QsY-tAxz?P|GsZ76VotUc zsVCce$p_NIqLU7DWsJgFp~0Ud6$r?1Q(m!{u8lEjJE|j)>WZ)^HSHkX20gZ0nPRV? zwOum?yc9}7MTIkYSt%&}`ga)A%8ycGyR{m0gRY7drU|eSDxfnYCqPyKwxPeWqevy~ znM^G6k;p1v-QJ)^1TAH>QiJ*+&4^4=_4M5n*8v}oQUFW-A*MNz3i06EUOnyUT&|!` z7VvaAZYpF3qIvzZfO}shU(X>2I-Qle*tints@*{%A>Ul`a0UUnk(N=;6h#Q>QL8Ic5buj|-fB$L_z^TRsbBZ#5o;XpyxZal8VtfpNu6U9MXU6Loik8K&;_?Qc4- z!iU+1`|TSG>04K`G_vyFxtyu3yYJ6icI%y64+8QY-s4*=bV7!{*(>%?8ZA2jpKru( zNux5jJ4l}o(vlkB2YUtJ6us>Z?~IBNWld{Oli+y4gvRveIct;?tHG%${QauR=LLJa z1_jlhp)%iq*~{6dtl4K5CKCq5{@Iz*-j%MYl_temYSOvsj4bX2#gk`>UF7`v{7X(l zylY#Tsm%Jx!lF$JtjeG{vjwAau)H-ASEyi78^7-{NqB!G(Gr9@?vOYg{R62YmNq|- z$qUH%g>TK{RQLOWurHzlgGKU%X$r)>l?%x1wCMZ8aFm3bCt3r-!mHsV zDuVSvi~YU?`*ZMRjSXR~8i<9)4I0V_6((sVz11Jc7k_#0+Swa1!+16@ zEm0nTCZO;Sr|5zeKox>Q&B2lx$cbpN<&EmJ9_>j2)20c9Awe@NdFvedh6KJnUY=XO zRXtwun8Ni)7$ae~vCkMB{mO*Ue!eQ8Q&*iri$@L~2^0&2Qh?0xYY8Ff8_0!FXe7X4 z7g!sl(FwryG+7(KoGYNE@DoM9v4Jqlq^@XJG)X^9>G4nku-3?Ubh z4h>oja@JR)@poOMFc`pUr+AZB4-gOGLv$u?`K!I+ZX_{Fsn`{mk_*<5rfC3tIZ~nQ zx9F|z&pilwbSQ3Jv7yZ?w#e ziyp1Pt@CR=IsEZ1{8OMSKHUWxoD4)Wv+?zJVQlyNiGJ+4-3->ZIdvRteowdFWq)}w%!phzPGw6S+BhAk_0ucIi2k^eYTf!yMiHQc@AtmxPWtF$-|1n zO^?H!i_yJ}ZeAzl%D4_$JxW3Y&8-la4IO0u%}{r89RWrZZ^s}Ck1aSZj^;DB5Ik^) z4L~?TI)W^^May`tgE^+#dpTf=(!1c*GRD#ZCItG`(T2hi?00LXAaCIUN>L#OK^h!8 zm=Jhzbg+|O-Us&B-}>vwdGyIs;~2OFN)Yn`P%w?)9VAFPD1K7w!_od36T3tDP1xB0 zg;E1sNqwE9HR|VLVnmFEBZ2w3FJLDVc?2|;N>N+fj;7(GDJaXv-OACW4M6436!Do9 zlo**#ngp`eGd6-XNICy$DKRs4rOaP&)ZngOsPABA9VaC-fL%u?c5mdH8vzG}M%h=D2om)AaO2V)scJW+TU|-V_M|pO{LS?mr z5dq?ZXf6Dq3vAJvS$MI`?u@8>a$KbtWCSWOJe*S+a8<#rc+ zKWlpjxhqaC2mV)PbkLtLL-51>?|oa__Gft%SkHs+v|E~Gjpldvi$3MnH}(bdB^*iS z@=>N_3)AT^>iBBX;l*Ku6zk8SS)O~lYPXK+nqw#LWARt9=v90s(W1$|jeJnA+-ot~Jxv{HcpRg?_WlMYwj81?)u{ zNfZ9^0`zRX!dT?_IOrbW{otkHF-=sfwdk`3 zcM|lZ$(V(AMwLu`4EtKKi&(uSVHT0ft8rrv8q&?K>nOnLx&M&C*BRispE>{_%UD0AF<=lv|bTK1Z3O^-xO&OH3X?@Q%)?lUDeNUx1*Q#y!%qDN4|8?|2bD;9kC#$n!Y&G-P7UNJAo7Nk zLH!+b^MZO?e@MfXm+A7mBKylalN6m1*lUx(wx`N#L+j0yaFHpkNyGyaivR$HO^JCp zgYXGGe3~}IV2%g0x~x<(Nbn}I2pkF#l-9BId=A>5A4l+I1I+Wf@$Qa;QBoL9Ix;un z9|XF$Ba2XTJ7sz_Id}TXp|mx(&(-d1ltaI}(w=h{_4KHUBa6=j09QanSWA|1vc%$5$ri z(>K#$5I%m}`)ky2WY?wRPtuB1o_aJUH>@JjBfXuRArtRq989NYlWqYRvY6V&I4!^+f&y|c zNuAY!Qq_y%7$ugiC3qS_%+pd0UCT2!GnHd<3J)jpquS^71&8<8Z?+s9;_o72T=rS`Mxr|fp4*YGAMV5{D8*~`O) zyT)hQ3-W2pOYfN4qj|&K>>RWhfp>MY%hAj%dAW0Oxtn~ZlYOqZFcdTi^fn|_4dL`2<5lHV>$-|%iS$nY#mQeP5LQ)!rOEH-SgS8Rc4 z1hjF(OI{Y3`V5Mq0vrF0?u=G%R4&XyAxJx{MO?M%gGgWpOZtS^sX09Y#&D~h%&&CJ zxbQhK@yr8g=7A18eEkna=I;nB?0t}#BZ+Di;;_H8IKuifOq0b(H+3>@b`hZksXbKL zRAccSjdF~P;d3t)FUM11tx;sS3s%JvMY) zWTTbC42W%uF=|N*le)DlK>4`fwfQdL!{Kyp4CvMKShMcqlZzI77ditip;0d-JFs1O z6U@Tz$PeAHyNl7mj4lV(4F63CZ-e{6O6Ge%M0E4{|K|N$+4;6*Ed)TqY7(~KW0vIf z{}+_PT=B-|Uk+Z`#}Tkk7UwQ?Q?Vo13yC`IK6|NCXLuZLwg!aLAM$=cpv{`-CT}8s ze$HFcb-|LTYQ1l?dtVyzj?z4xJw{+Yl>DLgTfoJoP5Q!H@tXE|nP(2(2N|pWeB8Hn z?MPNCrzE{BJikK|G9L)HjYPcc&zKs9Og)V`m7BWrgeW4=zIMw}F^!Xh4 z4hXO%hOO+(%Z>iHx}Lw?`hIyb9|94C-BWniLyG|JqktPQTCxwVpWCno$t4{xcxMe3 zQz*6#DemQK7SO<28DsW*)6ZsEMAo4q{)}7mx)C`(*=Wwhyh3G54I0X*!-Cm5F2zb} zy2ICr7qvO`Fef*|%`UNI(zVNUsDhVJaZ}H-E7`Q-;K+SY72O_(;7PTytn}J}F!kfg zB0bhZ5kX7lNMp2>B;rnDT=dN{jKftX)D+A)zog_w3Gp=Y@%pl<1?tfz;o&4GyolZY zqJHIwKw;}Y#goPft8Q*pIkZqBl@&L_p_C(oesPrL=={e&CCk>K@L134%x>{hUI_!u zo9Yw!kwKmNS0#34?ARDk4cM!-ekO$XOOS-f;ovI~S8G|C7RxG|06`RF!Vqepq4vmG z^9x|bLE5KwW*ju>^56p@1fc;J@)k6q_M=ov!~g8QO56m{^3)+MQyCSIz!vSMnU^6a zC%Ps|CR6UB`tQbny(|c%9QUQ6Eg3~mJl(9ycz4xvY)?&O92IFhOy$>)+~>$!Ne(Wa zp`k`V7?T$m+r;j3h{LU{?$YnJxYQ5(zd?#Le zfNL-+yG5k)i6gLG7N7oG6#iBsTOklHyANCmjuZa;qecnZvV|p6)&#kVx-cqnXpI8Z z%af5qhM4HfMuGSE^0{kl=uo??5xdN{Lk*DR zcg9^1?4*=0joMBIN!_Z8>0$SlLB+(=`H77hxm$@0*`rvlv>H(Vp3xvXE-i4nUkAt!G5rW@Xc5X?3lVQnXkqKFHDrBDvf#5lTfw9^+}|d!~%T*gvfu8D4-66 zBzncj@yJ{I16cGMc|M4Sp=iMd{S+feDf^-&295!R7@v*~RytABVY3l6fG_O&f%4qUeWiI*UuXNM6SHix7QAvWEJ&h zNg#=D?mwy$e+@9zZ;SJ9{lL6WkjlApAyq-JAv2tLtJ=p4Tw0Ltl2X^#(;}ql9;jG) z{(ik@#@Yr?K=itLk*#}g8*b10nCI@IrTCUw?R0fQB3Sl3s0JoTea`!7+0DCeBVn1h z5-Dh#VUvkB9{bQ?nmg=b`;t^zR{-`Mn3peAN^bG%+_RV&)yzEaw7MShZi(7sP(SLf zg|@rD)?H*7xyiB)M&ssp$h@7Kv5$iR_ zQ=;uA8(Q`thRl=CD-ig}yNYNo$fn^|^3=;+&y2DP!NLz6!k z#Y6j@Uuw;?%y=easqTtqWXb_v`Q)4_bM7D_!RuV74DH-UawB*Mr&l%T672i)(#keV zk8RZE9F{2~$0KF1^_~)qWl1C}OV~;SQs|MT zVeF%;^&_l%wrjZDOeyC%ja=6jQCj|Q6Nmw^qwx(xxv$bd-Z6l zfQ|gzC^OftklQj2Oum~1sPh)G4ACRHin_Lc7;5k=$%CcA^pOJ>CSrVuxKg5y*|ZpB zn2AF0vF!z&$CbMkzz@xQVS&g54+C@MXv^^*O=3+sXY@ichh~K_BgXslsXbr5CA2?j zl7UQ#-W8qE>N{^`sF6I?11*Kwd?hc3$?zWqVD!YhZTjku<9#tbEdeM$z6w&vho${% z{u#$IET^3D6BP;y@b214DwEf~C^gphbQ7z1fCa}&7Oi?ii^z*KlTb^{HIT#nzzLRP zW6&lumw&!KldLhAV~TNBRgGyCI2r}97m!0GYC}n|U*$N_T!=xUTpm#}YZ<@;84gN{ zSzHlg+4vPEVzQSM>I7+ovma8a*aTz5BqFUStcB&0OO7-{SiOEGj-$aiA1dVU0gBx zDS2vr?1!uQ>B79;_5P8|?4?P~%Ios*<;d-!IhysBr&$U&YTP{ruK%?tA#`kyf&`ZA zr*SFeoFr6J6qO{>ZmHgvE`MvOoUDeGunQ*g7bO%{iKZfyClH)aR21f{15*Yuku(C; zs0k>H3kr%|h~YuH@qU8E48nP-=6S63*>pXYUT58G+b_Mg_BngHl-<62IPzJ4*jdKk zzPTj5{@!YmMuX}?ZE6Q>G`mduzdv((zU&O;2jg>ipJeU7|FYnH>q+g$^;mC$bHNV* zTN6}#;))a+snF^mtBZH_sZWDETW2F|G7lt!mK$dGGmI@f)#=w&j9=B5_ z3U1Uq&~p-33`Sk2z4vMq(8OL|^-tYM4sT4P@4#_@c*)Z=iU9!`C7}akffuBTxT&d^P;yHWevpZFV;W>0?)y>6%S5NWnr2 zNrL7YFet$AA&iW-Vw%0!C4hnZN7QYh?ccvZ?Co!f|6v#cS0uSU$z$z2i8O-j4CUEA z;bUXOqM>RQT+8mTw}& zS-$2rl{H=p^`jVzHv-57m0BXgwhvfjEK5wD@T*wr zaJBzu-na*D)<(aO_-O{ zJz_vX`LU||_00SJ;u9>?>=S_Db;-$U8nBcbrC$b7nS}#Yy~KqN8$ot+wa>jk!wlvH z+OEB|z+~ui1go37|5;q^89oFu4*>+AC(oZBqks5J0(SefK7lVpFCyX9`}qvZYGwRw zi%1%S6>lTnq{)_PShnS3THXMFiBpG~h7!q;1KZ@7vw_wH2%Q|nQAtIWl@OSo~DAu`%!%ff?YXa}XK8g)g7>c5i5+p%qp;y) zo`WN2Kt~34lwniaQy%eM+l-mGd**&)*=iZ9X3>1ywtJfZb4Op*qE)VO&< zNYeAhi7g`~S{!Dm;Y>wt7PwHGHAXQ=wKX-3P8ym5LPW9tOo&QF2*aP{X_mbjD(+sn zS`nwyNtfU*G70cn1TiBgi=r-wdD6I2AZ1Ps!<(hnu$JKT^|m3iHk1^BSy=fUqv$<2 zk?p01B&iwQk=&5Qy;`^{(HqoVCEEQc{|Bb~Ba`z-0->WE-_ag$hQzX;V5!eb6~a~s z$LjI(xogEbhfCR7&kiPkz$_2bKG}u$qxcv6z`>k(`Ab10TD~PUok_ zjFJ|ZfgXV*Yy%m=`9$d_yW3wDA;v^hU#43MuEZm;Y8Cq%WC#ixPGkuEe$11J9sf!) z0CFB$rtb>71bYxHF9Xa;F~$aDO$ZIkgb(B=mJA4V_#qFcOAY(oi(~)xyZky1TH=^A zFGt(%Ym{h~qqQc?m2Hs>$9!kVTwcbUNqYqqzqzB=qkwMbhAQnNyRhF)o&e&iK-+o` z6TdHi^P@ zWSjk>vwpTcw@zt#yIM(qmukK5gFf>tH+qqK&ZXkaIM54y#FAqf`l455X6Eu&K;A)% z1v_t%s)BL^__`P-0r%$*8P1IuKRI9%6rdSz5X=v+-%$VdMdr`wHK<%%I&mf zxvE;g+Mu7V2_Y#AFLD?Rsw6PTSfkUgi;nEAe4xwoJ=tq!vbKOh`L>|OEVa9g&L7ag zg+~7SUNCQukiI@w4tZgNk^@UdbLbzP8E90f6r$FI#UJ`h8#$yGcdy#9@-D6pBgq%f zqFP;g*_>NdZuUZQ_73?70 zmplfV6ztV8a)5l(J&CisU--cx^ypaXW8EcPUgD%!X>1w3#o&0q`4DffD3x_ z+QO~TAn2y1wM_s#+M>8h<}_u#o3RzY_{7~PI}h`4aqcY;iXK?1!9*Edhr^Kuu3unc zL{%&xzvB+1d0-J(Evw&Xg(=TTFEtIcQLi@XEyuE@P`x)rJQ0P`0Ts*%Eu*Z-@_J@r zqUHqlcHw#b@KZK)exo5Kg91@d6TKlj5M*Yqf|5!8nys^eU|tCSVo|#TguoOJfJgjK z5VF5_76q6NG`>}2967f^C+GqghN?CLhI5fJybOj3N5I;B-Y|U<$6!d`{AQ-`zkR-)1Cjk;(0oA_eNA#< zm>kx*qp3n9pSjws2WgZb1Ha!wzr~ro^27C#QIL3R_vsqn^KzRz7J1vSvZy|Xd_JH6 zFO|t&SCYEH2=g?ZzPElL#B`7InaA1Y?Mz^39?&T&caEfYD58!>=SsNP> zd5P8q_C`=haMN3Un-yo3VXFrhMKfljGLnsOqiSjm5THY|I_1_qsVUZDAXR9llmP9c z1_|KBQQ}qP56bFCMbWYb^`JRao_yL7%4nFa4i@qQk*N|!frAKD;zFGsY*YRr!@Z(n ze3Ugzkj2W{DoMNA#1QK4(W*)4sJB6vIDhIjgL5~?1g8*2oP+pa4EcbxkN`IfD=~v_?W>&+MO=pL+GBz7 zAbfyJd=d0%fpYY5OAX~u2NJ^|?B&J)ghCA^)qNpC8yqa>@-U%o=uCvc_*J3M@Or5X z!#yI=JTvsR6D>9VH}DeNS>v%wB+>~KLUns+<773UQiU{VBkn5HNS=zWV76rI?@&CF z;VS9!2Lpag>kpo56bbJ_3_=3Effx|?#p-&UMn9uE1!uXEoi~RtETx1L1K@orBGK}P zw$u3HKTL&`{L(O#6b@P`A@>3ZyVx@*Y|!q0d0Rm!#{)u9;jTl1q#v=nv97+LnKgt% z{7wfxA$kN94v_sPerdotI0A>$=*{TTLEn0B^^lAIuyxb7rnYwO<9U;H%-PI!zFCjP zyOwbRz<9s(yk=lXhg1i0-f-H*0Q9qp#e8%_Pjfvweh9w}U^zDb6osPk*CeT*F^&^- zV*DEsn(%k>C!}09r*>L{E%2(~$)QD;Cnrc5d#dNIOhiD@+9iJ*;3e99gnS~7ISMHqdIDB|wOVI9tn2EGm!fj^nh(HVHFZihb zLZLsR0r#GNX%)iIljR2LHPGK*Hh|bMt+h<6A!<9j+(Godd4ar(Va{a0;e9mtzBS*%rxkCVK3T#{&;m|kTgFL$+FlY@1Ssg0K&@$AoUV64MrBu9i-}q zYV!K_H6p?b$miBgPfc;L$4LPx3z8TdgkTk)UeEF6Gu-nl5oqj&9vLUn!~^6pBoVlk zUBMadF=#Ce(+Q6LNB-gt7^ZQ9`Bn<;SUiby8Y6>Z;|kO{{xOlGLfpKmF{3IYBQ|-W zLC0tqsr>E4!XAlrnT3&4xy725dOFS_NbDWK$e5a5#Jz!qFFvj@C@{m^5tD|hpvk5ICQuoe{DO`npeY+VDwj~{!T7!SDsZQDK!LJ*5E$DTNcFI-LapXk@6 z@v0mIr%T6^Lf2=>X4UTd%^Y!VstrW{Y4D$7zhU6e`3S(l3D8u7sDs!tzYl`hUX3AT zxmlsu9?>BYHSNwy;8?+Co(@&Dyaye~llp&xR7z6pb@mwtz=xsjMuO7^u*dKx)cy}= z<6nxcWZ2SW7yG4OzLtGMjrP~TQ8B}oq->@;vZBXsprp^GV9Ynf#n)Z7j|=>q%a23Q zZbnwed>3@o9U-m6kpNQ+8RgxaMjw+q8u-ND?K@ zms1l5!`FFvx;#4!ct_%_n_Io!@I1C?kG5H7RiCSFf3z8csx@Cmwr~O84Qw+FLakqX z^NQyFMDE)HDvJMoCn}CWB7GBBxO%?!;Ob}X_QCJ6$OGhZ053(u$+rgICqxHTJ(Ery zltEkfThFh<4g{*5z<(bEfET#=%O|^;UgG+eS`Qpv28z*x6ai_COK}^(wqcQ)tvw*# zlA}+dtAwYmdsI0c2qGl!kFP&m5bEMW#m|H)R*o&_1a48~GxFA`QmBW_Z`*pO{tWMN zeS-6t5rSqA)oLXG?1<+FBWqaK9nHT<;#>H z$?QPo&Fb=4E0VOaKNznKjSH=EEr9ng>n|}OR>3wdVg^$?_R>=X7Dh5HYcW!5$iP^`*;YGO4igUXd2w~X#td+1rODwiR+dze zP%#>(iuXfj-H;T)oSu#<5hdVAlhoahSd>vFNMMowm2U_EnmK;ls`x2@qtBMt=~RYM zmLXFy>!$#rBbG$s`>HoT;79fI({N^yyN48n3u6c6rGI3m5WbK0S?Xxm)r;dA{AlRi=`g5M9c4|K)?>2uUcgf<7tuhKOplswK`y&?yIw;RqZ-bM&S@YX}o zVSLXj+joT%S4R|nHO}p0G`)3W8bJ22{`5FQM|h!16YA=(q;Rth8h-O|ZI!BN@~8L| zU8*|R%_9flFc4I;mcK|f@>lfwn2QAU+f&cW_nSw1_SR=19DuQu)22Ev_oix&IZc_T z)Igp31w(W*QjgWusodVIROAy=T7kKlLOiF^`H2krV?Ef+U>QKls{hc)lKW1qW7WFP z3rv6aW3cseW7{tkkL+Yrz_t)!ECgOIJ^}4?( zBA55si{j7XtTXmcBincG%=ha{Zl~{_S)k@k4HhA^b)EU}nYQ$$|G+Nc0*=SQ|0EcWd1DLFZ7D!qGqVYRpq1 zLDL21C}vm=gr38 z;24>>ppS1u$PQu8lcdkcTxpSw1j8DW=bQ;!7do zo5Ne-^m^66K$t%%&#%W(?t!sMut`s0pq~RO;s4^TkAtC?;=%`syiP7M^wP zy~Y0K2j*q>xo$gbI#Z_LjPZV=qILdgxAj=2?Ye9;UH%Jvsp5GtWv!@fAzGp5=vf9X z{(cWXn@(Lpex2wpPkaX^K7Vf&>&{+L!cg$B7x2Hzep@}Bx}P>KYsUaPk2!sA?Pz*= z&5aK<&&7tAO!6l*)Ss{Q@0Yl?x=6`wUgoZ7xqrOxe|KYMQAMIBM1Mzj7lt=g&d|ys z1OsCY=nRl)h|_eNU-BdTS;5@{z}R_cZnd@~7U2|J^$IsL(vLvi&lg?(->1UJI6vAK zW{x&RPhHJ_Gv&05r)QZ|$olM#J9X%)^+Vk%{0KA_w5@adN^Jt(ywKn9%2HwdYW0}Q z0rBOW0`=t0NdtxTZ}sq!tv<<$6U^x-ap1JjlO$W_i%yxTI6tvriIp2GIE<$zfHuEo zN%zhX*j9O4qNV+8>8LV?A6XfhDvRd!kADpJ(k__WQqqku%9gl7tkCTOvqeTV3@RX8 zo-%BnToWpX&vGBwhdDf!Xwd3?9#ylI;I?KOxZ43dcPsg!N*}AoX_X}FRhDUgG?FY> zomQ+H2}Bp2M`q!)3(0B-94AREPp$H|tN>3BHZ7+8k&B12_1}@7`Wt3KXq05;PQI1WCUg2;t1s$e5##k7fFNsS@)rSx+WEIL}fpZYUV@jkH^kRQJ3Z zY0=XfP>6S4ZO@`+R}vdth$JAr5WQHQkp-o)TsGJgI+G5P-PU>%)1f~`1bLwPZhHCp z3*I`hjD_nfQ1Tnd3*szKQUl9-mlqk5R89-W!2I;b7iHzy(oyHMTcJ0kM$Xu)4d}k7$NB3OM}uJRp=Y)F1%24aC0~xd+;3$%qn8@4CRwpexgySj zQ^r9t(;*juR1QNLr}b4EPRLNywTsd-BU6gG(_dHh6kd-+4NKNXIStJ+?ExV-;?{2o zEaBS9#j@v)F>Y-<&F!fxo>Lyvh#a;rw`+1IxZX}?f}azN4kN`22E+nfC5t;uP$$gQ zehWx~2IM76Z-aiS`bYp(;gRQZSE)^d#`N*F0R>g+^-*I8e$**^VB4rMgvjf96!QPC z-Z#Ck9pZoO_GiC6sdhUI2UTy|e>Y!yome(+d-S75Z$1nZ*#cL6s=%bGZnw{LvTggh zr*UVOn)I$MsR>1_9;Qm9$)1J20b5JUMxB?^Y0>y zf3>zVy;DGaO>xTU51!*>>}IvoV+nsxV_@Sx8E>yfVQq@?Vfa{azmCz)%zWoB^7ULi z_gF*wP$c?6DY(5+l59r?gR3wQ4PSPq{_{^nZO>ru&7PiBANR_l^U+9bZ|_zQ6~-V1 zkiNy)M<5K^n?TPv1xH%`i|j7)snx^dv%iYa#g>2#4d#90>c_U4Zb^+5EXs_lc;;MY z-J+fnX?AQJ`B1uv*9!a)>o6(hP=eK=n<4TXa0l2=%Gfu8g)61n8JAg)i{4MZIMEuB zAXbaD2?sAQn-McYxetCokX3H()~lsd;R(tWuDJUMzBK}6(o`WOy_gpohFK=nQ;`lX zlD&9d_-EHnZbCslD=DJFB$2r|M85;RN*>c%Qb`&^BKGEoy-t7)bVRtBEh_onz@U7l zbicsfZl&PHGxSM{vqypaK;<0f6^5ZaD`dx)M7VmQ9oA~MZQ7pw|9C5@b5dtIyT7om z0`!yrl=KHu1FJ!W%+F&tcCc3&u4jkMT?>x=Nq3)$bv{xto8u$LyfvL4ca%3rfB)|? z&u@(|>#m0_5MT!4e~UtZm7ZqpJ+j@nBx8^dz_M#&~?kA46!P{3%} z(*;Y`{ZV!TGJAi?bTw_dBBAA#cYAMA4|{yhuq}Rscfa9^y@+Dw+T%D$8T#rcQ{jL67SC?^zU3kjO==>6Ww1w(ObHNw{K z;`a}7@uq2}grZh7;%HD+%jJsszf*6aWi-$#iMXi80kMfkjEwuWzqD{@I2p@NNj%wX zfv|r)4r9+C7c5s0+m$l?+PqZ5NA;N9DQV}Yhp**$!mz#%Z=%%)%WhZ<*@49<${wr z{dV-s#AU~4v;Gzqk?WS%cJm)+#ihB%=?kAB)G$opZz*#Z;@8bhQH7;d&giVy4X$I2j`!!ek+x2>=n&;L@ z%SEKXUGKW*l;%19C$|ee=cCZK-LNN1RVuwY?0I8At^&vM$(@8{3qUJ_3LY~C98>pU zWU+=ugh>FEpFnQ}(URe;++B*kuWnD3Eqh47l29>(0;jY}*oeA}$X^JnR~`P0hL%Y5 zmKHldh#o_M#h+Agw@0Z%;)PP`xAB?zxLBIXoRi3bI~Nx&$I<=u#Xax*{`Mk1+Y!98 zXuf~`ZLFt200z^E-AW8fQxe@{i@uP3W|c;?&dM3smFp9Uef9G9%g*Ms3zyqeXLF)e zeerZk>fv84Ty_lip8+oXQ=oN&-o<=@f9r+AV4qP#nx<*s7LXe*1-LK`T|LB{?6MV! zcdi+j=_UtE&RcCzaYXU3E#%Q!hN+%#3U$g?1ao$)-iWBr>K(O@_K=M~YS^}>qMT@7 z-p57()>WG+=XDOI6|eC_6Y|EM)iEpMq%x|1IHsHs)|6{jRHt3mQW>A{ta2r1WTG>< zsiLzNj$|zAizC!w>;!{*IT8TtumtZJ1M$?)L5@GSKYJxr`r98NhqE;ZifZ z>u_{(nfvLa`Ip;H8+G(XqwTT3D8km~#1?1P)~A@}`uyi+d+_`7d+>AMMs&L@?-^$& z`CL8o=^6_|i(y~82Zx;<4|`7yzfPD$n`n&tssLpCY4stf19K6Ot{>8abWoP z!;m;G43--{{&W{kcZS}Rd}rPR*PuKUojh#zg$;2O30=}yLp5mho8sIKngEH4QC?d* zT?Hq!dly9hciUg9HHPJWYCz3Bkh0BqQ6VYx6^mG8yPZ5q_s+1o(bvVuSH`)_-N ztZM*j1ujate>gJd6kMQ!e{OBBoHv0Ao{S3Dme}`>T(nC8qH`T+>}~F?RmkG;S=5XL zw0nL^Y~1YJ-I~ozygg09;=M}z>{(zQ1AVXXpYm9C9_ZKjMm6!wy-PUDiK)<0dLA}v zVMc+n0vVME@-7}*R!cy9V;cH=84*6W!qpOzi7;4FJ+75{rXN6LeE4l2W;xiivSO*x0eW9*|y$UO!>JTF3Pp$IZ$y6~u3j$8Pfep^GwxMt!qN#f5FN zmo+U)aj~M#;*hDF7+V;Kz?W&g1-AWoT;~S2m$-ueJwxeyPPzC?2I8$KAi_TP$bq%z z)KBy^tiAVr(wog_yS4}iOKW|NW%hngZ)Nw0J7^o{wHQg()sh%a-1R^(!cBNE`g}3= z)7`sH++cC__rSpg(Hk1}v>RKkx+YSuE_K;fs+2!pm0gupby83!kF7a|PlRkxESGIO zlQ2AS6ET*z8{>XVMV8PsYC;%kT8zteZ=asvK4*DMcgiE%Uwz&UxXjLeL}EJhxcS3E zirToj94ya%d$4=xe2;2_Wk=6BtX~W zUt&Hbc(8?=x?S^*NcFm_?anJ^Y@^ZLd(-=r3w|fWwTJQH_e(eLTUf;N+qaib!^PJ_ zxA!!&>Q`c-%h%}YwFPF>_l~QrmZrz8&f#lk9==tF-3R2QhNDKxiH4&#o3L3{u{%q6a9PY zKb;Qv+sBgtd73SopaKBNvMu^IZsltM0Y)($^XCJDCd{G*6t#l|oKS$l9v$;8RX#cHq5tJ+)Sy7>n;uIG*WMg?-+(!=hj z#p;S`8qtuM-TvUBVp5Gu3Sk$vq}1$m9>B#-ZTvJouRT+2$X(bC;dNAC_s5&b;jA$0 zkU75V#SNy6cFJhNP;=9Drn;xzmatg=GceHOX!*mV)Qt$~v)oi>!^38(R{QYjoq!4e+rXAx0BBC`ob?;ndfd{w%^iMEdJhRIr{ZRmfHsd z=fj_N+hrq|v%K<=#vgV_-1Z?qn%kC=N&E1MG>hA90yArq#`|MtmQ%Dir!m%UZ$CIH zT6k{PVb!JY_F`nhh~YT@a8&846&}&X#=H?TJH)`3x&=dK@SkaEi`+Mz$83k@x>oWH+CHBkw0}jQGN;;s$5i! zLW^8*fsPCrdw#94KZ_wS?5)Tpm^=cAP{PoX7VU!jK~sCQdU)H8vTwkaQFjGM*LM4~ zg9xxYM3K=@P28kRa@Si%g(dk+iER`KMImd0b=2B$COw!-aw%agUrI$bsNPCPdCaG;Gb$^&D%@ywE`%ArRVcDBnT+RP ztT91dR(SvC#lsIKQ@_v9(?Cm1ws{`b5tb6?lmTfREYF`$&UUbLxd%fn6{()l!A6HX zM@HjQ9vL-I(sHe_PI@%^c(2%e4=obExP~;f@qKZSR{JeV`|iqJ|4H0=@y~H3?ofZ@ zj%{ae<0r@-!qaW1G6p>lEhDpNb<0o#Qgz4(7;+|vf4C=KfdI(Q9WliDkCn~rw;jmu zNoJ_)@mSu^d7npKp0BQGuGhzCZhOR$VEp$r(d>@n`C$C-v(WwLOdjXu+uuH)AE?>x zU$LA~+)sgw(_23J5510GD<=X)416c5@3o~4=)`XvsEneR_mZTV=9+AJ#Z{Kc9wG?3&;~8=J};0(dS6cH z;dB`|Quzr(;V^6G+=C zgXv~e4$Pbb*0KkUKkPf!MHxJppgHOc$}%qr+sS=%#O^j$N(q zA{rm9C^>3$icE==vWW~o|r!-TrU**6{Md2A6Q?p7&jF`>%if37Cw%|7VZJ6#_!hHRph zV1Oqr%6d^Kn7|+uf?yb_r|lA4^4-+mYk09%sQJ;Q)hEIKoB8 zI{RQHIF!!sv}xt4exA zIevo~4n~vwg+kkC`oq*p@_Uk8fK$1HWKeH_4t3ysfX=XBO;kl1JIQyklKbw<|CFv8 z0W=VO@>7Obg6Uw6U9xEBWMu3NuSlQoF4?%+xYY8!RMS&Y3U~9Sf7H3~t=U_HSG-`aiBZAR&I?&U2iSYYe+gi93~PNq{S@imN7%)t{a)s# zH{Q6T!7kjKret?Mtk_b|W%DN)S@6o~9 zN1@(J*W<;e$CVMr<*kv#B&kUC$j#?oJ)FY9!r5;hNkmr~r!f4YSbJTiEsAIocI-MJ zPq7!w%Q;vibk!eMCaDjd{_c_|udHQB$QwkJI4AsH+o<-`n z`d>Gkes}NB%Y8_K_t#`d1G^|H@kPayU(Xv?0^ZLnW=Mi}JF(v8mao0z=kqsc5)sU< zFA#gPCUPmQ5fM&ApVLsE&kCCz?dJ*TkKi561nWd8j9c6sZ^OH&gQb2q!+Ap&R>9^K zZfPQPom06T$f);U&TnQ%jt30ZFZX$g3N1^V9=6KcTTjzyVM{E+ zKPi=4z0A(_1UMg3V+mj9Z|Vu9--neYa&;cUcmv&vJ*@ffOOK`o8)RaEs)8Q-^EyVX z$|qprbg@iTA4dwlH!@_(ZZWbQZ{c8E?}Eq2{YmT)A~DYyX8&=+7jLJ5-hC$Pm3Z+2(Xf-8 zd(;kgfg%ZSlSlz2MncT|J>bsaoM%nLY)v-?9u~}C5UzSATcz#d0Hx3xnPeEB5tcCK zwoWz<4Mq`ROk8~tCBN2KzX`c1{%@Rc%K-Szg+Bq(I7E#YJ`$+Jgjbs)f>ADF{_C*IY=A=WmPB;iv|MgjiHRp1~5j;)|@cm~1}To_15ekr2z3hjisPj#H`rgq&B^vol* zZ}SyFVZ8u|HXzBhy@huf#G#+Hh^O@cDAcj8e~gf`!C=7;w;`bcf<8+!&AD1m?Qed1 zQP-bAj&B!TpSfQ{U2okYdN0R`dSAnddT-D?z90DtTX!Kw3R`ZE_dfZ>ozADz1Ve;x z_aj4sPKTvau>x-k5oodFa(rArZ}uV9N>#4F3DY;FWs8-`W`>sri|qvO-z9Pd9FK-W z5=GsU&)ZHXl(AX5bOajOPN+EpvqY(nBcLPgyJ%SCVoQGr2lo>z73O5R=4w0*agmT( zW#Y4MjZ``jFiG@9BS^@iLyJL8q;ZfNF9;G95F%(%i zbPz4UONy#6kd}u_i2dq{@dx*qnW`P@IFz;Ws;Fh3ksfcVo75c`N=%as8^7NFC+bsJ z4+ZYmREQH)Rn;7({b0!I#S*2{pDpg)N{2~5ydZ3i@_X&quSyI`S+*qxd`$E}-ZQ*S zlVT%ZG&h5X1Mt;x2JEY6;pl~rwzohs;Y}54SdNsuo-6Y$(XbBgCDZv67)G0C9mcob z1gm(-N~*O0V@_mSn_tPlo!A$Jv<5ZshLVG+i`B^UH{l>7kqvexj zM8Zg@BqX*Qr>F}B;9aK|Aqfh%Fry*MlWA&4Embt>l%&(=&i?A2jf6BMg@~6~)5?YZ z3qi-BWs%aXfPr;SY_fzU2XCyx<5xM8^3<9$@B4@0#LET#ooqi9Qq2V7E0EY0D(P6b zw8FJ}!~YoiUCfXe8r!-1N1&SsIVz+f+okXrB^nE?ia2oO0mzvK?C5!aEIj*dUleE8 zswSDnh${qggJ3Xl^y2N^_Fy!U{f3f{6&wcHP3UW>BZ8Af9WELb+DX{pZPqek(({BAs^* zo(JZGtHB!jB-}0LK1*HarQAMXU+K7AkXcD?KAFY6e5`!D#3C>K@~y6Tzwh$7qGR4X z`+WL9se5Dn`V3mqzEe~6y+jMSvRpdF!0p{)-E`}EJH>k#1YU`Y2`;-=&iZvzIaAILz66M{O*hWKA+Y;45FWi3U$GR%z4Yg}?C!s0h!^*ZMqZ?Zz7rIHIK9k3DHN*;#4w1B0|LpGBvI|-rDN&wQ z7VUvl5n_?NCy2_%jgk8ET#ZTwN)S9ToJ#;3rt&}J9V4_Z@|AEOk?VHho^Uo-a}rx% zXVm+VY|gI4_6PRwf**%=MG?@4Pn&LA9hsd78d#=>MFO|+NFmq1sP~`TmuMFf)@%el zZq>T6Lh4^KLqZ-FnM$MZ+b2w&x_?UrV597+$s>uk98W zMmYWh#FRJy`f&kWI4NA36P?K@0KTa+gh7lM3dKH@g_m%B8J6Ai?9Y-BpgXM}QWUdR zBs>cTt{v(R1Vqo+gX(cnY%xbGBO`SSb*Q^T;z@u$pH;64eXqR<44S)fYI1}UC-$U4 z4ti5ObQM)QmGa*m%W$_{;9*Z@xW^oT z%Pgi8uTYciUIGh5fwkW4#XyIySlSRD(}8Vy34~(-VjO1`WtSZtv=}YvLWkQvL4XL)4A@!%&$ zJTf)Y)THNTC%J9Uz%h7)Ulo*|oq5>>c?A^?r&w-aSfUMmCu}pB-EerA8O)~cA`}^Y zLtzvmaDu-q3&jvZ;MbCG+cg_33TbHgC#eQs_PH4adI#iZ49wr{hn!L(a%TIG5K=pz zqp_;53H(@Jmk$o$K7#d%pzkFNK1g9@^jcSE_auPbP7 zvG~Bdb04R$#G$pU>qu*<^%Sc9of#jzsnuRxit%s{?()^Ks&o@8k1| zm+8@!UV~uEHXo6~E4Od{5dHpWIl`$oY2#v1uOpFKlUF$IQ%>pE!H=Re5{ac% z*P3Xzkzxt4Rv{T_3Ifaxq{u`O2+`K}|J*nQrkX5S%u1;iXQVqd9&4Ko1-X+WYq4lw z6Rz8f3G;_miTRUm4f`p>(}>X!#OdUH0F*;UTBW=nd_ftl?z;#@t?8Z(Q8(mQi) ziaFGYS}~;Q!a?|qfXA1MTY1+}6nZ)4F%~qnb^gNvYiG(Eg#82GyeRazqhAhfS9KKz zQ;pKpD2JD#aYL@1*)rGBzRh&mH$-;~v3Wy2{Hy&;CZWeBW4obj)sDromZS()+dY$1 zy|Uz9D{v98?-;GX8BCAQ%HKX(=w4}hKf`FVZL+OW{jkjuz4|n0dN74K#oNbquJBeRGiDBr^5Dm@~8^$P`lZ`6~FA{R54&e((IOmAG1{C^G%2cM(G zVjpNA|Lt?lalg6?rf7E9FS8z8vVAAouA%)c3N74+Jgq2w&*`87YwSL3DsT&>NZ4I208Q3(=3qfYuR{e{}MTi_ttqgmHBWD zz{Tek{BpW-KN@THTGQHWQ&2akRd`OC6e4(@{$n^s&>&0pmd~&+bt(tKS0uIy<<23{VvuT9CKz^~W(2yh zGpS`ppJQV7669>}LUx`q?V~0A4#m{JQ5Z|E`Xd>SO@D$@2*73#yP_5k;~ZCKZd|=m z25bV70LJq!^H82{YNeQWSFaaaDQ?mtq5M9($LaBjFSAWU%{R%w%lnr_nS*R+R~htl zZ^pOtykZH7sYAFG&-`^8&Lh*}T!DKo%==BB{pYEnXuR32&xP>oS`pCb^f^y#i4eB^ zFbWUU!GcNFpIyA(B=OANIv^XY4%7V*3ZUpN0`{77vuSUrao7+wi}CTE@Z&+LY?^jMr0_*(M$d% zpUC(AT7%SpZjn-{6(Q1TL6b==0A}R+W<8RLg}c^q@gQB&j)_xq2NI*-DNQh_a_~nJ zGW1~#gwKk83-;es5m7>uDsr$jcA|y5TQ;d0DD+pMsZvooHHTsHzWG6N9?jNUghJ(>Gp9 zFfBJ6%$Fa+`WKYP7C*V?Wv`n(9zo=_s!h_Txb=)jHLMDLGj|q#87B;Dij%ODX`4{uJh^40hnX1W{j$|Ek zn>E^q7jI_)v>b)d^N|`dTut~FtRMleX*(o$>&^+WsZjoHm*96qL2|xF^WmHro>3Yv zD$a@X;Lll!FlD3%l(JnLicxj@mZ+2$1G8k{y)|UGX)U z!^4;ueI7HJ9HIPf>?m_u_tV*%f@XD{%SOfw2F>$-=|hI$g&r}-Jk;+)ZfKvVW=F5@ zMI~N&Y;^%4k3QZGy52#C^Q$Ab>*M52z~T5)f$wcwkHGi%(TwQ1-w6q%K8bEQK9^QT zR77d`KJKRHJu5d*heL!e@>^HnwQ_U{A<3=zngyyB2 zL);n7`hU7~x2eC7Yj8yW8Y5APTTZZx;wx&qR!=ZY%2hyG$ z!beD2{m|V@Cp3U*ALnjd-JatP9saqDNPu!*R-h(UnTM-0@ZOu>OJPW$*M?;&#Y_1; zzSSsmWR{qY037EGLA7$!Gir&pAgla#gkG$FRiNJJOpCxTV&zmS8L~^+K$$^cXaqs- z>LEI(ks!0Yl#0DWoyrQ^{0`QLtWfno9^r}?Zw@o<0)i>F_Y`SL(!~}P zIzeB6wHOw{h`;l5koV8%xUH{Q;F2Z)37VJw5SF6pLGW&S=wfEjFJ> zttWsKvFMC_Q_Bu0q@oADlrTcnf4O$KT_ygZ>+rI&)xHN@4Y?m9xa#?McU$&(yYha? zDE}B8Wytm1nfQ;px5U~%_=|Np{sBb4TwdCGOyLhXbI9K5($e>R7f-x|H*H@UV>HHJ zpZd=ce*SQs;Lz0$D+{{3H1TwgKe?LqX?VdaMQ9uS*JmLoRNV)wH=S`Br<(8JF;Qd%a?AM*H>q-P9zLtb$x@vlfP2d^X}+1lo}4p(zL78R!H>tjBo_j)uXPa&Rlj z$3?T5o;zQ{+iDWQ-hHuZJ1B9IWbSnIH6>42J=H^G9(}QYReZCQ1$vJYeV&HAP-R&m zjko@nKzS7t(5ajTI5pL(Q&v3ol{p+8_pjLR3OgQ^quo8puH|TJ0=>LHcRWPdylJt4 zZmXZe5KCxS>u#|V0$f*-7O6S9cYO6b9)>Wu&hmp!GQ814Mfk(PRv!V}VfBle77sbj z)v>{7EJkjHQUW{Lg3ZZ2-~)ZE>P?tweeZNE*2OroNkMopUkyZB5oE+%NdpN3zdI!C zr6t*Rbc7HNG}GvCwO4K-SaY6Z1eJU55Gs~?9T%qMvze1&q!6S~<>TWmX;iCGU=7g_ zp}|OK)MI;KlP;B1Ompa^UBeAUpkHhR5Fr&S}&Yf)yx*~GRi+$zXIF%UF= zk&d-c8{ivCZ0t+s{(A99Ob`Zuq4JxZ^Er69fT|r{RymJiwQm)WnshuTV$=ynDd(fo zi0D!uV0G@(4(dePn6XC{WVt3M#2C)1N^&*r#c&xQL0xb))nGKe@pD`a?!IR5 zZ|n4bJYx3-UZj_h;WeA(H_7(LBl6ZMmY8hC008FGg!iEJ{wR_!Z`$)=Yi`3}GF&hr z;#>K34e3?4-Mgj%k38p$82l@U;sKj5)kd0R2pkBoK8S!Fg)v?->vO&?b~-Xj*t?7* z0@L1Ejd@tLTRM(LXiH33@05tiu@DamK?;+@{cIYGH*x|#OK`%@_WRbZ)|xM>maojm z+8$L&Q)n15KPcpwh~L|Bzrx&Uhn01UfKrW1BW;x_{JA8XUT?X+=SE$w2=i}lBX3(@ zvv;g z5^8FQmAr(S*`CfOhsNEU7&2K%gM&BwlGKkQM=^dc>ktz4JLa6$2W6G&Iw#Y*;<#I* zzPB&R*YKMzwy!ZpW@b$?Sg5>2-n*@WpQj>WOSN}1LS$dkb zak2Dmg4g{!UZysBJe)6PNc=90DVi7eIrh~b3-O6=dTAfG%i~@|?%r%!{#d1bRi>^=Gc`@(AykiA3xBm+jfL>uc-0iG(3gb@*p? z*>Lll<&#oOOZdvXcU-}oi-7VTD}QOlSrQ<@L?Hh7wV9_AtV6|QF4?pwPCA9vLhO>( zQ|;_&+SM$`R&4_7`Iv)XbXvXrYz4|&jwk#|AEBuq_TiyeRdorIpz4HT>V2@tX@uo0 ziUEqY1T&J?wo0Ee=vs9tw!~{hKcPQTmQP{eCwUHK(1|YdLZ78~Sx>R2qtJZDwlsLY zs&Rgrlv!5Zb!gnBByX0c;@>9g2JqHWM9qYm<8Tj6nidf5;UEGS_3un%VQ|s0lR7hCRpNKOw3`(|HF-P9Y`Dc}T$)AsKw8g)2I# z51Zi*xhjjW<$R`9qf?|1W+132NFsM)7Q>1prR;t?rZ1c(%mm5@hHFYJt$hA_D&pLN z>_mSra%uM@fc?B5+H|ICQIiY`YZUfpScD!9xZiYh{EZ;5p8{XD-NV3z^OFG`8$9c^ zGboI##Y$2L%=8=QhWFS+^LaABF^wcG@rN_4tA3Szq7<14W?n?diw(+X0K75|y9rJA zes`Id$)STj77fv|n9cub+*9|Z)ePu_2Itmm%G&0w>b{(vf6+gzV6D0nw=$gcJV zLPWf+&w#5w8hbuVz|K8P9lbEuiU94{Gi!Md1IKnj#ZGzGiBqU2RwaR&s8ybtw~Y%; z6e&=1!u`j&n3Hmg&LFnZtN$NGHjSVp=?YC1NE@Hjd8Py&4dv7yx8u@!ruW|~5j+9Q z5fVy`o{EGG2L@Vf8A+-%PRTiG69Yy(p?MaO*oCg!+vkt zdRY1v3|2N4(@Ad+F?D^X6vy56sUe^6Ot)<$wiLZsP^&cygy>~2ziQ$~I*CV>V&T!2 zM^BZAw^1NoXA1+WMtED#+sw$CFqGLNFo)%fUmq?h=vFWD${JQpis2e-Ea^Gh$`O8+ zT~1R&*)+u%d0z zD)P$Z%c1AKNrWFk-k!8g-!#p6lEBie%wHcm6;hXjcvZn>v^ub2c%x1Xk~uxw`(8Ol z&EprVd3W!(a4KgoGCp)HRF~sf$dP~5Gu$W{tK=)h6v37{eA?H!T6fV^hOX;f*zhgA zdCu9$Dxv{plGv;CF@5fnV=UNI|MH2U=m^FWAESjU8@q*(wfciD&Gk``K$qC8wA{-= zQ-SW8lsv{<$%xfeA!Ek>{NoJUr@uQvKW5(=-lh31Ug<^ZUrHj6g^rTvJHJru(mi#gQY|VJEp0Ddb0=ki#Zg$o^tOKYG(b@}8@W<=cFiSSe<*$>D6m zw;U)qtK^xWR)Z1_Akh)4VTwEjd8!{aCx^cjyIru9M1XzVipjX6f6j98!rL{LE50Ufyydhl?fS~9<&+f6Ecvz7G7;OqcPFgQ?vQ!i$r==b zj0IHv_XSBg$!^w~CxLN1Qxuda?AMclmIj@L9);%0k$2L*s+&0~#9h!XSc<-z!U0nb z4w*{dvNgClnU1!(7z*>M(B}W{j*xs#!&NExco}~&IeMlp|IVO>RX27BfPs;XD}Kj6 zG2_YnW7V-{KY#mpJ86V9*?!c)gaz@rA^6@H%m2DCh3|6?N0s~eI$T>Fga0v`E~3YE zH-0oJa94OYwc)XItX34`=kht8FQYufe?}(sUgLMdGPQ0r8Df@o>7;HfkgPSXCjT7K z<^EhMQl5Ef>s6)eIT^OWX(UJ(K545)=vMLhFyh4G!&!9UdpmqmthTrjec8bp1A>51 zKd{;xoTu)0e{h7QqU^qJvr0^E@>*zBIbUWseH<7~y^^D--9Pa^_s2(ftMj=Wy^Opa z;tMEdjbiy-!MWwalH{a33BKQ_4pE7tMF1(yK&GxQM)>SzVBtyNy5BM?@bQX|(`jm+ zbdZK+!vBbrmae7WBb^X1#nE?xf@uxbgV%AXO~<(y9y?EJR`#5Z?@No$(}CO z6xsa3BX~!Jy=W?u=}+}*LA!tM}%bfa_duUYvQXW1p6D&;x`8sxL2_%jV$~4 z>3=SW^y3H6FN_#sZ2JEYMnCue5Jn`3Vi?1hKU`uH8HIkS|2;+G+r+zizF$CILkO#S zwf>^GeOmKb`+5N`>HAf;yzl1be0?8^y00Ab()sKZM0MSIftu2G%GPu60NJzy+2}anp8M!{ zh}9=31hB)XENLn|K%i<-a_qHct6%|vn~kei#IsPcbfu$BviMPWQ9=AqefyKK@-g$T zQc-f%iD+;n?88*vD9EwA3R2;=5my6E^_oyN2G8 ziR=ylx+Mk-azp5rOY!0TBDB+K+lJ!eQ<+OU4Tdv04I=g^V#&YDyhh#L&Yh7&) ze)6l3l*Z8rMO%|7=c30d6>JMY=*>VQ0JFCOmnLoow!=hQ{JkI&WzKbPm3i`{HU|CH ztTtLSNrf0K`1jv`#1ii8gQbenByD_~2E7adst4hcG&RV#3htnsX<7RlmE*H39lfw1 zJGv3wY+AnoYS1h`5h!&{aaLMzDFRM5I>-+!CM+wlp)(lfkV{VIBEHTBwEEi_54idA zx1@9{v%^n83~qFyJ$C=y5&mRbMye8s<2lf8<-i;`$JQm8hL zywN67z1#@UVbH=yqzq$M3UD);0Y>b4t6jLRTWyizpOnXkm%}8-OY+SEscgoq~5erk81*eX^oq^%zF5f?t z=qOHOW@{`-HamE4Xkn$%d>cz1-!^X2O+}NOhSb;4t;R;)N;Ed5P^~>~bh-@8nJA%GGfHcj;vru*bc0=urIC zF1SOzI3n`@U(hhE~O%2zc5Rft&Oy!YpDP zcteKe! z`ml~qxq!^_KcBY|W(v>wRDtn=pQ|E%w+~^0H|rxv0>00QQ`s4^`#JU%J~!tO3b9a8 zPqIv#oHkF+D`_0vGgm}`VPwTx=`I=Yj)viAH+1UElX=JbP#OYiu{l-SM$ymilq^EV z-uMS-7ED_nbt0W4cbwN5o?EU=m`DZz(Q$tDY2(w{8zqCTV~RoL!=4fgK=E9qw*rpi z3ui!WeDorbQCk)o7a1m!@7jST|h(ed#DcjO>js>-CZ3QJ9rroxUn`hnsy6c_ zF7u{g>xB?miOswPL#JLkTxv>y&TF&YxHp)W&U|}sfR!f9_>8Vf~4XCZ{_8@ z2C#;>3lx&X98xJmozj9*HnJtj(uNHgMes}Tj4OX1|h9aR2gI^>Y;JgHnb6IEENOweCI83V&EL4s# z@GWfF^x;xq`)$^xB-tMyZfOIHtI_e-ckltQOxq94k{<{?r7CmU>!hi6@gMoY9-fIW zFG%=yoiCVd+{}L9n{Ho=G)bMGW!1hFO2ZP43+rGs`Sl%onKQxNf4FMkhJFA`ZvRiJ zKu|~M1t3>uqC=IT%c@nK+OzSZlWViNYY$S#55=Th)ejjc_!P0ue!WFUXV0P>!DhLuPJj%lFkISoTqT>AoztSkg?&2$_D5#W7cCs#>HnNG|UNcuuoS z`#LlS7u|QT3J55OGzCV%>56J;^s*0KCLUZ zV8_O^Xd6hDH}QUg;ekZJtmwp}7qm8ETptPlF)Os(BKHEZSY_e;+VS0*ugK2~zzq5; zd##@0D?-1j^>yEO_H(DcyoNDFP3BR;+}#}9gIL)Tt2~lEZKdR>HnwRGxk8nYOFUs& zR6kcd13EwT4Fnic%4-=m{)M8{lN5=68}QsS#-_a4EAno21G0_oTB(jojV>|V0U?6# z`*(hxSNVPq>!pc#>c8Sd>e^N=!A-&P9x9n9xJyr8JiQBW3Co8lGfP8kH<^BxThEQL z1RDqM9&`&+V~>WIAT(bSD@G`Kb78~%ZT(0jB-MzL`VoxmARVl1)E;1`QoB&uO?sJo z>m{MeN0q%fXM1&wdpIEqRGLmid~NRgE3Dpt1PCM>j?gsYJ+roow()4u^*>1AjfRUZ z0IJJ&V+O0*G@FR7_5hsL}~{T%~`BgjE}x7tzT$QAMAn`O2r*B(No6q z<+!l>sM?g!y~kG;iM#O>HPC;IqjCQaEhBhNiVdZst4XVkxswF=3mVn_gd8&CTk-sqBE%b}2Npan*t# z8FzUfnK=n;yhJ61u+1Q@Tj8(NSC&RZqlKs)3->Y*mdyo3ctF@Zm@4184ha8==b9h= zo0TbU(CUG{JSM8}`$^BSBxIL9p580HxeHmLh| zN@^|N`W*Ts=$*v?Zl~ALR&^C;FQNE^Ig6BBXGB@#bwB8@j^;aHOg5!wqUSD@hUAOCbVN8F0 zKh|%&hU5hVSU>N3@0A}%B&_$ICSupS+&^~;BcM{L2-UOQXS>`v2-8L=V+Q!b_{PH4 z%bPBCh0EL>e+c6Jl`ClOvOio8BNS|3KYfLONo{~S%zBcg&*~>dV&uBab?a{+8BQH4 zBFb`Ffo*&<%Z7$nWPHUw=+t-%xcCfW*ve2JXDC!%Sqt$GqM8e3}tNd;P z4$7yAVkOtX9Uay~2Up*-)ifP(^)GM2^g+|q5QYyyc|KC~$f>KX+=yV8*p zL(gl+X&&Xq;oZ)8k)6-LkL3smwL#SwDbGUp=UuOj^(8dMKjbMhZ;~xo|Pv{RV1nZgVJvP**Aps zG*HoMI9(J3Ay!JPp2c568d7)Gp=~UnT2_#2fQF{n`7! z*5>0u=W5$c{h7%_fk~}y+DI`$-$!euds0ioaa;08NyFRzEg;Wa$KfJkcW!}qy?{o4 zu4guapE`?qoSlU7e&=${m$kpvpI?1yuy2LBcZ6RdB?FouzH8ww($L%5wcNODr^Fw1 z!rX9bY!bY<+<)oD92}DLq0%7~+KcLLS?`Ed+qJ!aDF5HimHB6rw?1gRrwjL=d-@-u zq1oug4hvs}=1n{7QsedDZkLteiDL5h*sS+N^#%8*QxMp7{T8bm^sRIEHYV1lW1ew% zjEJesFfzH*b_qwt<6;FwWbiI&?|^!=c4BkffxY&rORl`oh=jib6^jcTfg1FcA$1CWF`Jbv=*4G~W!Z2?Y&oA} zW{Us%DzLXTXxoLmXjapC7OOB46T3T*)!`1?6{Ez>*adZ?>WFAv{(G+I@jrdSF_O&p zR-b*!bnMFir@!A+(CpqAu$%OD%&Vs!`~=0{v6bAwNY~h+tD*xJF=YA-rEv2^fQ6_R zH@R{^5vxgy^W#J3z-~S6^RXJUvvn}4g*aq-(d=&&U=Vj)Jt)gE@h&^1a;$}BrLRne z-=eC|AOTr5I-IAQf-D$diy+KmFZED=?pTbuY5O`^i9)bA#sZi9u1@CANr-1hj>!{J z>S|e+Ugsv`E7k9PvMtT0O#&lz3qrxxevs_CvnBq0NK4}jr=70AOn!}zL0^@9kx=s{ zD-Ym?w|O{(hcXO_)*b3&=3+u721I(y_C%A<7*D4tw<9ObhyUz$M?o`@RpM~BP0s(( zj!Z$JP(-*&3l)LC>sJ$U?aV-L$^7U)Y+XYRO>VETY&^nVwr8Xfm`aL{Ho!L{%s5IT zB;N}T{%Ht?me7Jw#i|tL$u$e+0V4%1#g{j{LyMDki&7d2;kc6}8ji|%lh!|e${VYv zxl)Y#Jie9Vb$&Y)t$;GDEbk#10Lg# zF@TB=xGGrL4pOF)brH?NM98ews`lz!jVn0AqSQ5-Ss3+mj)#1y+J9z#;cJeNn=SV# z$=$d9WH3>f*&#D!yHxyXA33P-n*^==AqNm4#o_~UHgXb_X$6_1ZJ8|1vrRS?D~qZd z6YsEpd(HdYFDxxo#pt^k2_BC4a`_hfkf%hJ-uNt8;VU(suc8c70uizKrS{_7bMAw< zowMbd5b#K$Cv%GWqAW-Dl{fpUQTlE-YaOkz-%mMBQIOv`%|1`Hiiui|v6J@*+vEbL|H^Wvn)>D z3lHnByJ%zePfXE*bsQhZhv)g5t!Bbib1>G{ybk2Gu3WW`4NfKoz;p9ILqBig?VTAF zxq`&D9!_`#KhGnMI6jUHwQ{{L`?JlcFkLN&KH>%2-ab)CVQwYdHvIU|VWd_&<{pvw zeV0?JfotQebUA`Aw;#o-;lzcX4>xyD@+&D;*+bc5pa|+Q+#X0v#Or)t!n9rG*6C^R z*{2}j_7mGzf93^`sC5sW@X={j0*TW}9vd8l?&xv#N!&n00KhRR^#=yDCad)FJsl}|qK~XNClv0|goxL2B zgeSzQp9;FWUWdS4^UzuPuZasLpxRQFmLgzfj22_pkjzUe|LsSHk(PxY`T0G^=~|YO z*}f$sUhJF5fpwGSa)bw%PTuhFgE7|HDP+bj2hCBrcBCq8-6|eDN?ve59#%C6ak2o- zX=PIbnvEB8;v+VqwPPt5Ij8wbt4?RN^xK&uQ5I7B7kf=%^^KH*ZS(W5PF=V5Klcc z_#lkvwi1ppYf=RXW#gLBB9lg=Ziw1lZ>WpUIDGhH1JFHQ!sP_e*47ZcAv`^0sG0&g(y}spMmg?Px*g~S>{7!h_KTYDjTy6k;E?gSht`N9-XP& zf9qTS!4)873fNdm(7DUU5v>JBod3h}apppJ1>#!?eytt1Uac{Xf8TV4@P_l05MLU8;bAnKz(2%02yfpZxOK$*_8h9J6sdwtK(H1r9QvE|1||MITM-fu!hp z^GWyV?49TAW<55-|NYDm3s?AM$*28)+C#kpQT!wNqFQ8cQ@^rKXJh0b;p7ij0&ECf zdIfz0MgB&-n|k49#l92h$o5p|-opa%-FR9VY)GXuM?1z7IA_Xx>3B?m@?cFdf~0s= zqGM@s5_sV_bh0OR?yZDFnA=zot95xF7JCD6eKW$b3&BR6OB*U!)qqkv) zugL3Kv+36(JwG`)hT_Vtv?MYZ>BSBW(@>S;1xC?9k=B^@7~Oq}g>O~g4)g)KZ2w%i zq`3O5qK+br!_Pq&194$$`=(lkCS0Gd-oM^&>WDo_)|Q8#gKmm zlAaw%a;n@pWu@ll8A=Azkp-KCP$vdh=v4rTPN~Dlea9vFt^=I}pP%6TSa0qNCsuqX zP3A8^!K`8EKTT?T46zN&rgMXF#gUezCX9tB=s-F8WgE6E@d*R}i~$HmC%g#?gxVjx z&gR93N>4umCW2R8S-IV~TVzdBRwA8vZMC#&-}uLjR~XW%sla&7%%iyBs@Th>xts^9 zlClnM9pxJlUl1D&6P;Ya&xONg9-TpzA6qvsmz^x0DHqQeij^sH|(Zq=tJ? z=xECUd}yU2dQE(KU$ctaDnEGoIs)AvUZEn)Ch)U&y{{TE(#zp>qTNV$@ zEDkJ>wVC8UP4^+y_xic-&Qa(5^CEMULLn?XKlo_4=&Ds^Yee$+UjA5CfK5@3S2KFX z`P3lu?XotVS7NY>L%@p`Tc>zgE>e&n#?Qubr^jQd)qHS@R_g=nJmhfiv5`vKs>*Xr z21ZYi-RbFg+_Bcll8lc~8iJ?SnbwUlhq%F46p!x;VFIh1WW-)oYpTN9`=j^$2bQ(p z<96Z@rwBF~JvwL=uyT`M;I6yDhde2q8hE!>h(fw^lvLB?#h635H44e?LIeT1qCYHF z$2K=2%a+Jm`8Tu7h!Xklol+dyJN=o-@qwooM^0|U(R3d*3!XMFx#P8NV87om-u2>Z z;l-!-0$xdL&`R=w32*$Wtk}oELo&}HO)+b$JpftZaTqm!-aUU5M@f2QquAZ zykjU0b*dr2jUEnsV49c6vgO(vGm2_r;_PH_MCrzh_6Y1+8WBT(QElFsc)!t(!)|iK<1AdD;;hQUJ+{v@F^wLRk3<>el7EnUiJw}a7ffr8P3wz5B zse`sAR?rO%CO%v}ZJ~nQR_~?A205=!&7Sdst9F4j(Bt1^9_TVnl<@IguhJ$qI<~WC ze-5haW!8lnJ>VDEVK-(Q92ks@ZRbHW<}%#pYf*>K?)cOJ@%Pr>@KIXkFj>tHJ4n)L zxnMmsEjDye+FZx}yjxGN=DzlY^S3vuod>shWN{`FKjIA1Y|@;f_)VP34A{ZA|IZ9T z2+93_{(;>B3!kDzNxdgf3qr>}d)v7>NGA?!2u`eWF-je8YU_H>PE5{64-^w!8ZB-6 zSBJiz`?c@k0=N3yXWSpl&Qk$JpAj2Vf=^%Tz7r}w?EBe%P1m40BdX2N%fS!c`h~WG zMXgG}nQOLzFC42@6c$*2LFn@gsEXo$(EP2SE->Y6T`!FCV@DS_e&Z5jrSzv&af`8l zb;X_yFRF;tof4OZ{O5yk-W(AgdERDyb<~cb=CQG@Ef9yfR4S#FsC6*l|#JfdB2wb0ilh4#l zB%ibZoBPpi9LESC;=H*Wk*9`u36i083q3m2{0~hfxjBK!FIedya<_~HcRDOzzPXm3 z_x4x1OVYy_R5?r(vT!BnolI*G1F*WOKj_x8mwRi7NLqso zKMwH@;>PepTS?vZ@rInZnh0Pok+m=Y(-gGEC9`DI5!)()LyU9moH}>*`#%>lY>pPw zb^Z5P6cH(4F^&L^{8n1zmkyd zOaloZu}})|ka1)Uy}>T_umu&oG)Bh&8~eiT!EmS~&@-~6Dd8wOs8~tFO#hHgWA2IP z({zf5zr`+x1yRz}M1Z-0q2;s~BWInXz0?OSFLiQv#eVr7WU@*yLSjCUg6X1!uGw3L zzc0ZK=**VOPpnz9o2z7eeSj47(zq#P~jnUATxn|z_wn32(C((a8 zO%>l=x~Q`#*(}dfj^kxMcd5~6SFyr>7Q^5jLCZix4UXN@Nxg{i03M@SPl>9@VWfY? z*cjm%PMQ=2%>m*jrfa8l(bMTLC!HcZxS<+}outPn=|Uh1xj-j2q+7)b4b^B(-G82P zCu!bvO~r5K^MBnHd`Y??HTYDW@sEj{9T3z2$FZhkTp{6GEsO7}Oed3NcmR1~T~JcP zc3UyPhbEm$;{Qk2JA_BVcH!3D>Dabyb*zqU+qTV0(y?uKY}@YGwrwYW_4{4tzs}@L zYLrn8vTN^W-Ro9=5kXyc%Y?=!`>}Yk01}l`cnyVWo5>?2CfYKRn91grAk;o2Be4Qj zWSV6$MS!2j~e;(ZPv&r;H*Gsc0 zw&vz037AfpYx?zC|MlV){GdCCv)xI>Z^CNuwm|v}& zez1Cc7*BX`)qGLy+2qcbqRsqE+i}2Mi@Rjb-?(Y-{dG%=T+N{hg zV_cpSjcgZXO<75Yj)B?*o*B4!h+xw4$)|WDQ1*uWh~7L$M?o_2dNw~fss|_+@K#+- z#z2c9R$&)&^COY>QGd||38%?7%7i0GXezHgICfO3rcotMB5L{BAMxI;sR$}F3aDRA zUvjmsAA3*{{khl${H}FW7sN&St~$g)1|kf%5mhyS%`6LZ09_z~uM*HcY^Fx~1!mj$_3 z(AN&NlesSmcyt1{prv($L;cHre&ZRnR1VPH3$kq1u}yT$k`-WTdyQ56tz$8*C{u#r znCL4ueFm7F4PhZRBXDgLaAPct+Q9D+$7&?Lx8iM8H$;{|?w>uoBy0Ea^;|Kl*VhYr z_oaZ&yx7T9Oo&odo2b{+05sQb7A8Sc9bv*ni>Q{DeXtcJp9*pb1z#r*a?~yf*3<$e z7WtJEJSbK5E3jxmH?}U`_K_LlEXSl=0k~*k1%Ds(jab*UA%ekkk{Xh2V-vN5W~npy z3lX`B&v=E5go|j(=v1yOJ*R|2yr_3uiX#Q4g8ZK#2_9oG7{cp>bubBZ^qllMDqtBL zI>fWEcx$68%edT-Zf3eEMfKLhk@P-JQ;;I9CawQrKoSR?3zjRkW$^tLJUSEu zvo80WrKX8$^h@5Ej2)v+*Fh!G&2RQDhpC7w?%V$YP_ce8C#)wQN>V84-CV<&bh!VR zaS`})U8*+nPCrYFfB)ZsYmP{(?mtdp81(y+g@>y6Rddr;Vv>`~znIj!?!_gImg8O= zu*E3k81uu3sG1GB|D=-iV{dQnIH|Pj6zTwn_8vSKzLMX3o%-BcaP2O>0YoSH zzgtOGOI+n>rZeDO#guHYcO97dohr?jSwvYz zOpT{{G0RM5&Z}v|WEr7|V^ceg+$>Q#Z@rJg$8)?K=>d?T7aKRxVAt?}_>fBHyC&#qPI{>NivpL3!<|8^1B&57!u`tmwOop_* zSAET`E!#r~d**w$pBBuZ>RxA7U^z%7{>(ubTSRjz;UKsOk|v{q+UQgmpYC;dWQbV@ z?$uFHlqkkp6`0}ye}jK(0Wd22)k3iyZm1qza^Hc6T<&_qCE=`|KOC&VM2j6%0uD;w z17)DmpIi`dpkA|l>+~0V=^?B^uaMUe10|J^f$%*g0rC#VHS!2jH`2P8n2Be-NdFvj z*n`6{f#e5B1WX_H26Wi8))0eyYLCF4aO)nyRwPybT;MWBH)|_!9(~}zP`DwzF!X6X zti~&d;lhXJe>cd2bP=Jf3G1hJfzZ%}1;bs_vW?PKT$9qYlCaB9)$2T%&7kM7j5Ti+ zcn&X*Z4eU@xBrVjbPg*1O%~6g4+&oI(6A?hIN~Rh8PiFbnYQ#y@H3euxorf%K&Ao( z?0q$Hwj#0KRa~g3#E3OSGfONJD$Rk2b8LuKaa*KPe<_^uT#a^OgxfWN1jI7SXm8Kk zQgS^lX~x#t$#JtP5h;97&j}+g3m2mD$67{j3}j!qYy<&(KRSaPT~ZN^;b3OpQ4L9?OjqJNYO010-32B2C^v@Kquc4$#$$1 zK?pqFD>g|L!Hg}E{634`S&4y*_EGlxG`hV*P-h`&>24 z_B+2^NpPFU?(q7&=Z$tkXr;i{&GIz2xnaC61zpPjd4Z>m4lD+k1GccCltqr?zRCzH36%*` z#-|it7<+`3d4Z7^QX<(PCfti>2jP&dBIPUkb&ALeqfm6_&4~A@SXtL}x>QL~Itu@U zT)+&Y=<+r=oxCY!h?Mm{+z(9&08jHD2vQ-7c6GotME3kk65j;z7H)~Tni9!aDD#f- z;cWc-M}K+$a4mlFjT0`9`85j|r$y9d#oRtupgA#mb9utfxn}(j26P5F+iM+!rN`?m zxT?;{Mts})MF#a8%Urq*F6GjV5w}$`ccQtCc=?Hk@z%U$!3J<4=jDiqb`vuDhJ1TaDy_$y~+zxnlH6YcWu|02UA&t6D?XFX`ehW=lbT`?>{)u=S#$QGED7iStJPHhp zM$&s6-Xh2=CwCF4k7RR}Hb;7?U_m%@<7%*2c_Y@v$HEc*KSJB&=P(n1)QlOTnpE?u zVeT$q;CPlI-HMKh=FH|A>_Z?$i3W`x$`xtVswRIGFjK2oPm$!&Se5s@W!o)RFmVq% zyKEG&-0w$ZGddW-EYz6exm%l-7B;@cNZ*}1V||o2OwiDJs4Rmj+@O);H5jn7iNAn* z-$;q{`hN6lpZLTt`Q`Ro&~Zuy!jRUr|CN>HEL3s<-6`RDtv;ga^0nvm}&$up~~LP(wxgWW#^ zldg}}=5^H<2wCzWkXNwtytA1G|La+~SK0j0q5`ABqV@ah3C9EMLQ}-v5)a|h?0Jj& ze@U!2*PT)zC$A}PLe1?VS^^~+s6vyenF80)jabgorYOL?I#yE&Ct<`72l1Y}8aqXg zJ&;Ve?<1F}l9w86v)S|p`6}PCeCuLU*1_%gFyt<%hTxH7u z1lZ<+(NX(6mzeD>@2@FMbNHsT9ya7WNr;qz*nv0B$%S$VP^2jqkh|ULP9*ggZMxMM-*z>F*HTyw;nzUqHIuvq(3r9D?0k< z+YO$bInJF4NQQ+qC%Szw6NMnJ&(YGy(Nds0d@-uvtPe}XUEL@~Z^rjYLGf6@%>AR~ z+;7E(=H)?;=`c3c#Fu-0&})4_L_8sMSuHm22NAsR00%rhBoXCKAG}}yj7Pp^f4fd( zQLSoJ33{GM4*#xwE9vGw44cBXq8o_Q##0o=3jw}&FDLV|U?d#*b$F;xV_R#v)`kts z#s@mGIAxRxuwN{lzO!?H9k_$RwPJIck)2hT>O54Gw^B@cE^5efJ3@(Z?S}3>`cGXx zal{*lG4G0p;FZ=G(VU0wM4OKw4H0g2p|~~F(bv`$vZv(w%%jk3W7wRV4tAy^bsd0l z{-QaO_pecHqJazmoA795Br2TB2)%I9*{VqVY2g<^4y~=3sE}E)0&n;oNEHw&?LGn& zYf8yDxTa;@SVI(>OQ#7fQ7#BWcI~BHVlx%~G#{1_`>WT=;It?^l+3ne9t1 zpQ8^iB;TJ5{(hjE`cWTqAnRn%kPqL@7-3Dt-4ESqOwHI_)n;C~Px|ph@is?Ci8c>0 zYaQLr)SK)|lR38`bLquQHr3ms0AK!wm9CdXRXBh5==D;}j9d3JJbHt4_T}0jFSXLI zU+}dkaK?$xcNA~zu<@Lns`Gg8_{R*^n}t0i<@lx9a+NT95*w$IuN=e-&7cnz#UN3H@G7I918(HuN_a^Im>~5yH?~4AGh7rk|aN9r-tl_%e);GunZ!hH%|0 z=entko7%yqbOTt-0=>xc;A$Ww`TK@S;%cqJQBrY=o5yYtKG)oMu~q8UFdhQsB>6;v z=Qy~#*Z`Q>D*(2$C~LaC&nr5Ea5wPQW_a?r7sKa$e(cn!iDYa=^S)5+H+Yyn=iItN zX=htOyZmP=o12r9)$}+#7)0v^ZkxYXM6Vsb6DjlIj1Z19*6!6l=<5U+&|0r>y?lCg1ZMX7;yi+0>Kcdw;xJ&N#6ea z+7VJ)3no1s9ml<5_;6}L(CeVs`FuCfHbXtvw@tq})Y@_c${(Qb^b5mQJzXw{4+7t? z8eRT9MQxd3Bxg=jD>p9YJ$To~j>Su-DURus_E4&*bB^}|%g^%{XTb~E&as8YfWD%t z%Vy2f^D>@Jp7Xo>8D(%AN|76LbJocRf!`HOgq*?1&We|AoRzZSMVh=gx^U0dRz%Ik zvEq#*f@xB*x6#pTfHO$ZKxG)N@a24PA<+{zi`KD`;|xO$yHd~LXEQR6Mp%wnM z-k;#BR#irZi*TBB`)Su-BL(7ZIh&tDlp-NW{nh*>j*Kd|6JU&fT+4e*vVyo-`TQf~ zU)7XB?ha|YM{T?qLa#5p*`NgD1}Bz1vih4Wo2G*Cn5dxAhyZ}Jvc*^A)?3Ghn<-WX z0=U}lvS?p-8YC$5XO^bFA>dtCIhPEw3N6T`YVVJgZnEeyB8WX$hs&cXqb=JcDg|mtJbH0q5snmM7X^eAMkC3 ztoG3IKzp!|CdJvLSvwdMdWo(`rxh5{Pq#4{#D^w~Wj}^+$SuHtGL@V*8~%9YxUAvV zExNpHmN{uzXv!$(IspVuwnzR^s^*R=n_Gv18}K#RViRXb=Rt67w001nr4IHeVx&1Z z++PR2;?Nw~NIGb)wh|Un$RFFjsxxp{#eZ=j(ZXC1qGD>+%j>781}MsBqboSqSipQQ zRRz&(N}IkWo(GUX6EyXxwh+36MBD2+Q|~92u#m>4V>wu_0O$n>$b(oK_7-uXO&7BX z(e1yy?Tz?q_^xzv5Ugnn1*1J(0b6{s!L+jm9GYPyg?`fF(GpreZ=>NvqplBbf#mj- zP1ezFf}yA8nBZY#W<3>Iy&5DLdw;%+!Z=&2vD%nx5eEYXdLclFdL?KbB*m%ZSdy($1;|WlL$mRnxqxG1a$emH?9$&;`TY8Z zg_4=oVn^JqHMF#IQLIg9i7lbTNX%Dg;uI=-NbR=$2B0=WDCMCHU%8tF#QTiLgA|xR(O3J8C^Thb&b@%bgFj z#n#D_0LCnDLY|C;uRj!-Pa|~?@7oF+C8Gw$@{OEUqA(T(Wk5mo@TOn{8y2OkGnL{L zWUB?062k|M-QEJL*n}w=EtTx<69r|&i%SWAV|y^wajahNO)Q98^>b|y^GeJT*mxQ0 z$dzG;KM4}XEt1b@k3WXuIk~j}14dWwPRc<_Wuag#TM3Q4s4Wyps7^{8D#fr-OK_r0 zT=samzrr_>l`)l3xWF-{F$wAQ1Frb)w|(?p#!}GH{|HRxaNmW=d0Y1~m7g%nxHQ*? zsk6A>AJ^->&SHR8ndS9t^Hy$e00TipcgZx`J@(LIQdr2__Cyfj+o;}5&rj?f7ZiTj z>Hbb5!2@y~7sb=Ni}$-Dy%~J?1GfinvKwRXRRC1!l$b;rziv0nq(0^Ticer_h#`^| zCDy$kXEPMpbmre2VL$^$bN;Od|A+#e=O>}Y2)^{zTc3$8bxW`Gc(msWx*r`Ivan-}+h3xi*E-Nx1170mxaKtN-I zQ8Uc=O!-pYgeeuuR+*byn`12rTDxML>iB8R+|^vaPF1(msnGpkZPia7o#Usr*E&6} zc6$dxc-OQ~k+Efyc>x6U&5!SE1hdeq%v}_gs1cCF=DKIoj*TK$*2Vb)=~K-u=-TU{ zLx587O>{RF^{Nc5g{78;=v3U&omdrTMMVi2Gv_QoV`pxYOOWR@c=*=^QT8xj0oHM# zxk7c?w7nW*nV#*mD(r?(;d#VesvlHB(6{V|R!G0H@SD&96eK=KS`cqes*y0= zXqU&-R<>?|2wn6W_p19QUC$ihS{HRcsyNv7HX7e=799Qok({;B&kGR zey|;RkTUxCk(gA**;6=#v<=P`Hc(0O&;){Dbj?)Sw>C@<84Q0Vn{QhY%8G(byq zknCZ z1$%}d>5b+3V59k(wWVHJ5JIs(0voABV8Gan0w&;|4ATe<1i?Z=DPE_`Mc?odQ*M20Y<9p@zlR6BO@F zC_7Q3&VO~6T@&4a3f`Y9+cS|z()8}$YhHE!S@hs?XiVanV_;K6Ed%`pc=4$wWo$FjRZf*P#IGW&0?F1J>*QO} zWs1TI#2wP4mR)fwK_C%h8pNK-p$zPvb7_4j~S$oNzc9QXTpL#T-z2m)ETdP`$% zw?-zJefq^tZZ#}Wh7cqyBaOZ+t|a}_Qe(P&H@6CYbz19gsf)ZoZA|+;UDPn@+l+QZ z6E7sTEiDFUJ}vpJb|JaVjAwx2xQqk$=FQ-0wmixpq}bY~P58*qIOgU-D^?M^GEuEX zoVrD%xO($2O{rO~Izen|82E8U=@xH(D$fwLbinF-Bs}z=%YLwZkFJmDz^6^0r<99H z&e)rfGRY!Cco>hxMQu6Wo8^@5_h8$0!@Qn1LI#d$Ah~95dEgHMNy?AK zLMOZooa%7)h8GzIz~B8`h-dS#4uaj^w!H7?%pLVVAv>-9NnxugAc_Ab=;HurVO zP}S;Lo&El|+HV^I+m7cGkA45^OYh6R>Mp9(#r7HdP3sbrS^@)MK6!- zAHn@$u-u4V^maB)uO+!xt4SkefhJlRr&vUhqSD}^B}d?TV4#HOY|>d^i7FV-s+%Jo zN@428YQVAmz*hv%eOglvFYbeJ!9n`CrrrJhC0?|7z*WimzL1*iK%7mb%J>?s+RuUa zcvIS}U#E)@2a*r*fxMXQo`@5ZF_3Td6fbPDpBcY$A8zx#rnwvw4~j|r{#8hl85^=v zRdP1h;NA7@Y_bAB`oEE@ZfOrs8{nRo;bYOF!6B6NnNYu?mUs zM8D#9S$-Y_%0x^eKKpy8bMU1V{dP8LZK%t@Mh>M*ujO zxoXgWbhrH!I|kkR)7%!OM;p%tZL#)5CXg7@b6C}m9-M&V#{Z_VuHDR;$=2Qvgt)Zy z>MQBi3Q`kjTOjstbC2+yQy}n^#KoA;At6#mX5$xKFXBK*0zmV@7t^IQjYdl}^bZna zbr?@PcbrFI4I8P7s2sesrKQE8+Ep{zchuS~dn;7hp|$~kbf{tqQuPKv0w4hoK$CWK z1XaSC+nVX+g{dgC8b20xbH2X-Z3Q}V1aml~sD6nDbX_j0>3$X`S$A%7tWIN%KjLY4 zE1b^4AJpD;-1zs3pku;wODJZH%4LH_>p-RXo%e#TrDdaYV>SA6Gm^9$tM+V_BywBs+QtObgmjwv(TK_YIkF2hTP0a_=0vc zQyH)U9$}Ay{zSvLE_kqc@+N3Ef*eV=`2a3!o$u2E3RC2nyfc3@X-K1)1E%7Oe@%Ox zB3S!9yj{Jhz<_jpJnDTBT)o7ICF9kXE<01ddb>X$?qExWTnyr=vD%fJG9(rpLGRRq zy-PE>GhY$ViHXwe%oRt)GC1ij~(M_)V@{t^$BF!hkeKd$z-u5 z#K?6ulI%$FYb)@QedJ4N=H#Mf2HYBulG4IRB)D>bYBsbZzR=(#>Oq>A)(^sk|85RSF~~Hw=}OQe zmGX^)mY^liSJxLj^aeTkV`&8YHMh0}z*x;;2PY4sv$)-fAIdGj(SfUFkNqIBAk4=f zaEIaI0vO`N&n$x5zGv^WSTiPqN2!)zYmwdx(sa}~30>rh*w2iRpSVcS@UF>M!Z zluDJ79w0Qc*StCwcBM`ILB{V8Igluo*Uzt|(Q4KJu&YH#w~&*zS$0tawW{Cq8>3m1 zNh)PxaZxTuJao%pJhN2B3p1;4N~ICDVnBxe8a3>&uMjQfd3Ib>LY4kbwJFD19f1;+ zVbQFcu@GOOPLXy7=^Z+Cjmbq~6)vK)X)eUmrHjzSYX!$_5s;!D9hDIf@UPBu^pTl% z9xy2ky!Wy{A%*jnS-^}XZ)P5Ld??QGbv8BK4Ys>y=+>XMKH3>3aAu%$w7%N(>i*pS z8S_^2@RNk%vg>UUD0MbX==kn^EVY!!o_5}q?A6GqCxs=Ohw8kII?LVz)nW&97MO!z z1Gr+LBDChlNkl2^SAiu<;Uvwo^3Y=Y4|c*744yuepp7)es@SNHF4HsbHdv0+kvrjN zi59X*K)ttN5yH8qNXhm8nIn2X|KR{z4VmQ!5_-Y`dNS?y-Y4#M>N=g+ZtXV=pN`dw zPbN=US6N-)=-vNkV}sv~snzB+N8EgS#6^Z=3Ts|FbSyHgiRk|iaM znTw0i59}gU@rGVm;N$>r=dIP73DGf{o|{Ha4-k2nMr3f+>MJl~a4U`Q$@`U?B%p=o z`alE}?+n?>bxN1Do9pF%#_l%A%9u9=aWP;}GOZsQKWbY+nlciu5 zRUk}f+Xa3HMnePn*r$WLO!IrNxp8YOa|)9r#i*5Al+`vBz+F6+5hH(p+c-? z?NvlO{Kkls;nacVs1)gR&XO?hMG+{#4v8J!*8QA&M7(H3M3F!;Oo~94by)RH2!K!` zVmRuDEQncNIWf8YG{G-12oF$#5VRkp`41DJIz$!61`DAU?ZSWXG4=Y%wd0hD6={VP zZ^X+*YPPV3D9ffhTk3G4LiSJzmUKhQQ%K?i@>69PH!7EMe0!~Sx(N}cm5$ht(9fei zLY#UVg8&|CxKfROfocD@{ab&{OC>8ITb0X});66AuErsNVwQ@etMHQlwrr4lnF_Z! zQP=Sk2lEVBfk|&1@IB7ParBRJazh)A&8@1dWfECG2ooJky&?JEP<^-?Opb=z#MI6n zv%>=rO6@3+3>)I8~`XH-_1MrjE_>n8ey4_B)#CPYw`3={B(HVH1XL>n10^&rE7Z z>1Bkp5w39^9kfEroIx9FJ~0VALi|1*k2M;Wa~?TVNkIN>lk)FgMQR3-6G~;4(#vz2 zqqpi9Z-(B7p~JnaU=#l%C$Gh%~7iA7McP_VR$-J2w76&g+cu+2?omWv6T8zas4W%3J0biriXr$mex zit|e|m@0F7{+aG4gI219RsN+H6TM(WqOvOuCeWi>)hWI7NApCb>33chsRluQHsx9y zn7Ex|7EDy7N?DX<;4s98G%+GE^cMtFI4%4|#G)Mq$k5MAStsVMpRJ8Q(?)>8(qYHZ zL0gM7%gSlG<9BsnOeTpj-~pH;TLKfh9;mFH2r~tNkN@$4)Ps_MHjtC0?&uN908v%gMBpynnAMWBeV1B+oIXzfV`Jn z*~mv*39E6VR(^szioz4X{f<7wX0pA7n0dn>N3;Uokw{ML(Lh@YSQ#Pi^>cO;2&ct% zwNb9GQZg!(0Ej)h>mdh--#0A5P&W9(HY~$eno^JE>kOTh3#=4zmN+YaFXP0ki~A!YRyUQ!gSe zo9OjNg{_;b;(Zt}s;^H-p{K!MfM!|q*bfWYu2iKzU-#SUw6d~|E2bD8{(AlC=FGid z&T${i;Jpa&+<69y0aQRy^hdUSHO}VhpX5>>=ZwEWV!9iVL zCX+O4bBr-jKzKptT0>{{2lW8MFN}6IWm@T~NQJp0V-R2?K}sXd zd@cFapI^cqHQqdl6agEKemyqnwH=0cdfpy#zczR7Ej@BQ`b0hbo|w35LEC!MEhomF z8pmN!{M@_{{A69iGOfQB?-R1*%|5nZwdz`Rtqd>OIO7KXndN^cG^v+H8;tB};Ponh z#xPw)2Lq`7tdkA5Z2y(}prg29Lt^Z@e0Jp+sAJk9g%EPC-vcKinWl@L!{t`H)YU?B zo?he=OY{@BroEjfv{nkMo%e#c^qkpIFBzh2*36?o^sGpjv7xmksQMZE0MNRJOIM~N zNp%v4Uhy~N2e<~4y3he^*4*p7evdr#>Wj_-cl;vqecQTS=?7auN-p~Sb+;P*ztPY= z;@3Y}&zG%X);6w8(~}pg9*JSE0NtFnEef(GjZ_ycK}%0UEeA>s#XLkbsi(awh`fg; zfuV+P6-&bs;=rtMu1}+-uAjk}hGj1sKGNp5C?^~NO13M440Ld^A)9-#3(rhDJ(l5E zv-dcFQixHr7(T#ZkR<6UV+%9MadhE9TfY@|bj{g*EsN@tBWiAh*H9CmvKII|$ih43 z$L!@&{Sv!!ipj@!6l7egc@F((`W9z7KuSW4V;~V#_Pd*+#c|>rSumPUn#E4pE+tzB zFVP>^8)4R(&=3hIBQ!t)BAZXqO1ZEorG3$^-GeCGY<;hF;Yv75MoU?CE9%#IGZGr@ zND6oY$bqxZ_;bioIL>rNB}V8->;y#cW&>(E&5Il&6j47=3C+ z@rsQ845;zAeMe96aO*rv_fL!mx~ghA7idaE%-|1Vaa3c`zY~%kB>?6bbf;K74dusU z41NOy#s!7I#Y@XMMb}8VNlDI<#uyMiq;cnkqNV9cmy$*N2~Xb0;TyDc=U)nNn6!X+0hdi!`lwbz&${C+jmRTtufa|4iZzbejI#x zFpRaODkZ%&n2i;U)5-{_9wynG8T3uR*0PhcL~KM+8HFSqd9JX8dWZ#)>JL>=MTJw=sH$UF z8Sv+Y3aK`F2T$i@oNw5QP{35Bhy+{Nn1O_71r;%hKllv7FX#@kNuq0Z?*C}zO=Xm1EL0Po#nAQ>OMc=&WIR+X*bCHQYsZVbhmr(p2w_mf5b4RZ+=1MbQI#oW zabcnt-|)sF%cGC5yPE-HCT_*(=*4`asLC)?%eJi6Y4IKx4y{29E)N*^->$hb403HJ z*t?;zsd6lEFp$~12cL)+c0=V+(aM;_;XhE}t&xRe0|o4ABJ362X#kj^hd2^HqyxhOE*^u^`!!!wxlDYHL;cKB60S z3-ZcCSutq=ld2T`xu)e=`LKwSRJxkoVf$H+r0*3>MTU%@`%UU5yIQ+T|2`m+g-Tqf?r-L{TM79342L0!j0TeX6|2eR#%+ab2-1tzO zpI6!I1b*KTua6;q&%pU{;3Bs!3MC-zLebVZh-1FgdwR?T)_A1ZloG94h z()0UR^LuGq0S0P55?Ut-OG*jw+UZ?t^^4csbyxKTSW5QaXd>w?e|JBEs>W*fm0!^+jP;e0wNe^w0^Z2_x z6G}H$GzSZo!-;`InHq}@%x622cq7*iuz5TtGHUKyRrGI+Or&-DWXA_0xA(?LDNl?m zP|~Ui+smmd3hwYUiErN+s;fdu2s8C%`rq_14|0gxX6@OdI6+A`^Pf(*m53k*|3E23 zyf+3|jbhrJ?{LS5S5nj@VJZ;ys{Op@ zxSMuzZr-Blo<-F_>H`Ry@XBJLe7z!ERvhUhTB zO^33u`EtJ8wUv$Lz(#U(WmDj-?}c~V69-kkre@Z;)FnjIr35WSRfw|kyJDbXMDzE7 zK1-t7lH@$3pT)rK@sJc%z#5x5V-{!1!eTeug&q2PRU0hFA`)zPUqD3!!Tz2>MQ4zut~9n`2&bnhCU%w}CG0U#Vay zz7K7qz0&vFoxY*C-9xXg+oP|C?vLB6sm)J=lWVbkl9>9cQB%jRbj>riPTtw^c-uCv z4asQL(4Pm>Y0$o9s60B*(TgMnjU(c$JZr1ER;*^bC#{Z?qQIMz7CJ5Wia4DTTz4o( z^c#lR;R;c08_WkiPxeuM?;QZFR-U=k*#| zezbe!SP^$M_vh>^+Kl(^1D7fkL=C3`Hq$UsZzS2W{XGeJ7$S1$fY_GYfu3pLkxQis zUD%*6w7-`@{!Dtf-_-#L36TV8JM^zd`@D8xi*B*Ev|W-Vr6&xuwYE~2edJ+*s!(g#k{>yE`D( z>c_`7sLol1VR5j5pfJ`Sp6Vx%gYbH%VQ82swha#g<-KMSOcWL_cteJao&@w#2=wsB zBnbIVZL&nNunn!|O7mp^UAtT3h+;II?cnSR=5~zW-dHT%M6ftT*3a7mz6lqtEXx$@ zX=$y*)bSM8w;yRcZNL~|&H>Op8Qe-wYRg38N2iUs&Oj;jrwA5G8Obs4nPT%%Db~b7 zX!lrv_%a`?=Tfu~>h3}T@*5}PV zE3nU&y1Da1Ps{abf7{o0GM6k{Jsq6G%Is*sjdR%TJrC=m^PQ_R;#<9>|XaN z6i&wRuY4yL{snIC4)o02d8$1GC;qB!T=L~UGJ}1uyLvwONUmdg^MmI=^H$Irv{lMsMXt zSI6_e7Nd6x+b0*hucJ50Yr3zeD;#)(>16!Z8@a7&@lA|2md!6jVY$7$41=;9369&B>sv8Y0xx zEd}Qq9FZ~)R4_EV#UF`Ik)qUoRuw+Bw@Nd&oDZh>Oej_XyBxp)J_o*5jOU|)zXM!5 zi&+K&Eq>!8r1|FH!|EHzVSnfn*uX8#z40#adyP#nLV|$57!E_G!-Dh0-8y#Ww)&vh zBJ&aY22LoOlb}_~3wPm3svs2!n7gP32u^QcxJm&1T-m1a+Y$XDVLciZpE0gx(teX7%}o0p>>pHv7#_>A(ffDKobKyt~w$`dq5(8ufv>ZMPlnV2VR0c`= zGnY_@!hLo^u5coSz2;gk zHiVu&$2utI(M!%`cW*81MA|T{v>l@JfX^aj^(eg5Y4Dy$O9x*bzKDB;O8SYqTPKU@ibb{5y%77qUgzATz_Nef%o8cVy4A%Ou_Bz9eU|f5H z##MkiekpmhwGm-)6A8)Sh&Z1o{wF$!VU_=QD1G{>J+(`U>JJoCNJi+~-^nvM67)cQ z1^<^dkuNh^wiz@!KP>cgGZc|ifK*gt!CvKa@Z#cLdBWApb2~xl%CE}o7a$j4^ih!W zb20}R@I4*gF*Ah-Z=+Ax$f^SUml{kC6~vTkXq=~e13I6U2v3L7#Xa_dCViu+5hsHj z=gIAh=sfIXR3v*7P@$AdD2&D$ZW!>8YU(en>@+8+KxEw8pYS~(K$xE&(^ee4FB~^6 z36ci<$4ZYiq2Nsr=&K{@lYk=d}zKnT!9Vp#T9b;T67_><7d!W215Depj5JBt=PQ}(oSu2S%Wmf7|m8*>lu&Gs$S655(wu-#cc@D-=}UWNNn(qf`lOydmtoG=tqfbK#=>RmxT9lZb^% zZA%7^P_wLWHFPV(J%whpehXNNhNzt-YUd@D z?A^IM@@MEek+JK#_>H4ym!11BQNrPF_;Ubi;+Jh3ln;N%>@n!aKFn7y6=dO)?~=&p z`u)>k=C_w;n(q7j(?c~uRS}L$Du07|NZHE03HB|+1;Jv|@#}7t|2rY`Z|$1MUjhJg zGIs8J85LV<6Kt_so$#&#KybQ*81*s+WATEUTg}Lx{k?eWRp9({zWQ@UCg=5#l^;0z zem&T2TDhE;$m*B$M?vU+_H z0VaFI1}=d^Q|9Z_jp&YR8H|K+{ln!LW@{NvKf5^F)7y%s?5vLXE}gt79Zld|$1{(i z#JOEZ3H9+72J#f_~EbNm+U+R82|_a<(#7C!&{R(uFa+vZX*2VwpyKlT4s% z1~*irxpTDDTu)Pr$mO9+Dn=}|HBl{_96zuSE|kweJ~OiZpjE;$px*O#QC;~FU0EPQ zb9qOd3WdVDh)qd~OsdQym-Ff-znD?F6i-rbHRNC|!nXB9t3N&{KCZre+3; ziIc2|0dn-G^njq9K(yM~M?~(?@i5w~rxpZN&&TM3+ zM`0e0rLmhUtCtHf&4l*5Rf=c7IZ(-PtWLOF z-f`u&YccpXHqj2lV$i=Op7%v*@imF*`uA?JF$Li|4nVwu|Sb8O|b7F6#k~K5b zgo&vv4Kv_(f6Rsf)dwARHRcJ>_*I?LliAgSLuWU456dgiwljp8tRC(}Oq5Xu)Ozwar5?W@+UnnYbx&v2bBG5yW-LK9?C{L7t0a9T^ymxYMeKKoI`V(tX zde{vFL?ZR72=4zQ>Ybu1Tf1n{s@SR6ww+XLRBYR}S+Q-~wr$(y3M#hG+W)<$oi-lk z^L*;x=or1FS!i{2{fcW*#{m0h&cN@KUq|pEL7F#LFi=go6ddg>-Khk2q$y?R#x!h- zu)8|+8oe$)-Lfk$MR}`Dg5t~ZP?j?C7Zvl%^OX&uP{bkIU%!}I^r|o*acq71ORDuZ z#3UF{pV)Vn+;vO@;gT0s#8$m-bn%3S`AGNhBJFjD&8>#%r>SmYALYFlQvpgCISKNsSeIZLuitJ4L$znTxS*it@#nmxsfY54<|_X&4}LD?4>% z&^A2C(wv7+P=xJLMSJ9;bdqcyH^UKHG5%H2{E|%^C=qn*3wi#8lx)A56k{Ntq)6?+ zEt8*I=s7RTv0{^))>7qyR#<$7TDqixsZ4jG5qsR}=zC+l zW>YKNYv`vU*@c10dwt8a{b^DLB|g_>aE-$0v>5e&t9_EJ3i`&BGG#qyM+0Yj#*3U9 zym?U5cVF^w#~71|e)jA*-+3YIWH9~hGaj&<_%Ex&EDe=6`M;QtSMdti!T+@|2qOF= zJ_cU5u3jwwLg1cN^{(1JR17)~jpcbL#|}=VL2Wm2-Nv(zAZ~dfczST=+fZe(t#v)vK*mz39~5FW2{Re16pCmFR|Sb8Ouf zvEiaVSy|~Weru(sbt_tpu^eamz3S;1VI)uj(7I>hULZ$d#|el!-&bEp@!f!A=;;H- z*DxQk8T%h-)-Nb9DjW?np80|ixSGD?dZVAL;B(<2fL~^O-%Xt zZE*0qBB$T2VXrEUjBE_u)C`c3*nF_IU)E&F)^nnpo|0SBX?a~gJ3E67A-dFEVDGL} zQo=w#F^l1GJFV2~rjgdiV3_P$u}*S)iGXynMOC6w2zul!#^N1Yg$TP5JZnAnl_GF{ z2UT};Gq|<0ag9y6HKnb?x`u#0sof0xujaLVtF;8HX|U(@l07tyOO(CO0h5C8PA?&% zWkZnTieR^IOMzH-xMGQ^^|^9%^vc)vsAiDFEjJ7ER^*dyM6Gz0<_MeSl@!a4QKaoJ z-6)8Ye;-eX4XIE(GCq~TOx<%E%5jwqcp+KW(lCv2og@SeUY9URK)@OiX>uH@b`qm5 zlsyl*ecE5ofB^4ly0b3aLjx+2KmI|1-cgWjD}xI7DG0a7Gm}5Th$DZGgQ*szW%nf} zGX@(bLMuX%S-H1_Z>oiv(`VUm2EI1ZXaP8oQFfMqSFH!kM@M`bGqLodGZD~YWg$&@ zvCJAA%m>_jS%jei=ckvH4l_xl=8rGm9P52t$vmxp>e0uOl)sp1d7<{@ex0;47*oiZ z9yA&c+sMb()bJiS=0F=2hMzY6+;uYW{&SfvJ(_dpF{9QX=g~d;;-gf(U{3UYGcf_8 z*LpiWn}f-ZIy7R%9UACw=DiaxhL0qIY2(&=!9MoK;GGr)#{hVzz)@_9Ze^jR8Lf5R zg_4aMg!sa>*-}aJ{=YB~762KeZK?^_kRX*)e?;%%0jh)en^OPpLKAR570dVHcodq4~i z5ePkI;D`^$h!i+pU+R>TgY}PIbp5UOd}PM3o+g5M*#3F{9UpsHrS@D+WpR7?^J4Y7 zSTJT~VO9-Ayt3R#y(3bSK+u0xac(InYh{v33`( z2a_{3ZZ+C*g0NI9s7+QH^Z1d8=qHR3uJWH)nDL+FAb5N+>vH=ujX|ZU2-&3|csZ>k z6z6$+AkDHfOjEuP&(27EV}3oRDl9hQl{tmYb56@+^VAE<_wiYMxZBG5(h`Ep4eaH&i z4v(3XWF%7+o1-?E5%ci|zGxSwi9*Z-On^v<7J?0m^Q9^TNFg4Pm>K!^e4JA@LY(?Y zt7kVow58#n7}aqP3{&8MgSM6w9vV3-%GI2WKRQ_2Wc`t~zt~pXn00tS7D zKwy21izi>>&=>(|Sham`V1jJF#B7cK(IQl1)h+R;xG&(&Jl-?~5}VzbDDiM-(|Nit^domP7cr&#`@_8u>j?VEk(y7LS(hQTvBsx( zZUmLmilB!u3Zr41PLQUwE(EpbWEW4cw;&wo3#KoNoP8Neu%v!n@I;`xk-ir-k~PXKO^3a;hqx6F zD@;Qy#v#FO#Yt!k6hnmIg0+r6LBOLC`FH*BH;?huR8gEk3o|z!ZpFS?p12SyR76X_ zB3DK~1n1L4NmSueP}zP|{Vh?;q=?Uz*!M|Ath`6e>B=@Mc5%S9Nf~$N86SQlnXdF| zSg(<+g~_n8CWeKwDy1Ee9MPqXhNcc>SqDZ*C+*@Y*rMfLC@9dlpJCK|LOsVMAXo|N zh@~KkPl}BuNN+NBd|bgRO24S6V7tV`mrOL+7Ds-By9>NeN13xj4!c#gzu*}kX(ZG# zl(IUm2{PJ%O3rrPpy*Er%4?A%QoJBf*f>H{YzkW~s8|R?L%y{&Abk2bn;-Xg6LQR- zcr93ZEqEDyWu2sT3#KzpOp8+0jzu0%LfDB=UgLAl#YrJF`BfZRQ9jkXsH)~Uvs06b z_SN$76LKz9=9Ew1eZZW*A*I99D1V25&VHH3ak-~UAt4CrS#58S zzoaVt%Z4dL^qH-18H~zYKx-6Oac)@rwqCaP&6Z26p3e_zG^#CDO!*^}ei(R+Wk@6zFYs!;ij ztzdQY%r)%j=k*b3d+z1sw6*sUK2T5&*=6u$t^3*6%hc4-+eL^~BOe({Rn4&QzPK`3|77xc>-^uMMooF^quW|m z8)+R%E~n+#Ac?9awnh@h5|hk5hBK);Zro~F=)G>77zqsY`cwS8UgxnrciVFOE(cEH zvp!d+>i`P$%lHHaT?puv7ee|MWRqC7bKNMiIr!@xWC!6cpd+3{(@HF;_AR%Nx zILzk_{%uoV37!vAl}*l`^S7V5lw6C0ZX8Xd_R@g%DApGxScM9^{A=WZMG`1#>TG)a z&sd*YCtFs9fQRjjbXZ(=7E?_MRFy)#B59o?cQ~NQ z9NLV4i?><6D1>9B_wE2Z8pQYJU}=$Qv(U*2qK9>n*bMu{O`JmZch!icrkXDQiCZqz z8+qD1Knw+!woeX} ztHKwG3xFkgOzHTcG5N7@dB`dGNa=WqC7E%oG5Myx;@X@H>dZ*JC^JG&pO}lt!(R&v z=`ilEX}-+RQA0eR=P?f&kCdnEiVk3Wk203>(14zONHny4>=(wFQA%iAnxJHK#qF-x zOOb+P>`k~WGt{=K&L>xl0sHAU*4ARaC$}S9V@@C5=*3f^%7w!ef&j1c4{Fz{kl6B^ zfcQ^4c!&Pk)qiS~`jnz4eP;F?d*?wzzX&e!g?*gMQV|}1<>x5AI4^OC48etM$Ue!J zt^1P070cf$Z?lC|Io~U3_h)G`aa9wZNc1IWGLfZ*9`-xw0)EH05GL?)`wKlC3&fc; zDGJDj##1?~iWhk*()gsS6vi$8vHIZ$W_6lv_6D1SV_y;tR zxsD1nHDganjK~O;MU3b(==Wza#yj6TgHG<}YK^$2l20;W!C$8y-Q`W;P>`z`FE1GX zdC4V7qZP^SUHmi6+gvI4nPT40is&2UXd(b2F@HD!zWGt3!nmyZtb)mh4xw4vePiZO z*Z=meDY=Gjo{d}0?Y>A4_0wf$g#`dz^-j4$aWhs7dIwJQw*f`P05stU!#H+qW`WGe z$EPX+J8R%xHwW}LO{5%(D2>kZT~(~OENNauq?z+_P)~=c2_v_Rv`NIxs4Y%$z?l&_CZ5$3AOp_B5sY+|Fxd_XB=*3G1)0gK{3N)KsGien*Q zDr}-MIjywmyy7TDqkM{OqAhLk1&+J~*1Bkf0<4&pTIIB5O^AG?DCszf_@87oHABBk z4|!gj>mxY~j3gU2SjUXr2Ah%15jTEi{TUekO)^G-3nG1y%C*3l7$)7X>5erKe_^L3 z$ui4m!yK+uq~nYt<=?!YG1w9)4@g^9CWUf&MSPToq%1QWQN@YXV%$~Q z3OfR(dIc5K$4ev7L>!ktAo1Vwurjop2j=2E1 zyr2$P8_UgZuV;VkA_bG?15+jLw*NPF`r3~!R7Z9-&4ltV*n0)+eh=<;zBl=m(zs)d zvpqsvZr`nTwnlJzpzZer){wRyo0C`!iZ6brZJzhDA2Zy1nLF$_wfL~fCmk1 z*G2ZVUwRuJ&N7LPe|Kv)-Vz}}%j(|MhR+SGoDFjS{lFLh+mWg^*n?-(^Edt03=e_l zzz24$+qGBC2FUd%9V#Azitn<6n~e{G&XfD)%CK3EFEc8XbW|+=)6w9#blSd^*!_!J z&$CTdS=Y_y)1n;T&h92oconYCS323n!!briYVYpbU21O|BgaKfGlACw*7gmsaIIIN z8jb(CeYS>-n1v;UBG;4W*PX6s{+Z+YRp)i5Z*S$gZJhVdobf`z-pK}3O-D6HD)*z5 zO*X|pz&Dk}@{p;5Jd9!^aSOFjW6+fErbwd)sFc$MnhuW}Q5LS0Y3jMO zypX}lh|=piOup9S1D$v%@pwA&6-tJ#uH$`FqA3MzF$z22@T7b+DzVOI$8yz7sRE$4 zA$osBd?lN#b6Y@Dca;UpP3L=bZ!mPu=#g#OYczHCRQ*oL#*-}x_8xpf4y(QYM*cwo z&&N=>#YFqKuqY;V* zvb}X1jU1-(Vt;$BB6j5FVL&*I19)OkX!s%(GZU;vG~cv@-(aoc*CF`gq;OrhJCrIt zyKaJ&K4Yh+`Azh=F!b0P&`8ucv7Y#iS~G*s9eUsE+c`m%(ku;TfB&29_=h1mu0*se zoN^{^dLnH&Oo{=~KITC^Cmbx+7F3U&sh*Z;zd6dBZ$QjGKqme&M49`qaFANA!-5p{ z4)?%&HMf>rc2!kYSuLl!%KSAiJYd9e zuh7q3I|a_dJ3vuo_pgYM<_HLo+L8oyS;nZk)BYI^5YBOwAw>U((3Qw2$`Ym0s0a`LE6mSd zotufBp3Y;#`aCloGYnc{IWT0lPmv~{t)I8&4&&%yAQWZq3nukwVptdK-JPar6DMqX zls0vQTP%A{^oJsRcDb9KlH zgBc`_bQA|^KudT_4NE)VG8kYcPOYHB#-}S2lTv6K^AvtStI@LOfg}9lj-L((TNPRg zIK8vygrS6WUe20Ed_O>`yl`5-%cHYYpNV-%IGj8y#7?;TXw(URSQYe zl$XQ`K&(dJF)wH}spte1aS)QFN!*`3!^yc33!EpmY0>&8mT2J~@NuRve6ChuB1(#u zZpnHYBHavDkv$zovN#a@=Qco;oqif@eVpAXJ=(fQh58`eedMIyd$QWOBYTFO z#iBh2CE2sEpSAKhgoZF?8oF@tAV5i1&kmLOQb@L65*}LI)`R2xGBRn4yi5!!wGqv> zn!IX0I%|%Wghf|@?QFY`eFL|klnlGQLLRDYP5zURW*U2yvT7-diW#-i%V`OQ?!*|} z<6TAGxwB)gs!meS)-XVOYH=UxL=veVxm%L3p-t1cAStc+{KU;yb6JGsn=5Drtg^DHNm!??fDIRIwKc#55{jaAtfc#pp;xr8ALdHPm z?wzW-{jT$c*01l%5TkDBFTtN%xP#1al6A0JWrg*98_Wn&eAe?B@U8AzYCbmOy$zMc zg87AkE$5xiWB%uJ2wMV#GA?SLz3G9j&FISW3*2p*NYq>X+yDRg1nv(ALBmp3rDYFe zF33Mv9tt5*FJbrkcJbdga)ckKFvkGwJZH0Oe?9Z&-r17C15xm>W@Gc~P|r$7DEm#} zP=#gwi7m&B4aLUKv+eq0n_sD%(*=1D_-PW-s$7n75)s>rGG(zjOQEo`VDg=gzlrWXGU0COHpcao%nXkVd z!j=Cle>FTnLQQ{G>*__J&1?75DKvDIZCW@s#%@^DQq8sbVX|K|z1F%*;&P%U#h2vJ z_2hL9B%~H z#|a7;g_P|6D|m>#I|}8DRAS;*wyv3#BzP~k;cQOIZ>Q7No>WJQir>ujtWTu0})o_r@=b1cMAcjd)}CM zbqqlf>Uk4xaxZc*?*j*93_GW-V))nTUPV@xd~)eV$M=apvnh_Ln3Q5(gaIYwi^;*r z_gi&?bqR><>|MY8e3#!%ECmYx_R{LQvof=U9Cswfm;PJv*Y*~xl2JO&sRQhnk1Nn} zFOtuQrRKJ5iq%K;f!a+9#otpU3$wf^Xr9F}mi6wn<3th;Ek4M@o)737A zAOvS7LR>^O9mu+PC&**#!Exur9~pNJQ$5MxAz)FkuL!_0p`3vCvt$E$KIx&E5zx=# zwYE4RK5v|LK5{r-$e%vu#&J4q5@*myD4a%?M{tI!6h&e$ON98mSIrkZ?1KYaK`!%I z(dt71?eS_pWM=R}n&P!*=N7!l*tEl5igghOts$l32_Hywa)r;=2gGapL~~mu-YxpDzBYWN+a05k0DAS<>BFqJR7ST$61Xfr*&2lND)}@ z3)KTdPIgI29tO}Oha9M~;yHkNkcpq;^*W4;Dql(XJJx7 z4J+O8+cCa|es0-<%gltj?gB}@RzO(EFIk+=-ZuI(GILNxX}zO>Q!bP>!aw8#U~OGj z;H!$8p~!qO&F(K962Ga}v0SCsG1NLhBh*{ZbYXtN45OxGTp)uoJ;debsE(VV91w46 zuCg$DGaCA06u5OCIFQbCwf-}Iwav9Z?u;$2)aBzoaLWnwV?2H&sadDGxlz=@S@kq0 zjvW1%s*{m**e&+HTkLBJlb@-SRI%E#SVlF|U8MqT{G2O<;@msMN*Sy;;6syjvOw9! z?$>3cap$+8U%WfMf zL7%nxB*LHRH}DTpv} z;VIuVtsuY%-eLwgYBM=$9#rzx-v65(1qXxtphq-xWgD#E5d^#*(aIW&9^J$4*R}de zZ`?7b*>0gNVYiPD8#krRvcXk>r=7=7?(ZYa^AV|-=f?~{F8$T}m!qwRi* z+b8xpfClq=dRE5>%KQF)6bOOw1C>0p_QI9hFoo|r$<`an?#T{7VTl^H>$&i|tT_Z# z*F^ijlC019`z|{v=eBOQuK-n@MQ`XW1a6O)EWg#vosRW?(e{YG*8^zNKg?b2^=faw zc7r$50fDiZ3Z1oR^b@kBB%*d==@Pzif9GLX3b_av|Rsi1_ z$h`dApGzpuiOP=)u+ybE?p3|59Pv?j{I^{@zc4}MT56&0&+di9a>jwnu5qKwtSv_%uJSNB@{!VipJzgPgm9VEZG;6{#;h-u1QWy zszjKk+o#JhO3KPlbZM(bx5QD(phEg3odBb3URDu^qE8gv#1VH#C*x!gxuwt)QW_T8 zB%aEK!A~$&{tWM552+Z}m%x0Cl*qEQY;MB9lPOYs!z9D9bEhE z=frM1>A6uJ7#CB}-ur#O%mXlV1U&{Pi9mO*bupRDA}8;T>pnoNi9WNHwp(&IFEk<_ zw~~D3&Sg{s9XBaxbOrD18v;#vquNAJY;zu~lC#Nkt*DTVQT4L#=>c7f?7fR84&o=; z<18dIHB54Zk&u&B%@e+lUV)>dxGmJZ>P2$rytA&eu~VV3@EQcy+4u7ioVq+Fw;GCn zo97FwyuToMv3Z~Aq`#{bKFdvV<14dt1rhwBmz&6%EoX*upE+aSwIM1Pw+CXudE{v6 z(@m@csQlD8Zo4+;Go!PlXfMKr?6{ty7J*A6=INcA82sn(i!mq;8MB;v>Wqkx65Z4m zB@yVdn1!}1ykk5P5&Mw1Sa6ZTRQeDI>NI5<)gF_y+?kX@cN&(V5s)$!*=|;m9YEJo zpweHnz3UpSX(*E*te+0RbX74qDlo{z6~DrZOWeh$UYZRVEjmhT;v+AfQTh^OXC9z< zP?Q`km0iLM3l!V39j&iLN3dn-mJxvWaMV|W;1qGn?ZYiaqKdNiokjVHm&zJePVblq zz7oOZ(h76>thjH$&O}}mw+KO0J(y6c%F8=^)0W0MHttLA4e^{cu>BV*`av-tnu?da zWTcpl#4#YM150x7Oz5@Ao_xXh+ zeeBBWGC^e-hN2kseCMGW$PiZ05)_6Y%g9S^C2jOgJv5UE>Y^!=mBOoDGKknFRWU17 zYAN<{PV{l@r@jdHLeC;5x0b8Lhh3{=l%+`B2>3iTf!_2AYuoOzj6 zS#i?BOAFf`-})9N8ML(X&EORs z0&3{x711N5;mCP7H*LwnMz?oAWZLBe9&gJ8A!Eyot8Y0|UW3^l;D>UL7$(9ds`5C@ zrYkHvBdq;5=|1jE;`wXsraCp<6)aVk+iZqSJ9lj3FI9bv0&R;I4{nmySmvEWIqr%_ z5<RaO0hp&k%OLT^|m!)ezy2~UJMmxyng+Z1dv&g)QP z<|qz67@Ifbk`q<6s)515Fo5_a8Y3A`RHrC7L!9Io{0G{xxqL1lK*2HQps^_~F{vUz z2tY)X*3697-`+)AcvB>af$Wf(N)4VKlCo7sGoG<5Eo#R$dU5unJH-G|bXtnK<`&dl~}tJjv~7Z9U>v}UNS-?vm023j}%{m0^fw!;U=Hj z2K)J{^v?bJu1E0U_I)Tp&xyX*?eKQ*7lE!}S6TV0aZdC5_KXhw7Gy7b+ormH(tU#i zH$DzR?)|mLBp%1*j@KUI*W275038dQrM*Ij39Z}Sz1+6<1yBLB)Di98=ytmn|N63j zzN2&EsbCu=z?Z)IzNo$AbG+z5v^DVGy@$oqmgpLC=gxu2Qv+I%He-jn&rT{cgv)j8 zI#H7KxOXxUyU+Uce2?v~Csum!+AeN&?0h#L+cs)e?tqn}-+OLev6zw>i{T`RNBO0t z&)+lR@#D{EbD(SFvZ9$M|49~|+0#5IN9nP$n(+0@i z7gk)^Y+FL~7h!^s4o#9xdydSv@@(*j3%h}#6YJYT!L57U0`2d{pfPY-~Y?2Ef{;E6=;3AR6ofEh3>ivy1QhOhlh6_0>O>*8w!Z9=6-ww-uw<2kCaJ z0l)4GD?~UsW%{Q+W0uR>M=`%8N4QR3dn4ruv|6wVV`J3xT{8j z3P0Trhq35Bkx}3GJnT82M(wbfN59>QmC?(XS(PYTqzvWuSTC!$Gw59P+HEgn!{+K~ zvC9Wz1>?#NzwyvZk(-W>m>LT`BF43hHJ_og$3;GtsFrHJD5DUN+>86nlwPhRBJKWG z!Yw!TWMN8FZ-iQN$epBBHPdYKpL#M?g{WuiPQpVqJaqI-i@Ycj;Xpelj(4!-Ksz;3 zg;=L_l$-=e$L|dd42V#1PL#~<`&T?B&OYCIu=Ey=|zL@&<-GpdPx@twxU~X zRZ4E}s4Lf^{=v%?`gvSLd+_IYit@m3l^mNgZ;LT?t7)oQL++p^(FM>fauW@`#nL7Y z%Lo_UV>RooC9kc>zQQ4$%)#idpN#4U+btvOO! zK?(CFtM9mnOI%UPvn4a4fh5UAK*M+WgFYLRWYI6S-7&#gxx*_#`T`6^Qz{NB3|hw> zxNHn1&@dlYf@<1qiokAXcWHG{@J8i2)`%1_1IaT9iw=!|>YDhj>xCfKF`via{=y+c zJ*K(rUdf+U3(1dJ+Rjg+1H9{bDT~?97nOeqY8(2(E=6a&vw3)B&}AO~!D+NO70DfG z^PKHTKt!V&lSK%v`2Z|^)HH1kEL)e*2>ribw6O!HQh8r>& zM3N3}d1+xS8zP-Dc1>&W8f)ftsV4c=aRmijPokgYca$C2`ujL^`^=L~C>PTLMOacC zO5np-hPh{e&W8x@r3i8cgSBTZ$3`mcF489UwaL_?NStW+j4gAGrEkaN;(m4Gg zAz^=9WUO;bBf%k#h$nI?&8gOi^AUd$B$50w4GT&YA&E)J;_VR*_OxjDj&NNLRRiQa zLCGo8G80w$uxM(sBXg!&N>XNFu>ncs`8bI`HG(dpf^f`JQA<@cGKz;D`%eHM-#WIG zq6}QNw%#l`1~&pK(TG-m$-{wb3g>}=a1!3wN3OW2x9rDMH%{q|uV-BSv&^VFu$xw} z`|%`zF<1T9GxbOKCnQ3i;#^mY3F&z^NZ888%7V?=Oif99U?*_AR9x+AQEjB$T-m1a zw(z#p0$^duXjAJvEotf}n96f-fxZ^mj>bw0-9WFm2UWwXlj35vnD-ri?#^fd@9CqJ z&fsV7f9aKloxWY)tN3cypHkZ`{XHp;01C6_9P1~Ui{)gU>QH{)uE@w$TvY9{%a~@yw9}(CK{kd+U)oaLlBYgd||W ze|f{Q!I)#Cg?HWs?hbu7h333l>^lgs-Zu`5uG*A6$L!{Qi6h(Okqbc3cI!UA)Kt>6 z(lmVD*Fy9z1&lNcm}0)5*@DQp&w71t>U9mVUcHa)y0Es!xIJg? zypfC=4m^E7s&Uia>>yTzWprf#u5IkPjV_!{i=}XQ#E+aV;AB+m4O`MIn}eQ2+qD@= z7XK8JX?qL$i`1uWw{86*we;b=a$OsoCk#p5#DN#opGbdvv;3!6zGBOf7>=f4*!w*& zEJSyR*fx+az>Fqkf`Y1}#;z_jlUkWxw|vM%C(7H;l_E}SpJ>63^_Zw79etE|n2byU zxESCfGIejSVs+5y-^cobMLRATL)=aO=m#4lfl)_$+_c#kR=Rig$e5}`DpsF%p9_^f z|4qQ)*~kXeMA=YutLp#bez!~CfMVt=HK!iQwloQ)b_U%qIZVL!)or2Q!}2vBXQMHR z2*WP6dd&CzSr30Nz~9gF;g!mdS%Ty1CUW;9(T?w?y;Rm`|E%%*Jsd^v_x$3q`cuR7 z?)L!iEJ6lACtP0z6Ry^$+3UuiNlM*=h_XpAhai)?eXnDMWT>k(CQG!8c+FyCByKF8 z2@y2EJF89PkUr$uJ}dQb`}ai@Mm8*stk#egY4^T~pEDaK!prJnPICi=#;uA513m3M z4xi#}WA%?pFf6h@N_7_yj=`wU#lqq5Ft6 zV~g!98R>&yETl~23MClZluGn=OChGA3Db7N6l$gFh(F_6N#|gC3oIU>p$m!daGGhB z%cU7EiSp@+=Sna~$})!IgePLJ%|!I<1EXGNCV@>mvo%>nU1JEXS3DYS+5No2+Qw<& zI9n~y7X{@VeDvsVX;7#xZ5u{u@JFauAoE=WWmEr5si26BIS#AKIn6Ot{K3qHsu$(! zePxml(;7pe&qR!4tx;hhn5^Pdh}CD#hLaR#G_k=YVsFd&=+{KO>#|%oqZuKIajwFir_lOJK*pcpynJOWDRh8rhi* zG8z-@$jV)jN*y~c5zo*_Gk11x$AHf^iP=;Go|Ph%;&>rRF)c~(P6=Kjl_I&IIGz9{ z0a5a#^V?+c<3qu>fjidPzcm9iFiYM3l;w{P+q$0i6&2W9L_h5C4X%pgU6fuDsNocSeNb{u|M789*m+OX7+dnhM|B02eLPcl>z`X8y_ z{%p&Ob3LZXRW60Sm>J}e=dh$J41M4t0uPmcb(t+r`fOv;CsHYtOr%;EQNyqjElxwS z$x==`P&ED#r}iw0AYp45%a?VCc9<%?ZedaLE9l|Wl9`1kyv0N~I<_T`WZ@drn1xPM zdeU-==dY^G&G0C(A6n?JnF1Kw8rIznQ|PDV!D(O*MZq4v$Mk}%_Nwds9GG2N;!~3( zD@B2%ZYn)2gSKT8i^o;^SG2RLvSm?P&Ak9 zp6T30r_ssb&RDMRzc+xwPqyS<{E5}R*tY}sjXrl?}Z_NjguPm z1mSj;@B^6mq-S4urC)tu;4sa;ODIjBwbee@v{@pg~x=`I!fu&O-BtI2Avh@XD#u8k6U3Haf zc86rX18Tb*x1PNx8l%O$>5j8=WqLmYb9-*x^=dtQ!GWuCcBh^=ihdmT)xZ<3C(8rO zc&|&By|xYS)Lz-Do0)n+)@kE8e1W>vl~5_w6;W%_YC z3tYhp%(G1j2-%J!ox|vuK;7@3Oj&oZ?WOT5q(SjpCTUEAXctZm)W=J&QfyU`$!o-{q_$|HN)jaJturM}vU z^^u$m?H`B*k8w^DHp#gi7$Ij=98~)2lyD(xbo~MXk8-Is}6)hwuB*6mS$4=i>?t9;g$Ig5B z?AMyb)^q(uO(JA0uJ?;&t-xzoc?bfWl1-x_pf9c92`KgEpFizlDDofQW8BSSRq%$| zYA0-91gmDIVg}T#{?4)1J2+ccnr`(v7@!|n9HDRA| zFclTtZo;{-pB+up;=q|iTmnms-d-}?E-6SX7(FtY-SHQvBufU~RyP~?ZCAkCJnQTl z)<860VF_-=A3~`O^M%R{#18e9L3_#qY&uV2tWvVNxLT|E{i?QKwmo%I9Ku}X46*_j{PDde_3*P!imUWRxPw;qjGH6jOpNn;

$Fsk32KrVzcG+zRld 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 z zP8$Q|-H$rxPNwid6 z(8}uP6pnexhrw{9={e0YItS*|sv_j8Qa7LrFUHu>?uYSNfTW~fd|LK9@#TIBX=`qo zFv@%CV_Fz^L^sZX6!5cXFr-q}g=m%xk&pled(_87E}rJJU2^5pg*OL6*5(}?t*Kb> z!ZfFD)L|5Q^s+#^O}$f)U6QZtzZPIEhiJk<$qBJ`$eeTjPkfq+NY%Jo#{r2Y%#zk9 zG9vxr3X5_VB*(nW#_bl;LUYp^w^D9x`bpD>h|UGT~b-jf?L17X81vxS; z%N7y3zQFcCprLTJJ8~Lfytuy^;w7J4c``F|@?owg> z`vMyIa0+?BgUb|k3YiJD_3bi5rgx+@@_tST7|kZQg^1T(sb=hu)xn!b040QvLJ_|? z=h&hj3&c;uv`zjvplsUm&Q)3_OC&t*@``@jJv#)ra@uFGxynN5asfZB;xz;ZsIKg* zfS|b*Q`}Jgv^g*<<1Nh%PYhOA7KmN+UnE1z>HWXGIe2?c{ipZ}A)u_LyBex*7Df|U zjYk(kOYZ0>`y6Z{9hhcy1ea>+1e0INSbUnSKYnbCvl(39|J!hR-=6fT-nc&Xsf_wh zSW4>lTJm|B_25Nabz17OJbgYTy?iM;lGSgAMqF=iZ@-^zeNHjutmvS-g`r zz_uU^FPMiarLyop->2R*zVBOBw)f3;_*3b`uF$DH~?1p~`F9(UK; zsrL&2=OPolv5u|b9?imh@Op}4AKYko-HwaX*r;fR?y{2^<7P@-d5!4$3SjRS{&Vzc z5*_^i%&BZ!+=~Su_wl+HR^~oi2$H5)z_;N}B(HqtsEn=0ZT8ms@Q^7;>(2egQ#+JJ zbO`6<6EA|7E0uLbWCf*~dTrW@9rF~k*SJW`$?Y`Cz^j~QL+$PkxCPhM*2)IvIupu1 zD>fika1;d~dKl%XKm_^zaMJW{IZi-hr-yzn)HQ$kE_N%E=^$8T1c~#=SWB*4i==rD z)#TM{n1;ZyB!QTkL0XEzZCYxIS)3YiP(HkkDOlJUDnopZcf1S4l?GtVPX4Pif|TzD z^VL*SbIO>+nQEp9^*9^RCBEdEPFHt7C7WGW{*`b7XUHja#4{=Ns$Z4XN^2~)R;Q6D zuEh)3=uCzJ=NXdD@_u3_2g-;=F`uGd$LM=c#!Dub0UhWV!wO7SpOheQX~_OQYmq1N z^a)AO8{Zq42q?f908HhnL~fxX0O8(ogQJp_s8dumi{le_c(BNDQ%Gt)0|D?`wwL1dz~Aa{edvX}tG=W#`vVRd@w=EvZwbrSCB|LMpA#j6@d5 z4rEj|w#$zELw_h;5g&;T;g=Y@md0QbXjD+6>+*}z9_|@F=tezYg;NAYN{Z|r0YdFi zleug}rgiGY1u0lr=Ce|nzy^0&=f9EmVD5O*#7lP0Rzm25;EtUWXQ`(0-U9hmd@N5 zWk&q>a6`U8eGQZM%`J8W}5M_43JS?-qK0ct7wspsGGSvz*OW}?S zZj&A#R>Ab{p&>ShV+>ef62>e9{dCkz7W{h3atbs<1|RnEMT5u1%`jFkO?#(nh3T*g zXmIo(0Bu-`CFY7GrYf+BWZ^VL*gx{L3$kBADWr&t`i`o^_%v79WB$vp*~5JXmuMeCHJOpAB;>lNgB&byRHr* z>+oOAq>rIDL@$?D23E+>ZaYCwPHB3!?gSl+4US#gUP$ev^vsU3=-^e69v(A=GpUy0 z?jGmpInvbgVn|3AQ7e{&PbT5Our~o4~78sc4Zql9BQEFk8NjrN#8#HqP&xC3&SjElRbx!PF@cTaU zuz8<`pj^VPAdEHDsWi3-L{nh|15hj;4B)-=x9eeUK+|wsvx>mDEtcmqa*}$9i>O>! z34$D(JyTjfr%Xcqowy_19Jx1vaf3Faf)7nX-YfkNb?keb=|Jv$ISg@b(Y|w#4Mw1d zG;qf%5jiTNmSHMXsu$lCG>7qjI7YE7V%q?k;Dgl*$hLIP&*-*qdy znz{zb+dqFijxWXLY4E3*h;!c*XRJ{$M^dLvf3}kUo>O2(wyvmRAAzmq7ZGwpHy@Eu zR*@U4V7t-sE4+q`X!R7pLbF!w9q^N8v-roNcf$__x%~ZrZ$`aztuS&nkaApCMVolp z4Z0ODFcbm>s~f(nI10=Eo1C$b>fZ$(#ahzOQ6X?}1&s#1qp;xRcF)P^OX;3}X5n+~ z;OpX=jYLtE{^>>6XOaKw#ZmL5%_*XCus6h^ zh3mkr(|Y?of+T?_O}Z9<@;4-LX$v;o3mEEVXS`N#ht0 z@jdBF>tAMhJJ;>!%wM>)BiVzS}^|~uWai{nWjej z6$e@aJho=1ECO5__lR^yJ=TW^-=+34x85M)yDT1air7|81RoJLkuiG)G{Q`gOn?5>_*%b!!rYi#p?do3aQev5Z80fJrhKtlrie}n zYe6T=fqlDV4B|<>f`7a5+&9mJCXg+;*~o&)<|vW8YQaPHAiG*=@6PgdwC5eJIKJd; zVfq1A#!<}zPi0OyV+dukm`c|G;Gxkpqk)UZKVFGDNeMY?%hs>LMp4_Cu3Z#Qc7uDG zb$FG*cpDE3m3pcy7tS&bcp zO(lXLf4WSkHMTmZHYk*z^kMEdt6=~hj2WmE9~sKIB351wGcdZECOJ9u{m3xH?QyE2 zl>X%XZmx5De}R>lC156s9wv0f;pH8|vFkd(t;fFMJt z&6l{i!~TU}Vp3Sb(oZFfgiJ|G|Azh5xdZCo+q>|PNDEFxs;Axh#i&I=PHR6v2ohmJ5y+ zHzMgkgAEHVSBafc|0Kj@3{8>e1<(wN6g(9t3ss^AE_}5%_EpE`zama)%u36143qxVF zMqY9h=>2UPL#=Ogp4Pwudmtin`w5q_r=W0O6pNFj;LgZ8N)EN0U`@3w8FF{CnjE;> zg}^|q{k=AfSJE{W2u8g{D+)vhIGA)yR9PdA9RiUga(WmU8Knkg26;r6EK4VtZsg!0 zxc%0qkaZRuG0lUZTa*LhTYEo=`H4P$gT5LHOs1NTgbhF%4l|P~k?)Vz`#0_bA#DIhhs$&V4gH#u!c3WPM3Lr;E zb3|;!;X|C2CRQC|NMRU3a)@*Jlw`*%)@^azF>}5SoX`(7J?E(NT`FP}$~h^sP{DE8 z%Wo2SvBX<3hr%NW#qnvI%MtQ}mp9uku>XWH|u~t^oQ>KEuYU*~iY4 zu34#)3n0{ma|)!F^>8)+H!izpEJ<8-OC}0oabV_z7fH5n zaUf16+Hp6qN#wOO5=q;if?mc0d@Et1!XM{!v-hivR?5`|{58){x2tYWGSwtAHD3o9(&zghQRBirZ9LeqhCk zbrfh1kPi9*?C7s(m8=Veq?V#dC zzw`$P-!tgaJT_xfocoKkkJWwLh}3Fc?BN!-<42fGn4(vTOchHQCK7R^jojB`EdI%% z6#Sf0xjh|`V$q>3QtzbsVQvIyKA?83>tPYnfEPW6!|1^`r}V7jXHPRi6}A`TR45yz zMwc%sX$!3fhiBBt4+hHx_ydN&`oCG6z9g`BnDqoJ>uT3Du>PXGtu8E+>}*^XjDFZbk|@sl z)_I4%7#nHx-R;%%_VT^1&gOmKv(icD^u&U3 z>g3YnmHu-k!^izZ`;)8l^I~j`^PzPNyrTY40<&gK-f+>m7Ko)jZ%RcHrfhPGRj1Ez zMZeeYd$D1g+HL>!J~Z@nBtm}N$+B#g&FlhcJG3LZ;DX(w)jHEM=3Os>PZskx zk!BB{Q>6cNqsO;zp!W1@9b>=4Cz9Y<)`Rij8xy@6fcGcC$HaZ}f2U=W`y`@J$dBoe zrk!8Mu>VCPYgE-==O$L+se%KmG{JlByw7HJ?FRZ_&tb42C8+BuG6#5SE@9s6AlS(N zt6NBj0sdYl@VXiPT_b%MTH}62w2_JAWkk=N{NC&aHp?p<9om~VKjLKeK9IbyN-up* zxj4}ux86YrcJhZ+1%In{ty2!OUY_Av!NFMcx``T?;wYKV11ysw)KdB3MT@G$C0FJd zI_Mh0z`R*A)qIm6Wr;|If2mFd(qa?2%jNZ{!>7AYuy~@QSIw2x;gMK755j(Ye4Fqh zPh`>~!}x)-zyD-`;5GqiUIyL+I~8aO_$|Oo zXPXB6e(b;OKmv_gCuz+oY4t4JC8OiBc*EX3%`zzU5$am&SP`^pk@BnDESsm;^UQ5p z6l=|S&K(Vq8M)}%Q>v<7JKkjuB)t*{C*#OGhFPA(#CB0I^y1GT@EY2727s@I(?Ev- zYeHjMx?gB90EstX3z0&03WsJ`v_hI{J6#_qeC`pRY%ywco^mULy5AQI;4? zwQO6!?N@;R``lLKT%?Iv)4{%6MBF3R2HHKgFP;0?L=AJORb40I0qPGNOXILI9=CoL z9EVB3q$SX=7k=UHdt%MfGr2nk!cKdL1=i2!szrAEuY8_%2U5QsFOz3zREyB0WcNi& za^=e>LK`S)Or?bHMvPH2vw;5;VZG-sIS;C_EmpuXafwmqEDyItc^WQyu^C#pI~jXV zl9c@lh034Lz^(WCjl#Y70Gx9dm;enHZlNnw~$P^hpez?5z~cXah7>{Yb)wYWV4>r zFawcxyp2*M(Jp#y<7qGyteYvCJw}Odx~r|aBqviPyIMFUoM!4jYBIo8ZKoSDFj2z|@ysB=;TL_uhd`RKVd+5e@NKrHN?Oe{=V}csh35 z`Br3l=NSR0Tfm#uU4R2CpOV(`RFFr-nAeAZO)p;bgvnU&N{l{byIOxoy;^{ytR?~c(3u$l(=^x3TS|E?ME$aD7$>4Y%@M5xF+oCM{dFZz8HZvww4?u zok8w*O|B{a&XnN?^Z;4RpEl88x_XFD4YQ*FAgT}hTdijBB-3^RrLTjPh>~i+1l5AX z=R&Pc8#8s``-LvK0I@;ftwrRLdOD&~(rz>RR7HHVSgba!?G8LaB=aU7CXj-aUqqf0 z9fT8V#&T+zCpOj+tRNjXwmI8g$562Yp0b@c-y{x;@ODz{_NL2w@FD`m3x{V4G&nON zNF7c`LN_imwIW+H7?WJA+!DHBCqycU7L(nz6KzXlBp+~9Wh3Lc`NezFU<*SUCN^%xDRA zTZbI~_ibuY&CyIA%t?sD1FvbNS_dg2*-3Sx(9sexd*ZQI0XRYE{&n=N{9;x6+wTVg z4qpj=hlrcP;zw9Q4GT@lrUI_E)Pw)m0sx+r9SZfd8!HPe|2a>(2wD>uSSq?!2tm*q zLTnvGLms#N{VJ0e2Ll5#78!;0=@tKZ$!>z{>>IRJc{p1fH;Zkdpq|MVXx*dFNhl)>qq3?65HUnRi@I zZcQG;fH$R<3!dn9P1W76ybmQZv4zjG&6-wDIT^US&QfwnHen0S2ykyTvLxlS6!_~E zG*_7}pKoBe3ZwrEp^l>a_EnDQK_z8}LjKO?TVYlt!P}zS1fY-2ZxZkAmi`aH zv~4B6d=c|7PY|0&#%xv$WH1{eom=aK2+Vi(G_IvzTB(S92NW3`9 zy`$#(yWPM3g6E!+t=sN-eFKM35LG7;ByU?IKH~^nKS~*Fz%_&Ur)bvwpp~>{|8PIc{7*yEi2Ng!Op79R>yty9q6l!+L`lRPQiOC!f*VMhpwC zfwdrz7(E<%tSk1+#19!XAD_4%joTm=nHIGb+{rbvbvhkKRq-R=3G@cES;2yZ8GB2_ zs@#*vBhV3K>BY9$AD62@!QUAx{(alENaG$6V6thjjMA%tTZ!y7BAyClTY~8I5L0e7 ze*lg~hEs+X1-Q-Ty>O|h>)|-#!|y3P>v9Q}`R)DSnxIi|YU4Udw$M5)sK`T*qUS^1L|xG(&po%D94$;ALTZ z#(z5x4zcQMxU0!N%>25+4n3IZtR`FTddV*Hal67#!OBqZq4l;?l4A2WnvaF~J$~XP zeF(77O?aq9V~Jtjr}hH#+RGj?bb-&#KO+^vjj8KxY5k$oalJ+oe0f419khM`&cc#% zQS6at}SnL#siUfSw4MhDvkTe$;dcd5gB^TOXlep1z%HxLZ^>B*EcLHuuZeW z71Y*N5)&rXqlX&fgID*+NbPkdff=+eMEGzk$_2+8-aJ!QuvFKLPt`(# z1NX)at8;j&pF^IhLpCpIk$*mlm207lvM4RkL!3yX0FJ7ykmX-sf4K1*g5O5_4*V#UT}hJXeOun4Mb_8>~Lt4)HgFa$&~? zk+CJ}?gs&1mM(9WCa>x}epOjxcX8a}uOr-m@(O*8$)7sOJ9c&xzTf6b>dVs`#DpW1 z*d$u?i5Q0mr7bt{5TZ{Jf>VHs-2io21cxxx(*3GMLPw{Vi0*O0Z}!>yM7(S(6w;K& z$Z+9riKCI*uVcN{LNpAgB!9MK zznk?xo4FrI(r3HcxqMc?3Q+H${N~uR>;WH}YJwKai^dz_;G9+0kHtA1otqJ9CcYnx zEuXm`pE2Iv%^5E0m)Y@hgB#|#aB=JhOd?nnOBv84)L;y1LJ^_>ud=B$B$9NZ^Sa$h zlml(4Sy{G^S*a&{?4}nfbq^B&DV<0AReIL;T&#RyzCkDs00lK&X2WcLo7nQ}VZ{&` zcV#|Oo|o;7i2WoZxjVj-iWiB~x=~woD4x#{tR$An;H^n{a|~_Y{V1=clZ@+nrct(7 zFbAm^?B+tc!@3n0pCK1tg|+f=iqj;Ghh$`kC|Y%8YC0KsFWlIzMB}QWD;=$508wD; zGP$Js;|}8+k6Twx;+ul_^k$qFNz&4?8u>rq?}2061^K;2kcpFFfD#WR$+!5}@a7oO zeY~Q0TOf~CT>#lpTln1OYL8pBgHZ{ zn|bue<$y93AHCUMHIT$!i3@Wt4eBnOczrj=7_e3$?$K&zP>T8rIi(w#I$|hefiY#* zr|Aly_}b$5F;8xOsBlXuA^r8z6EW5ctQ3f{gF$>9tneS=B~;QjmkS=3j^-#U&%BX~ zHt(zGDU;1tK99|N-A?w-zM_&WbF*yz_1K-@YceeGKMri zYW?fg^2KLpFZ_p^*6$ORU+X{dtxsM5XaCHbI_}b;OD(XlP{FndhPsF}sarK>l(?Rj z0~gBz%tQ3c&U4d4=F>wQp)b7cr)X_1wgte>*+|;s+1fjG*MD^f_?&wk#=$eILSUcy z$@x+G74d)ADgH^;Juo}XI=7rc$J$Y#s><1T$^OY@ZUpBA9}t8W=tN7G|JZ&=1qTm3 zqP(tp`?etE%QclVay*brPBSnEmZMy2{7@Uj98*9i3ksAd+J(;oWzxj2>(0uSi)tm| zaM(u0YrpBcvO#bbip+5{W*~zavgnCh?LC36l*Y>6EEs9wkn&!PRmD-1Gq6$0>NO9*e9%Djb$@&B?8mf?0MGsnQI{m9GT_$dQ-5Y zpJXw6D5>0WL~S`cRITIpD3LC^`}Xf>7v=nPCwA>SyX>pbBI&dw%f&t*i^5fSW(>|c z+QFo3G6?-Je``WqCiUL7JSl(}8>TGvi*AlDeb={)`q_0F z;p3VY*Ql$T@CuvF4m2m#6S_<&evwi5nqhsm&IgEvXaz}eToF zeOskE65oTmC7+ zM9zlYwkbVM)cdsklcwN1!TtEyGVVir-a|Vb3Ub-t4y4pVlhofJPt77eY=pZ6gTE6~ zJgp4uWG2unN5FLlKTU8EkLW;ub3HHdZ|Ig~WP&;IFnvb%Ojt*G-UUUW>?A~s^$WM3 zC{^SP4EK@{et1FTr!9f&vy8EU}cf+{$I4$bP5g0Z308Ol}n>ON_d#EP?bW64ymJW9p-v5uX=guA{Y(B zf3I+IeN%*V-5TgI0auiMyJFpfx{`3O%x&% zuwdM;SVo5fn$16`5RmY@QSWuZc$BU#p(Hj9{|GU{5EyvPb?(3+SsY6wa z`qN7a3yjQOEW%hY(`v;Xn@r48q$P|h!KDH9<0OEQl9^Sl2nHCwN)S7<`C9cXHzuH6 zY`Yf`MuZ7OIGBL=b9&+EA+4ds4AH&GJ>ysG!P^A_%hhTZM(Yrhw>2I^9(Lop3Qo9X z%YtS(+P1Pl7g8Gn7j=3XIz$@ydm1b&dDCBMW${p|#HJOU)~0fp61~7&deWln+yJr) z<5{DK)Zhx|4nv@xez~cRi?zg3mzk}QDKolh!W~)oWJ-)zzX?GNr_?Xasq(>bPDjKg zh2@rJcww0cdb!^l-}eQ`N%jjUb@88ru9UHCf^I66wW5>f&gvc~G+z%B9Ty9Ff(jfI zhZQF*yMfnSWLgg&Zn%*J7C1jASN8vu9#C6Ml8U(mRbx;uQXLq$HD`|3?Pm(;<^N2} zi(od=&&NBbr#l6gOuT65GA_qGW=*-Z*8WJv$Z7&Z?n zrrstVsxp|?U&#FYK*P=*a1<qR!AU)X*1@u>j9j3xr)H z24&v`<5H;_Hp-iXEdvJGsx_GL5)QQey=7*nSWPk}_RZSV+QsJiSHCy%&+84WcbH~1 z`da%Sc3^M3o3H&>l$W{+3-{Ppec+Fnj{*me{)Z3}k`Si~UejpTaX*g0DRxV1yCDJh zJI4LwHzZB9`Bfxh1i2P+`DngI29&Eb4f@G~Va(;4%M#ZDWCI1Ib zX*HNZKSqVY!5N$81f3s{v)L?P^FB?pf;NzRnooV+tFmCh!qJ0EBTBT5?FyKPT6bo@ zz3|cS+R}~McqS*`ynlV{1S`gFr}RD`aJuto=6lE^p6lEP`<5FhgP{5R@bmP%>!yaw z`@L%GxlPw|Dulpo>+{I_aw~cBmhzG7)8(eIt;EWzvuFQ7_r1UC`LW}m`Q^52+5HER z+tJR_p{qCcA<8;-A0^C0cSeN?hTlo&OEbOzg3%nHZ)}j~YK`Eyy53_GTy@vKv5T@> z8gzD{X>%D<@%nL-m4nINf9{&@`{1Gr)B9jJw6>G+)$TFPW(y2QLn9J+8fhtVFr{wX z)^+)x==5wn9;_i{TmuVUKX=;rX1HCJm;1b8H=4RExGoa*%)!k>PVM+{I#_3$Ts}L& z%^4%yPv39O;rwksp9omkF^37R*S22sY>5sQ34@U0s2D{*JF_dMa;?b+a3AZ2FfD?@(oVub)KPR)RzJ>|17x=)0y{UDeICcQuj% z7lpqz#@zP8onz{@;~@o4al2TGo0<*H()w7Eq;w@yS^uu9kc;>67CT~Pok}N~l?y?>M=sm!zDD*Aqt*7Eu+bpVc2Y*d`(4&x zc!m)hD5)a?rqRBGK&n5#)uP4AbyI-Ez6MzeT%gHmfY!O|{^;K-O;n^VuBwkppg!PS zAm-z9iprUJ05-{4-u!pz6W*`Eu9P!LoTf&eFQ%D!y@br(boLp{q2-<%RP)XVP`$(qUidawBd7Wa1H^*#r>%#5N@W}_JqMVVCL z;0`oq+4;ib(oPYM=fv~ge;%x+BzDvhE3V7`*izGrsF{`A!g}#pAb4~Qs!1{Gn1-bT zqx!VC_v$NF5o9d5&p{MOu-XH(^GBv8R=Ta+*|BDS9U_WUJi*;TqF$A#{9E~cGlLXoe1%K! zbsxAd)Q)He#wG5x44%Kvffy25VfSs|j|NLuGF_ke=Rksr%(8&QU%KhwKxSEL&^v0J zY)d&Ou|>AS)N+NaMp9(dEHW-%fQLx45J3miFi}@4=huJ{(_alWRizU*XC_4k@Qz)8;F{~Y^!dDAfFp(I){f9 z#L<>`=(R$_pu}Col!JM+4CsXe3^96O`f-251;z6_ty=u)*&?j?*(31PNMKy17}0;I zAYMia{&qN~B};G*ACw!QW#p@UZrB?WmTXN`j%pb2Hu@z*%3aoIeP|JHXm=8v>){D2 zE~_s*RRF*H@+0GjHgIYXg6EXFBSlP?Y&8R(0IB8G9wi`VA9#jy;TjcF6f@$}6 zT0A3}Q4G)#Ad(ZNeY6Kj(wvy_@w0Z?4U?BDbjv3AB{Y)JO?j% z*Fn)92>blAM24N3P*GxJeHeE?y+EEtA_#_(J&?S0cFfeF=PNO%RKd&f!dEg*iYhOe zliBE!Phj&2vb<=zRikXtGR-7G7)ZbfeC@KKp(M4#%=nwTexpVvc^O;c)pUMS zWQ!tc6VHLx4-b{wO(V!gI*We5PVn5yp7w2`I6>gs2%L%iO>%;{07%8Bq|+e>FN^Z**1E2%!JBoPK1O^z>OOhcjs*JG zmiGypH0m?TJk!dh)=-J!_Y+rqJ5$e?Qs(KO5n;54s`;etLS~+dE$;+t_;6!W)W`(R z8ik|;0_u{Ykr}!JPzRs8U6}u#p0Q6J)gsZQ zinN*L!$On|jRyC^XPtrM$%vxi79$d5g0n%b)rrLKWyxHE!8wNV&Bdx1dC6Qu!7y&p za|DE^;Vqt8jsu1u3Ra5& zm5O=dQCdU`*5L;z$l3L7b~Z6J0h?CfQmm$R$BY97O`Qi4f!iFdjXSe}hmC&$-iEfh z5#yOZnfo&=7opsjZ!pC$-~RhnANx$;`Xa5TsyXmT@JIJ0yFu%9*7Wmh{1MI73C`cU z1&<%g8&dzZ%7SHIWQxoGYi;zj6tEjY{iFW5&`_4OF?c^a!o--~X~0X6DAdEHrb?(V@xV{n)>{t~bi0-kHp%Q>MQ zDRX7oP=E_*1s2%5eCMnk^^uuEZk} zeU3W$rElHWE5II;c<&hQrAq%s(`IK$$xdn4Nif{|O8G}1%**r5 zq1z?&r8~71afOGM|_mrl20I9^H6FAaNbfJv# zbX^90o2mQ$8J)~99N4n@+QT=`B7Y7>zFxoYh;azmJ85*m zyI6(abvc@`n=jWW6*tX9;;A{#{08m|ZhORg+dN?T<+&c3y6XQrJG9V4&(pMW2J;Gb zrT(CptI(bgH_YsOAX94f2nW2Q?7i0v-4=F2x!}{K|4TKS%Bg8csPcNJuF>0O5>J4b z$uyPWc^}Th^-q`0fA#PXp@%OQCa&%Nw_r|%7v=gEXK0v5($~^`10`HF-U2Qu9M4_x z3^N(ga`ql&THm@Z5kz{G_Sckt|ErCOmEGNdm1W8t?t4`MFw^yM_au{!& zJA416L-}EEySN_@H~yk}=kNgOcQ}M*0ZjG?9i@%&gl*G#CbDu6a9m)JN73{yzXmLAbtd4<$Nj+Rcg9fd$**>TE7! z#M6^xZi%feF|`E>^Hxcxb=5Hyuur(1^I=cAiadLA1QM38(!>H$w^5XXW|pY>JXu+w zF*9Cw=Skb(k~39aqVajAy2xTnbRDt4RCSWbTkyQ0x^5w|b98xusan~Zm8;p9s#oNl zGXckh$G(lyCOMl5n|w3dF( zX+IJ4PBm+KVZE0Q>4l75NR5dpotPX(ZUN%sV#+9|^>V6<^qs0ZPvNdE!jD3w5uPr} z+s}mtxK+*V?^zW0EHTK$x~Whf5gyKkhMn_z>yp7?HMnfXSkO>MVb)Gy$UW{>O82U$ zj(v~SY#L4cqgY^Qp_>Yi6hivAcO-+HKb)t0{q*t>A06f+&~xasK~7H~7I@8oqQIrb z_>_)M!WcE@zk}>*KVo}>U4(CdT^SV;Lx=(n_c6;|q#q59_N%@xR=SDMnVj!b%6lg5 zgT%R_zqcG7uEl#YE2m?={=#Z^arsQz-<1vylp~{La)eqN#A8EPe4xClW7bqkH?32x zj3=awMJ$=c0(4`5iHvdyqm&&JG9!Ef)HE3v)5w{xf?WEJ38`Kx1f9`~DU+N-L@mBP z5p)~oXZ5Znz0Yp&*p1P^IJIt4y*faL;RotxR{E>ak3aXoAfD3mh3_mH?pe^CEi7A< z>V#AnswW0>p{e@%Oaq%~;gd?uz~pp9+9VdHk-ac(;Bq6_`WTfSCDL$|>X_^ZmA+6* z==q#ME*Ry~-*!LuWd*s00C~JMH(ZJim7@K{Pm#Z4$ z`N?$ANl`You8Swn+5D%So|9Imt{R=d((`o1&f*@Pp3W3?!8OBbc081sFJW$$ad2?r z5Q_|EWpOx(KwKFqDukcoy}an=IS&h$DbXj0=+gudE>@5aS1Qg6`XUXN zDK}3cOMeENr%TgRVVcO#Q{^RqU}}?iZm6^}P+T_SX}AbnD22OJ3K*oP;O{R62TLoT z$cS*Y+#mf{J6*}sE0~bNg;a@&6q(hUuvQgOI*A8DRco+f4c8oT+>@a~Wj01hS-w$h zH3_a!CdEvZPb7&zpt9tx%mu28G0GFFEy1pqJz|p!V$Ars#tjZ5T^6Zqm&r&e6rn`dT`$vSRgmChgH+DB=#RF8f#Wu0UncTV4oP9SPhUr<^dT9J5jo z!X+_GHBz!tMxpRpctZ^+*HA5gRSFpSlxQ`Wb_*F7Bl1_NOG;H#N(}|sCSQ?y0};mr z`U0kftFE|l)x^7Win zirT#P-U2D_;O^k=;O^k=;O^kQv2oRf658K%!;f6@BlD&=@OXdbXK%{qx3YLQ=@AW~ zX>Kb2TXEm=i+{L{eB6;Yf^1U2KaJxGj+ScRX+*4uJ{E8+5ZpU)$)-+?$7+n4RQDUr$4=A zmetxveC5jBxQGOx!y_>FT~-Gh&tuHxQuTgR~a zz}FF}eM8*qkLSIA^vNqDE$x5*uWE?fa67#7p)+gF$Z~;I^2?tA+Hke%^LsEZQ|e>1L%_C+GIF<*eKy+ZWm9MY?&Ba*3Nk z;U2CxJrd{SDX+i=MAk2GJ|6KYYE*p?!Hv?K5AsD$3%lgu1hL(Gt6r$BnNa7=2X zI4{n6+)3N{8E>@U_c#NqVP7Wgsg~^oIZrZkBs)!zh8knWSUbfb<6j>654DfG-Bosh zz~(8^I^nb#J=5{Hv7Vl$3JxB3a)hT`cg`&%n?YN|6-v7bH5bR(S$dW#+Yz%vE>QJp zyu3)`kY1v(MW(jIV2dQ~TwHaGIhNA-IjTBGSLW&3JXJ#;9w=;@%uf@=@tWov6hp#Q z7ZD4Ld3eqlN;}5gj@5NH%Q$&*L{4a|*D6g({s6xSz5unV8CPzxNrtwKpA^;ENVD0G)x%eXVz71kX&j z@SgR^GY)H4B5YAA<6^3h36BXWOCx7gvIcp5go_QbQN55t1Z5-FOE34(!5%s=z^wLC zVbvVieU9{;AvUAH9mnk5WT*$ZeQ=+^oM&-gZ^5fuagBwYdcW0RUofPW2iX{?b@<$E z@_fy9s_r_Ad(RQRb40M43~E-!AkZeram)eD_F;k1luz$LcM09+5fJs4TVCIpfa3eP% zW=(Q#QjOsTa}GZT^l*ra8KtyE&RZHK3!b(l!sbZ891R+Mu8GBYW7s#vAm_h>T(pbu z4RW#GO5`I?-P>D=+~+jkGdp@J6EG_^17A9|?z`V%e86G8cXHUk6pTXgXw>nbbMg`Q z^wFr(D3s4-!}mMPkGQ5E_DuJcV&hEVRLcK7o9RL4)O~idj>=9c^-uOZ|M2|8ciUsy zA^q*>D`&Qm)J=Q3$!YKReLscE7Brz(2G zB&zJK>NEyq63>sQhPp$Q$Y?b>Qi%+fLXgl5b(f$zM|gP#y_XW;N`)>&h!^J2Ckx20 zH-ji?H;On{x3i$BUYZ0JMXE$TVMrTSUt%#(fV5kn;KVo9*GDT+5PdZYQf*OJ%=7Te9MtrZiOWka$u{i zuy79yMX(Dxn_ifw-lJlvuMTV3)yce-e+zT<@)SiE5ghlN~Q-O;*^{%_`N zuKHJQAha};!d6}N(T>(86rn<`@hh5;-of3$MVULeS_?b4JGeWzZ#-OBC}Amu1yx&R zVY!86^o>5=PkiDUBJYPky!l(-)*v=(y#m}f-T52aD99ao9p&KN7duwKuzjV!?>E1> z{mA*mpItq!Ua#Z%C2_TTTDZ~G?sZ`o6}|end$#xm-uH223yg|h9_}?B8{Ung!$ILT z+^sAyvdrz^{@lMmVkl`vhaMi=b>Q$e+&yo7XUD4mYX4n7_cF)ZAug}6KE8shrT6^o zuN)c8YHEib9p81}PzQJKyWW3zc$3UMbjG{uEpNX8E{yB5j~;wgEp zUAMhs8}3c}55WPWDRh|P4z894Z4fOJZMWg7qeGe7#`}`T6^v=?bLb1-Z=F7K;=({* zE|(h74L$wzQ~AugeQDv(|Lo6}^hU>o>2sg@v~hIAYh8Nuf%~6+if)!Of~sZ0!Eavj}Zd-s=asG zp#c6OXj{6*jRA{Ukzrd{Y(cvLJ4(*)6-Dgy96=!kJ zIl|XX2fFDXa$!s_52-ze&OrWY+;f_6cd2ph`Z>sPAIsRETeUtHbv~Ey9F4h8B)reZ z11D3Sv*|!zX?28-kD(BGah(u1pwMbLlbkclIUSxHt|Z2pv_&Z(_FPW)G0QM~fa@ZB zkm#WTdNE~|^N7Qh3m|5(I3}!jQ;06_r;}%i*s+@JIOfoaYvba&NzS6UZP1!hFewF? z`CdBQMfl-&nGg{XJk=;qD>aa*M#Vs-#v&fQ$z;hVCZ)1oNDp&yy_oK+MnC+-cfP$a z_UES_KN@wKrOIrJG;oCzN#BF6$%nmDpLp(}?o7Bl8~&29@5`qCM}4!;M(m?x_G?pv zpBX&$pnK{;&s2XUaW)hF+SKru&HWF1WTj2g;xTg>R0cazZ{!DT6&DkVPss0U+C2R}Db0eB9Oi)Tq6#O$6$333ntY)k0 zD$Xp|>;*PLiv>}_l?EwFHIgq>x%Cno&(h&A=79 zvrva?_5aV_e}GAnT<4+a%z6v607#GoAaf;A_e%Ft@7>2sk&;MBmqs)qMJp13KnE@s z1PJdv0W7d?Y|r$x_olkKs;kYkEAPGS>gw_~E4{0%s-D>eMeaK%vZuE(3sNAlyI27I zeW$Y{BTmGLh%}M;*UA4dO1>^+@@zDXq!W%<%SG5H9LbiuCGE)wwlAq#L@?KVK5Vy9bI343ovNCuL2t98v5TZNwcs@u_q z(@)4N^nvJP#NNtQrX7T(q@%U84#Le~QS8*E4z$zIG^(q?e?}nFs4B;ARZ+2)f1NA7r%!d=jbRfJo>^4t1q&!g;E_6J_8lVTPq4=K>@S~ zX?VHC=LY>dAY8HuX%t!eVcFL6K>;#x`M>oj0GhbKlZOLHKql-!0*bIye;OdIp#mrq zfqlJkNQ1(uT_}Rosa?oFwTo6rO-MiymY&)@wR>v!)nOMF%H!WuVd;ckknO8|yk|fA zxo?8={^oD)_=R7DqL;+(gKz$q4?U*c21lOCD=)8mOw=LZm*%|sgn!qZ)NwGH{ii* zfxBM!CcQc+;CF!Uds;7gct?5Qi}QCq^5$c^cm41G&qKpUTm&G{{#|dm#W?Z58t;p} zk57*G`1l@o?BR9x?*H%`x?RWzg?sJ=YaD&O~WIAAkO?hhBGN7sh+fefRw0 z+mB3dN%#KOKRvR0*WLGjX7ae!z3=$M8F<4Y6NT-3cR|y@_`S&|JiT!4xjC)J@F6z;J=4^Fv5B#m zB;F?@7X-TW>L@TLyI66m%v(9$D;{|Y>psG6k=x=Lre zu4B{^sL@VVUZ;3tgIR9S>#gQatKsHlpP+hp#SQHXiZ|bMZHAp2A&)4}RTIX>{#K>A zyX3UH;*Ms^$#K3m=ZP1sS61EOyp3vE`NkGox3RQ~6>KcC%``We>Pq_nkzA1?-;DDP zf!?K?&QimZu3E3HIr7yVrm@R6Yy!2-HmgleRcLPW)or%w zW(5}~xP$xlW!HGwt|Mh1{_EMXT>PBJy)0B#yA6v{A4-M>0&a6XXW5IHt9zsSk+0dd zAK%)(6!gs2_a}>)$G5jZo^slk58`XB!elh`%#QU^z&o}dzZCL3v9+;Q%dNH!77D3n z9QG${*1=?GqL`enX3SFKe9%2nPcF#?gOI7s4I`Qy$)rUJ82`xcstO zxsnQ8PWmR>$l*W$T-Q)LFe@d^ouWl6&tr7B_#)xYohDJ^hMB-5ADa|n*J$4*jOuoa z!}kOhOz__qc6EXF=R-D=(`MWY%~rzGg}`hnI9~CAOci|d<no6){& zv~3%Awv1aFrbNJ0OBt%Mg<@nbA70uEEm^mW*6rm)z({2mq}(i*9%I5IbP!Bjr99C8 zVM6I}x#hgvatyRE`rH-DgG3gLZ;19?rM!^7)N&GWTxeQhcYtzU$T}~iTvsdMAv!(M z&WzXh2FsZ_HoYLF7ck0PW(oNvVA4>~X;;m!AP}5KcvmYSZri~CYhzpltPIfsunY5m zEE!@Fy@1uqic~feCf_M8PNL6+Mw$2k6@i%_VS@%G2l+;MAH&39=r)j|QQ3zgnBGfG z2OJBNssq8LHLYY)kY9LK$QmpwE18%@z)){UF0AG!>hb^gtDpS+;irD{(pR5~+f7pS zdXHXF8dJ^8P$_z?5c%zauU&|^uBLpS+A@6Ju`&cR&*Y6l_2XNMA6}n*CgGfHq|Hj> zOYV(7oWAt6(AJe);B)qsKbgF|(8#@G7_G2n1d z#3OU%brhc8NTG{qGRhcMD^%_}Q`%;#V0yX|nJ9` z^(aB9GeQ|ekm{<+s2VM3Ra!aNXF>%roM2sn`i{T4lcfW!TF{U)p@p0YgjxX;-Im&| z@ttBr+$*rLGM_B5Nlq`3AWrm(3@~h*&*xOr(@JZwsO9>(j`DaM9H+a5% z@p~vNrjV~MuaM9m!5{%eAdt|(V&nye9Y{d}RG~~?kB?Abvc}^w4+}S0@?p`2e8|y1 z{J{kI6bN>4?I$_#C;&Q8=Xlk}=Yw0N*cAB@81k|F)-TNXpg^je+SQd$?drRyc2Dhs zU{j}dPwl?S?7~6`ODTx{NzUtD{{~n?b>&z2c+V^vP9l0|;_*>*9iCUOd;QsX{F_dgMFUhhKKj_ytMdAVhhuoS)h|*=;N$Nr zV)yR1ynq5fw9y}i_jpf4hx6Y-ypKo=b=^lI8&GV-ixde(4S+w$bhlV9xEIj4rBF&p4^fLZbgSXwtMG4`Bx9kAH1Nm z!96${x&KQG4~<1nn%3Q}kL}+3LvQ(}Lx8oSPz$|rH@M^c2d;STc+DGbo9DZK;@=(n zCc}_niXJjI?)l|+y)e&r-gWO|UwiR1KJe5A9MF@~c>mA*%5lqhd>?rD{x2PQ`yN#^ zH*hMqKf!?fQ0Cx0B= z*wh@s&UH8C3AnA-XJ$rcXUD=3ce7cH+I^1YEzg=YlL)n>{g#-kve^ok=G3y z=9&2O|8L=@8-pg%4yomn1>GIkFUv2Wz&vt6I9b^x@&qI1krzV8Sp;E=sjpEbE7x)f zyoVD!tmNS(Ot)B%FKeH*d+Xd9C0ZzSv-PrVf4LIK?gg7nkm5ZQ?QAx^b;h-uaLnv_ zyct)$Z9Yh^6f)L&(`xb9=4?*?o~KNCL;LorUB_C$E6AHnL;s50#qmy--(}icbRGGB z+l4K@u`9H!V#^`4?Nr;ED%veR>(s7&+3js{Hj%PHDM#(F%^kM2%e5Bk88emJ;u^>Z z%r>^T+9qG#7OLBP)hgEA9B*aY&SYUYv!-KYAN`;6D_UiZ@UE_Cb(2uAvzN$6WG*sK@(Hp(?hDM_><<*1ahEUt=v+G)Ws+4)!u{#>~u6J5y zr3U)YvZdRwbg>1CRyS+aC8f9^=O+2Yw3wNdvUAe@oSa)!@}^D&60kdqLh_~k2|h7E zxsMUsF*agS4=idC@k%~E#)kCLYi;j17oL$4lR|Wu30!Wuj;ovu>2@qSx34bO+P?XH z-?DwzxOE-3o7W9n8%D3g=yMpiHkLLw3|pH^>ubifRVX!uJjR62n2Q+wPi2wci|hijoZB$3EYa)m`XzaXXN5d}^g)vO75dy8gt z_(cNW6|J;_9>ICou4+X~hlo~K?i_$J%-f}w6AZ!BO$spsvOSc{a%oY@j1sgOWP}M$ z@bMAin{4VFShUhKpIneKh%a|apl?x2%W@7%NpEfATxdZ`!=YKz5Ct~KdzYKe1#!=? zx?(vj!&xw{Um?iH^xWu-idN>shL@9WUl2sBSrrTm38uz z6)rlFck-;Im0zf*42`{+YE<`=-RA37p$=E2F?BE(OI@eS4uNutZBsMn;M&MC%+_Jo zF0_cle$^$?+icA(2p&OliL8Y>&^>S`$|0~gRtl`Na!ZYjv6bCmtI(8NYw9xeKZ3+UH8ghTd0A7EV2ht+m*gRa0p=4y%AT4J&id3T=De?OaN zCAn8sdo=<9Q{BUMuTORRElxg&+zR04DsMy^j)s&G)mobJh3mF(!=7tLSqUS8sy(*T zZLnItrR9>eH`DfK+JOQWqm-=JDRnf&L$y9S()M~(kAST`jJnohq;g9fuqXW%VyPIJt;TBwrjwJjlB6`$YF=5`l-F!sh3j@WO>3*YhR`d40OsFp z_xr7ED(>}L9hr4!X+2K4C@t4k_79k-4r=QXsO^-w7+OKvVuCmmNEZXdk)G&j#B-6J z0u>be`lPCZyqMo@pjsbCbc72N@D~SynGJZp)n7dIN8E3I55*iSakKJ7k2ctz6&q6us*|r4a+pH-SCVH>$kp;!y^b;^7W@cNZfnhefsK-a!dJ0 z$g={7-rC91+tSCoy5_0fQ@f{jUyxI~w~B5{AMfg#r*=>6zLIufq11mpg$4DIH@pd! zPFQ7M0lP23c;E8YGyD4|alNx6BgdNGx!wC-^TR*#?(A*QeQ{~Kl?vA&Em5p^Y3f-Soui){?`#a(BdU|$6dz{ zx={2=*gX*)?%NUa4gL`m>)k*3P0`_wTK;Cc_kGLgaL1Z&{E-LFZR-lR$wLeIdw=;| zdf#9R{ron^d(z_V(cx}s>c{uq-}~S(s(8`NNZ%XYRQ3-rs!h-#v}@|HQvXeQ5T?i0*vwwfBE|{9E=4TD$i*|NOygeoPZa z2()#p;*s4GO+n)JdHx4oN5}7;`sK+Ad+_dk?b^Wa{m$<^@zt-^tCjwt7L59S`?r5H zx1W$@j%rmp9Vr%z43Av9zPYBOz;A!YA7r!XaL_++`J&CX>+yL$_l3_p9acf2jZ2G< zKmO%n@!%%ID64j1)YJ(l`+cb+(}LJcdcw|?UHkG@*ybtaQ*AlVD-~KQ30hT9tCKW_ zIRY7^J6=(6iJV8IeKPO3g#!CTg8%ZeN06L|sz50hRD^&mdP#sd4^$C&FDH{vuqhkM zx>!Vkv6divDB5LDIu;!sf&ynss=?KDz04CLN-*Ei|ocYpI@DtY_A#$`)O>G!NFP ztW~VrgfEOyxRVS*WMCnL4rq z)5tfvEmXI7M5(Ogi*={SUTJOX=-6k!VIl#_kQR2eQ(05%mO|3xvYGrYOD$_rt48@? zii?|+f=R8I)RI{#nK6b~bw#PID7anas!OJom27-XuFcl6U*FyR%k>QdSAwDiaeqO` zF35W`Vq!*!&xxs7LV7UDgvPkY<(8AUkvgwZ-XY?AI@E@3@G9jQXt^%8T#yd}3de9Q z$W_WcC#B75VL{p(WkaAp#)Zx|Y_mdYPRP#-xd|=`?GLtnCu{v}0u?Vd?Zb?3QQk9` z;wG=d6mVH`iIuPiQQg&5qt|ZEM9kH!g|A?|GPSWR73M|6UQM0+NM(wcd_ZX)N+orLsLQ&^r05cn^ZA~xkVAI z_hfMQ>8O3E7KGU|$Z)W7vm(rDc0owO+%76vID*KMq2-s9?2-(UF(FF^L4-R*&?&gI zs-j2mtdKS+nZdRP5$6V(Pca4gE1iNtN>6j~aW*=}glEJg2pkm9H!3-cR$Nwdb7C4~ zS;@nxg7gt8w3fU=xuNr8YzXo#TE(K3U}j(v;5ZuO{iV%yODVmsR@O9-+FGxHDDV@X z8EQnQ+0?rxFMeWsak`cHl6(D~;}=%cx=|?o=H0nR9k+IS}J__O(;EBnE< zZhK8@&eGZ6A9?yOJsV&0tiRthF;a-FN)1ykzQ&a|d(1n>E_}|tGA*R_0m8xkf^5=H z^~e5t^jh9CQ4LPk5R)A)c*aWsGqu0M>|5EkgQaaOW##Byfw77$3sqQeSKJ~47t~@s zJrRq{hSM93%5|pf5!oHKWoH>H*CMXIO^=8Syw_Q{${OoT$%PcX3|wedu4$}ibsk<_ zbhq5)Ru(SCUA}G?n{K!sg*Mo_PM5cs#s*!PuO~*!f$3@lu3{6FgPwpgT*$j@eTPGV zUb*3JAhyv9m_WmXL4x(5J1|FBiHnv-X0(Xz%p(Qg2tk2IO94Y8v&mLh+eI6)VQ_G} zvvQ5qcHY>`OqL_&cJ5ziZ@|s-=MHWn<1O)H?GXf1(8^lBsdnpW%Bz$1dMlgzbWqeP zY07s*r%>HGU?aR*QMRxNb9O$E6cYG?(i zbsI;bFkO|$Eiyl}kXjc6xgZFx+HcB-Wu=D|H7sf>3f;{e2p49$(PUpkq*dyc)LyOA zuS@+B*UPh7zTf4bZgoEwv3p#xO;2SjM~Bs3UAxhubP*P2Ctv5f8>qu`uXDbP!L#E zVM*0jSP;eTM3-BY`y=+y41UD%%5#nh|J zE-sX0#eC@D*W!<>uz(^5)Az`Df8|%d3EF%9`8z)ISp6~kiZml_}=^O{pEK(I1)NS zKR3k(r!)8d_m7;t|KVfKV%S1Izs>QU^gh1xwQqdUJm0bl>aTkf=;+E1jYZGC?uVd6 z*VO0v>_e}==XXEw;Ar$1)qQBC_27UDIt<;`o4swkD3J4G|Lnd`jUn+d!7(3Nr5|{5 z{qCRoFL&N`_sQsRP(|<3NxOIc%b&detINj@(OCDg^X~unJ9okB)35%Ko_YV{=5J{i zP5-N(Mi<~)rqN4xK7aqm2H^lf6;S&Y=hdBe-TQz2`){hXqrjX)&Rzfdr|*I;{cY#f zeGlIE$6vr&dKF{ku7CIIP^34Gt?Tpr+Be?&dmlXMUksyzLEZCT-gWn_Pf|dz-pS*8 z_dWOg+h2b0lKrR_w7-zQ@4a6?`?@#X@!B`)2TuP@;;8zI?EbCe{Rdq~q>UHeLxWal zqgsi&ea}4ke84UEei6_SmC;^v8er;SYZx91iC5*|l|ZAn1PX8~tui z{`}`ZTPz;zr&GqI#Yi;N=_qcu^Ftr`;G>Ve`_rHPWO6?)cX?4|g=RzA_KLF>Nn@K- zF766CS9Z1xmayI1s3QK$Div943Q9%Ls=Yq*Z*$)`6Mz0UN;ka{k50aVJXlb|Q`?x2MiqSY%dD4`x7mgs zC(6OoAX{|R*vziA%d73u7GGUJrqTUvwq_R_Rz$3kYj*ER+TwYf5h9eX> zzap27*6k&e+2nDW>uHmmH_EvsIkzBY%~EMaDlbU~(_C_ljZAW}1u1Kk5K=^dIOtwU z1XtD($^_VkLvl!fI)`a{y|JFJ2nt+T?=`2JnO}P1GgFPErPCNJ1pj1q;L}#qm)z^W_RJSPv_Ac( zbA!M1_0OCO+Rw+GpV>8jd~5O1rQtuE9vG>{KW$wG`P8oQw+9~oT5xx|vG=i!h2OmV z_y<>}KD03UL~z?IH{LmR;mf{tQ>QR1rAL?m9A%i~F9|F93IFH+b8MmQ9x3?7O97A_u8P<$-?a1Sp}$02j}ee9`iBaz^{r9`bnF#)C(rM& zH7hy-m#u8m#y1Jh+pr3)Ee@~cZJ~*j6k>awDz8(;qZSAuU+jC_!$yq?OYuezOS2M*YX4gu>DuG{ySP*q6Ma!%=1 z&Jt{={vmba zkkK?&>DLgM)j5k1V5O8sRkQlUYla(#A{gouuobHy`*4NU_F3&fhhODR)$g$G+E>E| z&LW#&BvX!Fz4RIezVNGGRG6tjTwivm)(yfd?OkwG`G(eS7jf6xP%GA9x6sS4hJOtGfW} ztPzj{>7(!Dpc?GJQ!=Q+3a-P+kg21A34uHu z;4avKXN9{6jT9+@X8;gLVh&^wWo$}UfQJLU?yV=wQ@f~qY8Tr&wR>v!)b6R>SEF56 zC?9<2H4ne$b-0?Ifu^7r_%W=m2J&hj@5euJ8^CwwvG+ptm(cE8-?4ELqdb+DPwsfn zU%&NNFW|(#bm!IC_x|~9XUH9&{N%~w`>oHb@7OLR{_gYY+qFv`dEw#s_(Ayco6DaW4Pv=?B|DLd`dn6sdhf>r*r$cKUfn{5g!rpjRzHx)U`K+RJ_$T}dzprXtNtBpQSG@6Tx1)*8Ru!sH?Yh$Cd6iK#v0JOl zOIzH<*>*A;+;n;^Hn(Xv83BUB{qP?EXM&s14Mowc&GN95f+#)I;Qg3d_TPEp=A?WXAUO2M4ZZI!F;8sja{ z&W*5R&f(sSSSPo)O7%^;W@#1IsN!|HxnFTR3&PEA1 z>lmP%V@%i}<%~++pcD*V+j78ZY@`>2{2Z5Ekg{_^dXVy6!T@WI!S)d#JHiAe33v)c zIygH>BU(Dx_6%XdH_Z4A>fW@FxI!S{lcWu|yoTKiLUvg_SdcQaLTa3iK>O$G_A8Cx zGxdWfs@Z4i{&RIZbaIl5PqGL^-UcOKYTB>SzELhTE(E5<$b=AuzKt-UX)(U2WM-w* zFcZAi_Dyin86i0%B<95QG$zmq*Q^#yN`6@?&I;)v#&?bOl5Ts!+(65HspXvH;}cwD zhEFbt`!EAjTzrCw4>A66E<7#7CI$4d9ca1G374RgFq|ut`x1rZ3^#MYsoa9m&)N39-M zIt6pLXwvd956j8{G@>&Wk8n9;Xrx!$g@ro0)55iebi)Ge78$sl(V4fkztY~gIvV<~K0VCk@+Bql<$)x>xyI9?8}whwms+B#EOp$@j$sz+qK66X>*uPE8cjfHRx z!!GL)8J9p?sQgc5@hURCN=6@*sX-9DvtTL(#W2*NOzFuq1WM&?V;Pg-?SQwkg`~hOS6xhtos!(CX&O{-s9Ig^HW}!rTI_Zk zQnyHHDab_d7n%iIge*emi#Q^SAWqGslkFb%1dBjA-Fkzsz@iDyw|Crm_lw^{VM*0@ zVfnr9{s%!o4Fodpxy8i~yBHl#FMxe0gPO2~U3j^LhVQ+PeAz@6Y)IUDFNRlsVSy)W zJcz!QA1~^9=C>47fO1HKGI=04+SNt8^-t~oErJTVp;No3c2Dho_w2$# z32P`Unjrd`3cJ`WDgE076?8+dg7Kc6oxKg_yZc@5dTH&x<(IyC-(xp!gDg+wrIpt| zCj7`x{V5&?nDdwFyn6fFZ#y^OY|%?k3To+|AiG?z&r3a~ zdqcc&C?DPsp|sbBB2nuz@Wy`Qh6K_*M=6Am~2@?GJc+;}eZC1d9+-q`L1>VwoU6z)af4TQpXX4NQLHVZc^XnBQk02w` zfm9D7VyOsuh(1w5L|7D%2v~w$^b7W(4yyTN8Mee7_!jtkQd+#*m9o#cRH`=VFO)WK=7K(H7yid^rv9K?b@M1hV^!PJ14=hyK%D25z$D5}d*TYt8#Fj1E zjIP}!r;VcREbHV28_(>p&Fgd(WQT1yMS7QQxj5bFrW4yQG0 zZ#7|1PJy-Z)DG9&;hVcc%_`Qn*!r%}*yifSM%K{CSlWekw!Fht7sRxVg?*V`FegK1 zA#YT3Mk#A4r;IyW=AheL%NV8oC1rnE&M!;(MKL?WrAF!SRg7$gKDL)Inwfiu4qyN= zIyBBkC%ME@+-J0IFB}BM*yt7F`3nl?8@2%oU3v#7H^>MRoZ@5STxf{#PY4lGH$qr$ zlQTkmoQqsVIMqFi9=^#-EvF8Z65Q5-e#8P8icRy$B`I%^vJ+fnT8Pa`$syWzq3OER zOg~Z0K3(%YQ%7(adWg8Kv_H}gLRtrEp-t!*`us`>gPfU_ls1EXWy4#R0&*aT8dqvTo|y9at<-RF*Y>9hG07-#9#|! zSrD_(!Zeo{r{kAf&H>6bNaN@RDG!0ak@*)oHqM2o#ON@Km^gIr7zlnkxBFCd=X}m~ zx#WJPuzRJ6IOaghIl=~@GX^DRM4#M!qnw)-lMB+`l9F3OkKinf3nmIWKzw-9pktDA z1{ty4B{^$U4pxvmIB)5cj`$)#lmcS?Y5^KCbq>baFxa|CV#mRDgb6IjX_%Si&Vi|0 zTviWY@{MwSm4tvp6c{;zq56TjQ-H(@*+M=-!&=3xm5n=_=Ag&Y23sZM6xPZsUF6Mx z4lF|d5z3EGajAJByC~$AxPnEgt#+DgT5DBpnx!g%gUc4BvDRr?)W#B5Gz!po#UK?H zTiK;td@d1~%*Rb)Wld|WcN<1250gJ7B;dptXu*l$0D+mm+H`)QV%AUokIVBHcO4VH zh)YDTSSwFkIm*hlci0w)lVd!b=n@&1DBE~yo`h@LY*r1a?4&m_lS&(#dv@YKyUR9= zjlKDLa;dqu+{&%A@>_HjgT=AbQav+K4o#IKrdG~EbeS|ChI#WR+a*=VOXKvdjv^JQ^Of`xuF*IDfjfHx0xZp)^;)0Jvb&D<5Q@T?y zm;iy@*-Cu1Rk+@+Lah}lXBV0tk#k|xI2yJD?FG9Wi77`Tq3{t3%ppO9h-|{ow0PYe z_zP7=(kfaH?#vC?5_a9T+HDlrc(md4*LDaHeB?#zE^nN43WlOUZ8yh63v8?+rs`6< zA|z{Kl2-Ovwb)h;#BLd5xM>wZt*}a=#KjX$cdX$|wmb)PMAT~C9!8MscG#}UBS(bF zD+;F`gQ|!HGkuvAJz;6aawsvq9;1^Nlelf|-XYyPM93IXV*<|hdQDlZ<&yE;_4QSY z!5!Yr(g9IJDxs#b7physbw`a)D_XUS<3)#Ju+r((1*J&K`;2lRcdA;iAtMn)quV7k z5k!#r7qR9BB#xYg2^LITo6(mU`XFnK98?ggyZBrmtP|1%kv!)b6X;F8*9fVy)`yuD--V(aUZ3r5x{TUVGN% z{wA>Rx##Zs_y1mR;iaz)&Cr8pfRNo+!tQr#yg#sZ?|%=UMBl^Eb?_ zwcoFO-`BOzY&*Pv$sEL~xBn7lm+>#3FV8^VAW=seoIR>BlvzSZ-^daYd!ZueL-+>x7GTG9Kop0OxxI;uOpJG<+u^TX za^-0S7F~t|I=K57nNQfwY}uD-rpP^lNDWBPFI_q{;?C%8N}Lhy8b$v?MxO$0T1|$k zd}ek3Xqk9-BxWLOu=f7;YdTP2Po-Gl!Gn5p$@JlTHs7~w$7`ftA^}~d3v)|i*p9t zw_TXT`t?-Ca>&l({#`J&*v&9SMuMk@+RWk+ghNPV{lztAqp#WH(~$uhLGYj=&>!?E z>b;Ffl-z86O;^r~3LMh?lq+NX#zWN#{wyal_aT=9$5!86;2_gJmkvEf$7NxtASj1k z;uINqK))$u&mZ<>Kw|J}L8o=B-A~HE6$vXkf8`NkGS73E7cthCpB}TaJTsoZk@LOK z6>yCC)(gmV2TK&zxF*CEB`UR`G0LS$S?RuFo7GB1kB_l17KN#kXW^{!&_HF#UUy6X zAx#ae=b{l4Mrvmlk*ww{OvS^YwNsaw8offB^8a;30zC;s^*BmF9JJJX&K|4Ve)wa8 zvgB!yJ&}UD6+r^pB)|&1hts!QW8^p!wcEl(xxv6K5&%g3aPSpD4jmy4x^{Nq;bt4$xvvU{-d8z*hOpW1@aD0sjmWlm<%( z9dWEqa^7{=F8gg8lETp*4O8$ZR6g-J%U3ZRe)P{gNO06JQ8UQw;0yKGO;Tk6bl7dS zO5;&;L@Q)@%#G?I?*>)P1<5Ik3A62XG0*gqeUaKr8vy{&X%T8JHkpYn&OW>qyW!8X zUT*wsjC*=(yYF_DzulsAGi@wt_I(t@s{qQ?<>uCE<>U?=66qCbtxzWY4%a-tzFduo z7_$TLS7U$5sU;w+6A>72KUDYP%Ic1O(XO8O{=(+HG~FD-9VirUfYa#JVhJtXRS?e4 zO!j4YgAoW_SC84Icc~u3y1+(ZYhu#YD0GaV=aP4E=FHYHv6Ov?w$9vgIj3*Gw*q0GG7jE* zT{Coqt1@#2uqu1gsrHSlI93GM%cU01oc`cx71_IjloY`MWjkJ1CR#MF{BDcj@8{EX zsm@uq1n32$WTS47jLI?_6rl@3`jZ;$fC=z;&6%rw0A>wJ`lxt8KwIw>_mZE<14 z#wxeWENx5aRrp*vl^n&5_T~G+52h<*L5To2k`;{&xCQqCBz&n_dzd}Vc{GQ15K=% z0#l~0@!j1tOpyYIV0{A?87qZn{QH^K?ZS1bk+95A{LS zbR_lttel4gqgZKk*m3FXy?;trOTRnr3%KSws^F_WdHkT3G}tE<1qdJ&*AA)WHeUAs zR!Di>)e}I1AK`7K>|ywCge>&`uj~OXU}~S`hy{Ql3=S+1R_zOV?1TS{g~jz#;*Txd zoSvJz*v>}xi|&W*mTs2=&c|!jZWm7=ab-@Hh40$k?d%n0dh6T$bj5Nv@>GBWFJ(p* zpWn{bE8&R7*5dq!BY0AX-QIp&ck(U;-$tF~bnPg-Jn_-{P@$SBug_eR7ID zw|cZ=YWHwkkw+nKYmkXZL9lE4Mh62Sgj8)!s6B@V(@gnb`e)nX>mTpX?+4e-9z)vB z;%mu~A}vjZa_P;kuko8m`SYUVqXoksQqMKhgSj7x*2FBj(zg@sm-^`~aCYc55pFvg zD~MiQM%{no_w+#4mX*minP%g{5rTF2aU2&)&^#Q}cNz$8HafM+uXox&hB85=8y7;L zT2#+e8)bl)#g0JM;oi)_G6QR-+{8?thv#DI1dK?)H^zel(=XGEE%gme!P&+dB5kus zu`D?{4qWCH5qH|N`?5Tfo8R=>ZEtYv#cK-4=*3+&eI^Kb9eEO_vdc_XcRPvP%_`&r zTAUiA_TD&#+d#<8d+A`F%m!$n1I&;;d*RDaF^~Hi=ukahOqd^ViYjN7EXa)T!ux(V z*2AjV{>$v8dTdt{`6VTbvk+)615N)YOS~Gl_?0~s&#WI7MtM`|D?5#t0~p`8=`xSat;iQ1tNE9RtEy^mMVFr$sqXSUYe12OpTy=uptn1cde^y!s$e2w8eW4`e z(GbWsbDdQ)#K^^ea6C%l)N}?>7!FBZ;9E;#p0~r=C+8ODDj&?y4mBO_Bqp_oseM3Z zLVrt9M^ap8M)TR1$OzKwQ@iju*9@W_7!}49!u&H@Cr!iN{}hH}TKDM>4XNO8@USKY zAhg646X%&{YS55`87nm$fteka?I$8mv_&Aw_hTu_zNP$I<$0%kYk%6V7ggH_h)tnKuIoWt{U_m z`Ug+8s6Y}XCd}6vqD!6|A{!aI?uKX&7V<>DPRt~Aq9lF}GtrkDV3gw{5aX_ty?#f7 zuS{ZK4Mo)jw+rE$P2yZ^HlD3p>gQ;1lKY)!kSsEayIa=E(--Fw5`yIWk64Cb3^^rM z{=(vaGte7{qWUx^Hvto+8^HNT`RO|6rM%3I6^wDmecFM+XA7ntDElJ%~I{OJjdr~<%*4$Z3E&9{3~&oIa&E^ zH@@=+YLo?G(Y6dNfd_zI9=)njCqZY*!=!2fHf@hQfZ+@Ze=9h1`l|{@i?hvH!7ouV zSU%p5IimPYV{4$TTU5pQHIii?X|wQOzb2@X)n-Xhel_9qH!Sc-vc$HHzqBWT{o79{ z>Os9}WK)6jy}E5-1!(-+QF1PSQ-_+_56Wmy8&K(tJWBP$PDsjC zqq5HAGDc4r%}%g6{&gXQ%+jI<>4CEdeuqrue zpjn>FDH!s>5Z78X*9bRItt6_ISzJ*Y+Cr;2E%M9R(#ic}XlZ?URELj%xaZnjcO*S3 zM}Fdkt4$XpQVE|P0euZNbkoeyBAkMFLloMX{m}Fybwj=W(~Mj zI4i(X#sHrjE&jL0`UmyBSl7!6W(Y@8YJQ7=*D~kG3e(+=vmdM^17_vOlo&4*HCMB!!3ks zVpe`dDvABX0z7fn`*r4Osbv?boqV!yBT_b_W2RFQ(3Y|L| zuPA>g9R`i|=)~@adN!|QSa)+t776)p5Tk@o#{f&%7SJt%%JnX_f;QeGVqd~e&7Ow+;3 z%(F^Q*9t(`_KX#^%fuL)+rYbY^z0+hB$1q5`Pbc|Q+yu`8-kWO-Pa4E*D*2AkO*5j z$r)vPoA6w%Vq3|)uIT}7)HLe=jh5S@bGfUTTQR0;-9E1-TU=KTvx&hjq#)aKRC z_D}6hRec3Ndk4D2#mGQVL13U;N3(7{dR+Ng4&Fo4PZ4dZ=~2Gse`qH zFXy2VpraJV2Hhqkuo$H^by4KV{}%23hbg&?V8W(z3Y+MtQsm3 zC!C*AK=5CizNMu?g+pQ>|B^-v+W*Bu%AFCVyi}PqNu~IgsviiY^|4RNHNW;z`3LqX z&roUH#&`(il;$Jv;=M(3rocQ~K}qrUgSFL#W*>JFTEaPh`)wv9`XoK@j?6237i3Vj zmNRuKn7;B<gEob8s`{S1XZa;@kvLprxB~m zHxuV2-bOf?u)2F(XOinBP}NF4P+5 z=e;LOhg$!mIS1J!tx+XqH~R@g5kV$DoZ_!M}_Gu*HkcqJr zj~+=^G0*J_AGc0w>Wl@F%=L7=f7Crf?X0>=7W(+yFKQ|8#^c}~F7dRX%RhbkxRn+Y zR%Oi%XFuhwKCZGq`dL%qv*8&<->q}zaGc%^cIBAMB zhdc{tov)(R7N50dSCjfI$_SiNA3dEcRPuQ83P6(0hG(zt-ziq(gS{jBQnzGRw(%Jg zF1uiXL6qDY5N{wN2l0ojwbD{exux2@B3mD6A(+t>{C_e3^7XgQUL#~xim~dpet#*- z$v$|Wl@AMzeu-FF*a7Cj_RhV}=lk?EYc6;rF(d_3gP=hoES>8jvb8@>h~EtZec+)x zYHd$=YJ-E2=?_LK1O%vRZp31B-#dIAw(UA!sGwo>BfoOaVFQg>w7UTTUUNjegepG*d9|q2>C?1 zfLar*HyW0u;rDO5rNAokN)oNX^ek9g!IV96kq;&b9#DlL^cm)zbJXEG)#G_N(2hv( zHZoN&zHapN5!|o(wmjg`$-FNbPvs)G5cEGg!RONtsJG)I=TV{xu<8s%fiK!N^%>}#r>r;W>)q3)&@SE{i@ zQ!T{-_%tL1AaxIN?vCtlxF*plV`Ll4*Mb`yIfN@M78ZtnPM$vTFVqivB`O|fgl3`* zB3}8~+P7znyzZqyX%Txv$rfEkUMjLz-r*2bNb^8)SI06!u!ahm?VW|wHQCvKe5E3W zHRz7?bC+1(&QJ-V+%&8c24uz;=;w7V5BRvW#5rzFc`Jji7E(#%RltxresIcKkdWzM}dag=gW}og6_Z#XD^N^iQ%?G zY7AT>^j%%^=&0`#@wok#0V<@FB_V?p#9?Cr_f%~w!KfLAg}ecu5&c^UgU#JAuXP7_ z$Ac|GFsT!%J!f%QATlIz%%HBuOI4Oi(fI(f?uR(-x8v#JZYbs`!yVLSh|1W=DN27B z$b-8aRO`QTphy^@_Y%kfR`4ta<_V4!uC6>uO_IPQ)^~>LGH6J3*%W!SC%P3>L{u+W zxI>glIN?ZyiDL+M*f)aV0Z`a3$1sTllqDW!mfYx<040*CC~8N$VsJvD-O^m57Kg0K zAiP$frXCLoiM-TJddj}$F?sc~E+ebBU=%W7b7vEclbcd3jx+ezBrIG|V-J~zIz{kL zH=bPAECpT*?U&{2?V86W*B+C&#r^IvJFa38I%}-Yuwm%(4J=<>dG@+9uJxp!8Ak*F zJ5w$!KozBvHs6!Bggf12NBf2B)ZbGGlrJMmJcO`B+fbQu$&b_ORU$TtRcN7MAUVoz z&FM+bof7w@@s=#I4lO$zkv1)VFJ9tI>X1^p_;P2{?i5XHQ}yy!P8}T^09=5BT{3Mo zo45(ak=GeP(*$R}Q$IOk1Uz+~c}L@zI#(LHOh={n9k2K}1Q%UIC=jsT!4GPogARmq zYQs3f!zrCC#q_z6FzYoW$y6WTHY!6SpJAz9zCrq%i z5jo2T7&XI;P!#}qg&jt7cH=$5q(;2ZsG`e|06#rn#_8ehDGbQf*AJfUBIX z3zav~V3toL+-WICs(vTpbF+F2nf6&JZ2DDEAMS&dYmWj zaE_OT7)7QTXdIXpQHLoNnwk7iLMZQARY!bcJCk711_eM9_$y>g%wYYhk|M24j~nELhMP- z|K&uXEAEHcsb9nZYc4^SC_RLLPa3^?BuBLG&+F!XkAqf*M;L-YNV}pt2&+1V%ib5>~A9N z%?q3ERJ!jQ#cs>@?sXa1?R$QyeEc932dOSO^>iTWh+O3S$B3t^&I`cXe-9lqmjVql zZO9?Ztd9u+PTQMo)=1 z9=sZR@aELbiAZ%o7#IIAX$IvzIUcl~#J{oVSk7SMJd7;K{`$H85WaRTY_&ifFgd1a zp1L2DEgG9wWiieM>?YOt@in=rROTJh&28lFFvLc|fu}Rl+ziH~n*BH;Mw?(?>ONKI z@u()P`U~bCy7J|dv(=UNZ~=a7`O0K`d!_qwyjvF@4PBb0ucB7WrZqDLtkv&R0HTlA zPESe$x2WHe@g9#EDz^Elx!>&S?ii}ylP#8sef=H<{Mq<-_4PJ2b?$j4g&(e$_GL)h z3X)SXqfMHr%^2YQW`!n7!C&Zzsad;hQO5SdqsX)G2uLr6K(4W&{h}h_K5FZEk*vRM z0W_qcoAq`=SNI#5C@V|VW7w17>UfR@t|X#8_%=MILES*GMCN^|C}|0{BnX*7DFFxub&j<(?% z7TL|WB9$2K5E>&ThKx3rh+(82ZA37EAjDaK#ZOCM_D#MPxyyI|RMn_EfY>f#V7qZG zZnx$t=aZoj?J~m!8pkn@9Y(mG?7k~MJZIB7S!}jRKwt`Ij_bmuVWG14i-VgC)u7I5 z6+%fs_}PbT^oVi?fj@NpkA5xe+ww+w*x@I+efnJO6cl=GCoEq#I-6`-XKvR>M>(dJ zEO2ClC|909uHPljCLCatV>JBr>5%y>j5D9m@=P0l4t8chIPBgCu)ki3jRt$3%)GAK z0)1BFL3d&(UV&boz5p5Rk%lbC<|MivbbgSDKU`*!pHARVz{kwvf*MF%)S1UQHk?u% zs6|_q$HY8tD)1y``oh*+%=DrzDPy!DiBsI|;Jh|jewnePeX_9JPT7zUR@g9jmRZza z&?+=E6s8>@>v_PYbb=9Z=Hhhll=UVu{y^=C}sNQPH$Zqrowh3Pv0b0Npk zE<#FLliwYd4_X=LjIG0MSy@A#|MbVMxp}o35B~*hx`0>vdFI1lWow$6*+$rWgsDAf zlIk9jq+;7aIZRha;g~gbOot|^w@JfdKY1Xv(2C=PTVf}Ifu8o&6`K=zTaRih^gT`I zi;kRImtHVhdd3UT)g;QEabcblyXV(WeDZZ7>4}xEeoG`y_5rB-s8Y{eYNpyk`2L%W zBpr|ed}yj?#H??E5|MnTY;XFqJ#`rJ`oDoTwA#tNm7~Dka`E^<v&Z zkMr2-bRWi?eA1%dVE|BC#N)LB4>3@2d26g{L);IEY|&oqVXXsZopno#$c#eHb1EA| z7u=Tr>Of-8e!-nHRE@KVFo(hZPPhVATpV8g_NvF6dk(B96`nebL5~YOFxe2m8P8j* zV`8RXe7-;LxCjVlRD_V-)(XHp5_;+v>cX6h3&P4*G`JXJgAmkNf7a4;AW$hHvyH_Z zMHy|6=@w{0__!EUyJ(-QF0 zqWiYEFtW(((SLo^!}8(o17xvz9d-^RnNoS`*t5G>_xc;((vRu)a^nNmFNoJxI5_at zoIg(VbeS->>{-bJvEm6fqgk5M|?fTDzYrfzBDIe*_@nQ>#z^ir_wmJpFz{jqH zzDS1`+UYS+W9;pCfe}n6fukRp(|$G2Yk{N`nGO8@ZKS(lq_g4gP5z>a9aYWR)OBMe zjWxXpmqsdlwgFNbyp&kK`}MyEbJ@Mt0-nf_SM_7hTxsg&3yL|(uQQm&{q0mYTmkE7 z2gfmgI?+&`@pih)7Lifl;C)6nebn1#?LFLmPh4WyC<@+6@dSvk?(fC|C3muLc5;_J zncouRd;(xlODDN!-Q;hhj-@fV^9qD6)Vtn7#OM9JE+jh(n)MytPQ3-$k7Hq)MB{`t zF7*t0xX%?H2M2_nuiFgXq7>fV0lAM&vA*vZNb;27<5Y20uPV z{2z7=p1Y>~-?m=+as}<%iBwURCl*FV4*d5Owmx(W9@nM??zgv|`*&T+-}0PyUsFzE zbMb!M?#%c<-^9L89rU>S0k2MSU*{CMPXv0dXQzEVJ$)NCon?2xxxcI(7acdu6k~HP z_xfCZHQdKBcqoM`)|VlN3ml6#5vdN76Z)2~P%s#RNf)wbbX+@JG0U z;_IBVYWL0)ZcS%H3h!{m7nNzf;nv1p>hjS}q?3RL>;d`09}w`%fkXw$VT^NCV+>Ai=h{EN?KJ*5Ju~w z?3DzkXU&^mp+WsXjnO(Irf!V71AW%D;EX(X?!;Ls+S?vox6MPtLrzKq9Zl#3;}(HZ z^Cq(TuKMFZc}idn85|2KiURZ~?NsX%brBaz9;vU68F0ovrK%ORrTs0$Ab^KF*R@sJ z3_|O39A2f~K4viF=5}3Us77DbOCt-)qRg4+?O8%d3HGH zaZ=>Is;u{no=;y{;Vi?L`ZtRjXI(;qtIuYX4k@y9%B%FrDaHIb1#`}J#Gu@5R+C}lg)qMm@0^ZwVbN`U|8T`1OdoG0?i^h@z? zyL`4$Y2T#QNb5g*F7O>~e7&DgN&osqp}sUKp+1TC$qk0glH-VZ^elQYXhM3yq80`* z?_*4_%hybmdumUS7K*fxdQ1dn0FsqjzCYzHlS| zK`cq#!=h+U&9E*cLDVKH?U4KghiFCBEo_{ducOt>_yVyxN$Y?-$!kxX3PWyp=U07{|y5)>V?IB&{&%!+N33dBV zc)Gb;KHl%1-xxJ)O&qZC^2O!hq6pq*gc;oM{y>)aZhNxV6g6Jc{jxawANg8?*Ks)x zS0$qMCXkfi+?A<3h<)kMinpiyQ8IJZf>kw}63JlI!)UJ6M6sLcD0`-4T&ll!Z^=OA zVS`ryC#PT{mR?dMAzJCo>Y@_g#-w-hOco+F*PbJ(7Wb{zmc&6uKF?FpySjx%rdpeJg4bAlCSxL9)D#CKll9q@nlR<987|%%HAA zZGl4gBl6b%mv4XlO^3m2hR&%iTV(e9>)f_F*js2(-F46(*D&T#Tw&1Jeo1%n0+L84 za)sICWA+)_*Q09^WNCZs$bE-r-+?8}GH7@YlN5S<94}Eg7OZQ(ImvwtG-5iy=0%ox z>|*jGWEcK;ZGO=Ze17r}a5Cx;_a5^5nUJf$^^|DAh~io3w>MMjnnh+K3HVFf{sMPf zjL%32NffCg$JkM13|HE z$D8M>E>BPW&!M0l$yAok!^6>M65L`%3MbAynT&jWO!g%tO+Rk#5WcGD0Q4A)ibqDx z2|<9?AQ<|SsqfS3UuKDb8)PN!V+?9XSSM4lGSO6;gOC!WW@gZ=HK_dWd2z5smdNid zN>BgD*zeA>lr$!)^$k+IXz5sqGhsB0F>EB1a@kPI!LR6wrg0B)ILOE}KflXN6@iQv z25(vr8(Jhx#p(Jdb!}b@heOw>nV%5mh(-&tLJCn1dJB>Qt}=vGrsSfWMh)UvnU$E+ znU%R2c?tOcjA-z}1l2pJJ~%-1-GQ-{!Y|4?7wYN@bL_F+%o&q+x8 z9X}BbFtMuY;cbyymxQ>Bhih35EX_+%pB*nCKa=C&RDwgniu>@$kIyL|`ezp!>h<9; zD>FCOEiZPQ(jCLi#8v#9P9G)=aeH7r=GNXipzc-=6E?HCm$7^_&InvLtFRYy#_gD? zzy99Jr&abUB4B2F+BV4f6eGNVrn!T;?!4I_vR&|Xuv^M$7fUO4a82AgyV`cP$qpL^ z&owGq$2iLve@;H1M}*`wkyZJYVIjdj;65TN$fg74H6BqYnS`-7E{FjmX_Zb!5R~^< zX#VuLr>@FT#DL0_o3u-C@nSx_j0`)v2(?R4dGFp^wMUX1dYzowv1Vf)&fVLsPNm4K z^~t1>y(%`Tqsw09IElNsm(EPO>h7`-RrTD`O=65|u&X_;8jdEeJ!#YCi%L=t&FO!%^*$C^O!3FI_R%*;geWJI6yNg#ye{-)~BgdG(p~)%-H(&5fU+ z%}{sMoHVbO;B#E1{kc-gxGP@E}{QJR(c);U;CxFAR@dk zx==9w6Bld%5NHoW{}d74BDs={j4>1X0!QMdkR<`uG>CLqot%eGL^A|9_sv zU!lVTTyzHdS=^sL`0R47->ABJo|()6{dSMDJ$9*9xD&Uou6(aNVMZRB$^A-J7qDVr zINU_H_zu_tsxDUnMD}+R7&<{csjL4A$))af9FKfWFJ!_n8#5JSjGZw#J}76m<(bn~ zIx6^mNTrj_xxUrjyIM`&qlBB7-dvRB6XP2x?xRG473)8$=X+>894_-5Z`!6Brmf=U zc}^|E*0vk62Qstqxtc8aezO~c5|6_FG??h#*lL5tImxmv&c$0MDBij~vPIJbM6Bl3 zg+Z9P1~Ggo0y&P1qvOI&0M(|vHPTyHc8Qe((^wKuiog$b)bs2Z*Z}AUlhKv_{%T70L3bZ3eNb!A)lNZ{bM^~Imdi(>A4bAA2@JB^G6W*9 zk{2Ofzq9AIuHDD5<~uRMXAB%t;(gh(B9*@E7{mnR+6@1a?s2l1uWjoF)q`O~ayiFn zgg;UdaDoL;C4l%2Y@Jpxia$jO`f$?~b~mJGfhkM`f76eX@%)VDZ#KX6`@@J{gzg$w z3(14p55@5C6zcZV`8(V!C5MgjY>=D$Ftuaer|fiz>diFav8hN{Uy)sKi5Vnk2uTu@ z^aVna2jY3a)ld$WkviS%&QN-ctewFEjA$lwI!GMsKn2yekdy*I3zY=KfH(>O#9^~V zu!K1j;m0COyyT7*!V_3t%Z-n36px2<4L17Fun3Zmm=_(Q?g}i|<~V3GsZ6qsvznxAGlh3%k3~03~(}9m%+Yg~knk+O&;}4%r%6clUb5c-ZyfkpZ2%#l6Y`4V#SBDrTY-T<786 zTa9{N)u>+3>SSJIHIY*;+NrRhTu(8P1&gYs~yl z5`qSn>vZ`lmoj`7R>brRDj0jPh(`4UpG6UxpoP67*5ap`b}`Eco8cuvyegp*lT}cB zTcHx+upbYC?NA@i@B7=N%amCtdgx_UvDCFw?Xq_r^um5{G|(VXyo+hwhqxsvOpcjT zQZuoRdAl(@W$N3@5q>;0HCKY_32i;`qO|@j0CWVQDmW(M&9;^u=PahL!lo#dBw(@L zjQh=;rMzkq*nJ!m1BpQt;b!1QrwRP7L{zOZNQ4g1n=`U)3)`^27U4OEJ%d5Nd-aO~ z$|^Hz;Chl~6}$Pnb@WO+{gcS*%n8<{m{tu}V9C>jZxpOa_J0{gTZES>jTExJKbAb7 z?n)`c_T*r48;?{E$`OtKJV2W0f_U8z=>_zrK0W5i`veK6`1v~_+7gzb_hQK6~tY)LpJ=hyPLB$f8v&~Zn>en;vnSW z^ek1jz!fs<{}bf=%W%4B&-z6?|J9#;eO<6ObJ1-3%?->uYG0gVAEGz>_~>yEbHKZ< z)ai4Sw-WzlA6D6 z&>f1;_22;K;{R8+zC1-xXa$^MZ>hN7rOxd>%;0k^9(2#@ba#Su>h{RT z8kv@=HBfTZ95zouiQcxEOJ3-(Y86d3zwo)*36||SeuwC~Goh-8D;ue7SG>^4fq~}x}DFjLVndu+Y1Udyw6&cRGPWZ9QohwG~M9G zz-fS{yWO8EWHU+Ih;2uwejF_e{-nOVW4$Yf8{i`r0-U;bu@WEN_B3{0o!@AblBM4O z&xJZ1&m!4SRbT7_9?rNJahi$162c$M=h$ZWvV5BMQFa&blPgBLVLzt<-}mKQlWD4D zI9`*8l>UA#=pBnoAHy$xO-N!3f0_50%RBwWrUbGu3~Uf_mY4fQUJ>-64dkNCGdK=x z6qNf?t<-&GZrO~^avp;Cc{gFi+>kX<#5NiMso59$ zen`sRM9wsCk4$L;Ri2WY5VEh9?+;a;#@AwID$_in2IKLveMD<>xS;&KUU*wT(PVU7 za7?z1W=*qz3+o(25FY8hI6?YjJGwTo*&!Sbyr2q5xq*)mEOmL5mz{MYWgiZ$o)uI+ z#xw3@qbMQR2L72E8zl#)M2N>kPVeH&hGiU+(2PxST96rJWz@>Nhdd+H%$UE>G|X@= zP_crwApf9!W$qI%DLSMEv`Tmzp?|}OA8&t4kG@MUbICgUzE2KXGq_h`>kzIZk|G@o;YGfL&1=YNS$fuVS_@HQ&+uNPrEvG%_-KtPr8zgP{L}NUR{v8rUM|qDZ*LGV~vpJc~~Z($-VC@`v%!T zqIk>Tne$z-#G0Z)mGTfn^Jg{AwPKFnt*VmYt5DVnu-{jQ?m2EM1*5Eg9QCFO1c&_sk#Wjxlw zjK+`@6f%;wF9!VGBn^qs$JevDlOroiVupF37O9mj?+RV0sDKs*cQ*8X1F6a^HKy|$ z?RA3W(4FMxtSN}=);7@yqDP%;6lAr#=55B)gB|UZHm>e*Wa86fmdp*2@?VKWD18tR zBvLoo_iV_Sm47X`V^BGkQrat? z?-hBi9^$I=r@2X>8EQhYILM&xTPn^Wb7|7r90ZdFFJ2>}-I7r)GaD_d6v;^lBd-TD zx4uN{I4IfSy!t0HJ2L5%G8)oF(k>x38V+32H>R z*@m-%+IJ2NATK-_qo|5^t#wbM#V`@YjwW!7v#t511=M0T+D8?tqt2YjPX@M)i!0== zEk@N|{!hCGcAIki+jY6A80g+5-@;%%?lmF+HHn>z&VhK(Gq*7?=S zw_5Y-&eRvsRuD>5r6X5fQ?B-YE+!*L@I=O}47l&g|5!fJa?>R?_yc?sxhJuD0DfN< z05-qrR??X3D97|oJ0JPw3h|r5LQi^9NQY5%&m3}dFB#Z-CsNjMooq(5HItubm)S7< zWo{>|F4BneDLBPq8SRF8JF*jW zXQWj~|JTQ2$sRvXh9ux*(~|G%o$4P28Yr6_A@A$sC!`S(ikI$*LSn*96e}*W(tGMx)Fv*QePvKG+3;1cc{r=F{= z`O!ed6brMfujK|;kQrZDyl*-CyHHy}c|TcsxIdZx8V$OWc6sTrz{%H+2SeKwY*leq zmm(Qsf_rgKzD8_B70>>*HFuj8M|4m?ZfhBSKOI3+7#P3$4I4C>gqq21JbQ=S0=29A zBP;6Lkd0k*7$*Y-lJ0O?Kgx&3^_Uj+Kn)VhJBuLqF!`V~zl&awVk&aXjMNt=WC*^I z#b%3Wq(AV7>%77C&H9I*yl@ee1Q@fVr)pefqLi^Q^PY>bcSdJ)f~$&eKZTs>TJwIP zsfn2unW*iO_@s46OO4XdEzJV(@{T zIFfLdp2FkfQ8_SFm+2Gxbu;h^I4e>#PJxrpF0SfrTxY zVv(|vKzS>9u>$=#Sqf`nR<<&nXnP4cy+YYh|L6Qr!)MJ81p|K(JOR6w}1gTygEtwk7&c3b>&ne4V^B<=ku%~Ai zjfB&aK*}URp>jM~t*LuBDH{JIbX8oIvwb{OLv1v87E2>!oj19$F%g@wfqtK=jXMix z=Ba|=qWE(t1piiTpe{ElH1g6sXY|H$?R&A|EK_>TLp4}`B1OZjd)c3CjB(`FZd>3y z@h7W1c^*SO<^D1-ap#P^WrDM&g?9M${Rcfe&J|)Pe`DI1;p=SJ zm&Eu6`zHJqhY@J}`tdQA&v!|j>fL2uF>m)9TI7s$UHUHk!vUqRnuEhsyO-Um*^Z0@ zdfR=*D`~FcW+QUF3XKBO#_a_u5MZLB33$RjR&D`v611N!g0REaz-$uKVBVG>KM3n4 zrn7eT&q0TPdIC#BQ1s0zJz*q=-ubv2A*_3H&6krUSD?Xu!c|EHZ4vaKBR&|Nui*Hd zJRvb4Tq>z#Gb3;qI#;1=-8?uFrQ1nMK|_;jL8isKlEl`T0_Zq|@rlyH;T@*dR#84l zN^`h;$nKFFbZo}s{W!Ptul2ex;c^&|@c#y?`WSeA z_P=*w=6OEdj_xA3c_se9Ao>H0xj0^%uurA_zdKsDdpx<@R@jWvty18eVq;-G8QT@TH6vy;hNbvxT3(@{Dj&fW=H_z5HMzpKxogmu%jCERg+jTh_Je z{g(p)w#o}*gPTyocE;^mt(BD_W9ljZ=PUl7(@8rC_qT;jVM9Nc%YoF4?jOEP2l^Xz znKdH=-PYc*2`CwJg0MB}&tdC-MBhIThno;r5avV(ee8Ps7r!jQP>hw1Lg?QwYZ)Y8 zE%P{Z?>QG&7A|K$g{CHV27UO9$Gf|Qe4Q^} zQ(P+KKZ>p1dVHTJQtfik3|?Il5rp0(FMQYQk2Icx&M$$){`+hQC9{U7ugy0tf*+46 z_#I2lj?s`Wi`AmGVGEhDOxl}oce1+yX|X#SV+HfcIpE*y$C3tgV#v5oQHEA^TJd!x zG;mJ4!w|kT)viM}`H=zx-zX5QYf%oLl9n#47a9*8UWMI>l`~YAVw73MC5?DRX^kR) zadGwnubCtvo^wm6po`3K%x22n1EXSG;++Ip83xUZ9y=2_BVWL$6ZZ2gs&R=6W+B|O zP!ulXjX)Wf$g|yj24e`EDZ{0{HLsh6QCwfM1=#*51-`~%6-dg` zSIEPR^h_Qu`?)ljyG+k=4Hahip5-2oo$seqUFIX6cWqy@cerrsHiQUa1yrD6#=^C5 zgI5vv;aGGW30u%$2doRmLZ+%~EOUSoBlowqye1{iPXYnBIHvq2xapmmn0S3(v$41ZHI%7>8G5#QU@n;o3;`Ve<@~+Roj16Q1Kp2a$8O zMexb&KG>flJwcYGHcy`>%yc@bsp@ymjV4DM^sJahIG{@j_so=*Z6S0GSmUfA^? z%um0@(mH&VO>(6TkvWVaxClnkK?aE+y)7bKT2fRfNed(K7%Xx3O4zGM*nDR63v$JE z3LWPeAO~-E$3nGBC+Htd;@$-lH(>`GPDU!A+P8KKN7G?w6=}GG+>y0TMQec$Qnu#K zs+`Pxz$Noey^h<$1B4($=E};MP)|i}Iq;DXi!&6dI($kr>a5h>5_@koSb7a#ZLsR; zlVG#i5hSX*!_%kbEJ7?jTq5rH2H2{I1y7nQVXo;|&)00%-Ca;1t0Z%e`58dN>|jcr zEoEVWij;8!AgV?Nlpvq>JPWAeXzE;beu;dr;9}o_f|Z&E7A^|G-bTm1=s9X%#4zHe zp>xWHnvFMP!e3ChsrC)FgRe2OFd&K{hyLv7txoU#*({h+Y^9(_3%3e&9KI(-e4(Fx zFx)L1`o({l%Kv3zK0ccfUgP+0Lt#ifPq12|6tanTes(e?fFP6)pl0UxL#_@;$uL^H zx;QDYz4Hm&2pBld6?%JY?F9$1jaxsywjXz5Q23X7ktjcWQ&t42dx1}>+t>R-e*6U7 zE=;rhJ2#JRo38RAGlCEI%BKK(eWOk(HT{z%IU5{ezXt#&;}3Um>bQa0;H~{sgWa3| z_l^0)t%ele9eABg6NK&ReVx^nC-b<2SjN`eX85{RsufGR4z~ak{;kgugRSTb=G65jcJqH^oehCu)LQCw9uce)Wc!rhtl8ehB5l`E$+>i79xRqjx`Qd5YKVu|(7TQD*S8Ls4 zXZUV{;gp-D4;k`9ev06yL~WUmwfE&d&ZrO%@7HJL{xK)vdB~9_>1)FL>5plAAzm~0 zs}u(@dJ@y-HN!oV!6ZN5Uk4Z%Q6!z5AI&KW-#0R%O$A#GiIIl7A~|!%yX_1Q#KeB) z{?U4!y14D^c|NG4z*Mob<~Xrv0bX^pzh|r!qeRPlTRZv|Ya+SY%0ng@u-MWUIr=uA zW1i-%_jUk37fuRTQtzng6dUaZ&puCf7eV0}zthlRa;d?4sZn4-!r3xR1OgNn)`*$G1zGg|_;9f*ISUkUu^J&gOx*|DzkC#BWLK1srU&gcaY#g3 z!wZm651!}_=ivyUX?G}ba`&GkPf$&f^L|#`c@Ku#)7?UirX6I-OwP)Tu?Bn;1!>UC zl7deV*9rDhpg@SkB+TGOf>Z}-aHw!Gh^WZ$keYGaG^iNC?3S_hyGGRhxHajaWO0rn zb+AsXwBk4iQ~c@sCMNX8oh$2t;@$0}Qv{0=zHlt?KZD67j0y}9{&>=MaI&39@r!}C z^*15T3lc%~th)1*<_SU5@@>iMN4H5KBxnhC(_F=1T*k5#SxcG{hO&J(XXYjB_t4-oYt$ZU^Ed;6 z!`R7$#Ee4f?gP`4`Pth7FZ-~9k^?-x1xUjFye7`V0^QBYh9fH};?7f1I*gPP7=h2_ z75{8XcP+-4FJedCpozNUNd8Z-kM|~$!etzTe8&BO9Eh5SG;j&9Xbi?j2m-1V2YZYYIWwAzQHT1d$ZR0y;^^&_X*&Fty7sv%hQ4?YZf+9LK062QA1?RA*myAu6JCiB!&z^l*q~#k8}@q!KFD;59qjyh0kp08 z*31L*f7prv3xo@TPVuc%Z1pZwBQmd9Udv7TrOH@t;w8|HHXp-HtTo)yp+Z6zt0%T9 zO2U-R*@);D`uDIGnC^AL!lVJ-g_9M_{_M7A8j;!ha!Lp;oH|&EfhyEJgA7`g<}|sW z1b<=Q5QRI1YO4gni~z3^R+4ck<>Z4TZ7!T7^4<;dF8$^G?=hwM-<%=c(pzw9T`AS7 zlYrl5+T(EAGNS`~lxmXxmPz<7+tVsW?JdNhfoXUiAk0 zQbS&fS|Iq~g2#LEe+=Xt7cvKwoA)ILBTZisJXRMoX+w#zki8Y5TgkD7X0n?xf^A3; zcPx^G>0nee2TPdrtL6WsKh&DM8DhlWE(00=6@K%O^&jefGP+Ls*-2CCYKOIzD!9GG z0b*3ft@}*>Hh3H1>N)*{A?7ZRC~kFinNHihbeOmKpTFn70h`@u%_RcjIiRYCw603@ zRTIf3yY3c*2-D%y^3-{C*I0R11bz-MZA0S(W__HDDt!f07sa`;e4xiX?UKB#*uBLh zaCMhD5SYJyP=YiN1J+}7r74rWN-t25# zG8|HPyv$m(@!NHZ${e}9^yIg?HvC^W$m73*x2HHu1Gu*N+Nw8;8u|lAsVHI@g>V*$K&>`lCtiM66bZ z!%bM9=FZQPyFrqd^A``i!b%W8Ca_Luu(;&qK$pTC1c~8XL3$aZBqA~)FSK@#Mv6g4 z4(M;OlZ+-XJ=oTZX9HbvMYi3e+cWSpNRkPV1xsoQQAR^T=_filIXX(pPLWoNTP4O# z%h3i!_uW(pd#e@)W-v1HRY}%vDaFp-f>>j`{rS<%(u4uF?M+{FlFE0;Y$v#U(^N>t zGo-}wj${1HGvvelX7JgrOy~xSTC_Y2)N=wE&lx!ss$Jo$w`eCRBE#wCLnO;$!urR; z2<@S@N@Iw^=)@pyS14k2zynfLb^5dFOrrdZ^*6O!y*wGvCO=0lKFRHHbbtZ zLp1VG_jrHsjX=+{$-3b);}O4jpd~;(U;0gdICU^{1C4Zo77OQh^XTkNO5P=2SomnL zwWAP3XG2hsg=M#1@>z8AMc(zvd)Twa+K0E(i}4KCPEthJLM2>2B0-Cmlc^L@cA3l+$;szld7m} z0V7$UUu~|8(5PaCHlC0Go*w)u7hNy?1V$8^1Zn<22&TDD~(C* z7r<_&5(OC$!$79va76cdygt$vFS3@2W(--jMUu0Q4#E!A3NNGpI^zzx4+kE0)dAXiX|1^Vm>cFME z6{TbPwT7TvY|no&=6{WWZD(0QDG`*mSzmQM0n|AlfRme?}SylWnE=dtJ5_q6hH8zV}eEp9o9OtI5! zA7R{C-8<8fM-uD4Vdxa*f$~hDQ%osjTUxd1G_*RRp4`20w2zHPwrh0x9_nc#P0t;9 zEow;0?Yt#{`3wt79q=!H8wbvtB>)lKHD}wHKs~=bW_vWnrpGtCTGv8u1H1@OsfsKw ztYJ}k6Qb>yR^1M_DgVs??9#nRA)86_hcKGxRQ%l~-L~DA)={lE(v}z8fh;cBt7>Uj zG(0@Ipz1tRo0Llj!vpM{gd}W{(i|S~s|^v9H0hb{H`FYUeY0 zMDSI+^O?FILYPI99-Vgm+;jP0zi7)BOX}8jj^YxMHpzIAn7Z4m5BclA1Wv=6#20j% zs0h@8eMpartAW|dRk44k?kgCeG9q1?ybk_02a5W46VC+ z?<48OdNksCImQ$cfS1rN4Kx)bhg@~|K=pI0rq%Ls?WDiyexlxgxAg_@BfEZ3fA%&U zbcTR{TKz#Z+tgR=UfI~at>eTXJp!=^Wm)}+hL>+U!2!EL*TsX`hX)<$@3}mwy^lmf z)n>y|k_*DXVD@Cg(x?pUQG&4-n(fLmeJ$j%>^$%Af`Yc9!3S)RbBBvg;rz2-o!6w; zosa5SeEPeqHGl8qU*w$sPRH^D5)U-gde@OSA?>(H%IbZK_pu~;s|-ulQDl93tH`oL z!qI@>behSo>5s^RJX+g;ifzsLb}WZ=bPb-)%W>{Sq|Ac_{xogVL`iBBbSG*KyQ(21 zkW$pz{ZAB%N>61n&R{1?0-hj8X1ry3Zi7nlZQ%`;3Hn zQM$-9Jq4frHmSw;mlIIJb4DD^ES0s<7@kF8L}-dsW*{q`Ws(ZP#jpv83w}8)>zG4b zKfF3u6>Yx@xw|2O4-Z=G!_1+jNBpRp|HTNm6lS>tOF$?E9r3Ne%jLX1)Ftl_gu%Hl zF4?C^%Ih=HwbviAot1?v<6C_cr9CjaTDbq|Kqqd+@@-XKPVEG@Dq=2m5?ScBpb zprEo}GzMj12HLPq$2K!l5*tsDVuprHtffo8<)l)Wc-w~~BPv}Qjd0DtNUeT@R>J^i zj$~nErInx_o-4x4NlmE3g_ax1)Jja~0OJ*AR^qyc3BDF}HyVo~Pt`3o*>8W<-`QUb{hsq8#|$c8ge!^7A}x~uH3!W~FK`E4sOnX~c*ZQ$7O z6m!|R>M`~Biq+vsa@GJGEC@V@zzP{Xn20=%c*v@Mb3BM10J83YQ#++2qvL4T3IdrW z-MTO}a{ut~kY2#Xngv+_peb7$w$~b>gz{E>smyb!lC4w!9w$ z1$DK5u`!PJDl!-{Og;~*&#_A&1+*D; zhGR;?<9OWt;(@@KPqVEmn62&Wd%%rf$^&rzZhAPOvJ;CjrD%um?ftx(U=E{!rj zGi+~0`NIkJ;=Oe;xZxVf0J9U^VGDYOw*iBy*FNy*s~+kQN48ZbhASr!&LZE({CA|Z zWe5+dQ_fUY1*{vQc$tCTH6o~{GyQ)R!4%qzG{StK)&Q`SjD%v2itrW(MKDRvz~OIH ziS`y_?sJ3JwwMkNHothUY)JYIC|`i&kkRt}-PjA<_v-@a8AuLBdvujzeYpJ98aSO; z`T#j?wUcC89vHVzbBkORM_C+vaZFqR`_34#3Tng|ISfFU?j5QhauGwZL8ry zvFx0->K+gga?ZIbAQ=!x*=xR~Bcr-m-XVnREM9e~ZPdGC_J-RVD;c+C+xWMVtJpd= z0((tdLYlKUt1JbpI&_u&mS+*`!ZhP&R2}g+tUgzYe)f5?CS>04RcR7xFm!GjsDS;* ziY3)*M%M|OU%3e=kk!G-$QDNRJ^RB~`PZ9r+mc4(p%Qp2>Pp|H`K~%(lJm)}Mee5N zzdM5N(1K99k9JqOke%S*qX8URMRCjSnvGZF&Wf-2C=v$*BvS#11&DB(=gMHq?*D0C zKu(ys%!SrD1=Ua(@RQrEr%j((po;a5qihh!^?c_A!eck zwMPc)AtC6?+8Ikl^k{-QPpwl<~xH`!^RB9jr&o_En%tH)COWR*@3vu?}v_XY9}&#uN)=Rn!TF zL@%ZB1%>i$gslJGMI+~v=bRLp1((P`H4PdpF5N)Q9^JysblJm1g^A+^4ggvUX=rjn zP#sy;N;uJHHJK2VPo$mzlS8Q1J&0%HpoPoeNp=pLxI zBx&CW-tpnc%R89ol_$IbwN7jAn%Z1%bN?^NbhKip{y@7d)CKk#&SsD@P2SO?8e41f zqGp(jehFmQ#+|sKnyjEbA}JK(6}zOt_>;y8&BFyK8eN@hLe*1RfOL`v`NN9bloq07 z%~ir<@039&!g-`T-zcNc`Wv!9Igcb`XMe{Z2;;vPIr_;anQyOEF5$>{sfI&O`nuX$ ztCFW-;P#h~5*<8v{;|WZ8BxQ+8zN}u9OU1O72)FH46LkwicCc5LV6o3D#kb^C^Itm zOO0r~o09}|m6)JH#F7CnCtiUXEpQ;8%22qI7=LSJQIo}Z$e3~#YYip zXRl@|VJPF;AYZf+wRuDOxoo)?^(S^}C*XFyF zr8P$EALVKMWO_mbZd6IA-6ILwZqYG6m;O1M?1jK&-NZ))X{3NIRP$y-avkwt5ry*f zr9Ii>GWY|6gNv?YeN%)hzE<4jLTWtg2us;UJX`!GigHnCelQO2D;mGNqs#` z8uQKUq5SlPbU&BMb!-Ya#^FB|0WaST-{B*J)mdv+HNeW|e>}|T2`*54#-*cSlEXFR zNEXz@0PPy6`mr17RYC_OVnHsq%17ORY>8C(7-LNWNWerijW5npqL|6^qjdBQ{az7K@@ z^*7Gnuc!yL_H^-Js$M8G;DQRx=DKLb8#hlR0Qcj_I0E(wrC|M|@H8`Qf=Ih1;<&r2zW62dr&cK=w{2K$Cm&ii^FTz!es|9 zGe;5`1)n_9sQqSj%qKI8eXFu^K}V|@caz2Ci;d~`q%=l>ld4n4X^NaH|814&zs^Af zYkTcQ#i)hzc;*ca=?S3m(5mc@ghK%_?O#FqPw75ZWF95R&Um=ay7d9xx4FUE5IyOA z?8tG)I2Tf+=>TCf5RhiR02y$%LtQ4E>a9wB{xM&p4=*QJ?tA6)9D*hYb7FwI6}7Fx z#IG5D46(Q}oxSdpkQZqCpZas_%Ar%~a2FJkJmTto0Zr6E`-#B+?`LTPjP%K`k#Ge} zBXuV|;I1zJC0qcUvv!{eY&sjQM&TBpM|Ly5dl;jn@;;xr>TcI^3;Y?oP*2HU!v64V~L9S8%xdm}lgWw<3hNw$nc~U6Orek<$i+Q`<;kW+h>7n^EH>B?LBr>8fsohUlK#oOikWqP^Bc601kZy!F> z1zEgAW*7)Q84uAZ*nl+G^>@$BF1Sl!`@0qKo_v@@0bw$)ud<7+L{-pl#h^)+b{i59 z^;}=G1*v)shtRcg)FuYfiNP+!?bY!Suks;r&2!C~K)W?yeXfIR=U$e`u4PaAVWZTQ zNX|Bn;&Nve`n{%aW_@UV{U-q*+fB5_Vil&}+S$kJ*^z7YsdfrzmpJMz@BuTvk$im?zaX^_;#ksjWY_r1zeVdQbZ_J4oSy?ZCWR=bY8s%Tl4qgCj~gk<5+p~9 z%*eyd|01&z#^e?RP~sficZrKD{%|Z0Sl;F)$xi!;;cY4zDVBoA!nrERsfIenCHsQM z$T1M?9H&faSlpc?3QA4-!zHQKjbZ(yGu72$^8`v3RnX8^!pwbghxMO;WHeRrIVp)^ zz&^}O+yaQ;4zR*_v=u!j<-0g$uvNv|U-u^mgLMeS($8{xaUy=s0nkP`TP}FDm-OCn zCPVGe8-iuXF>%b{yU1(-l{Q=l^rR4ygjHh3i69*?52m?#<*<0MzGtxQh_(msbh(x@>Z=Q^ESr~sOWiP?O zVnL*~dkeKnyp$jZM)@*+S0l%NO}hQ5a=-Bt5o%kU%;N^z8XBn8?sM_vt&G%YGEMr6 zA2`Gq`TK`<5d)B;7xJlavvq?T6`w?)133FPzm+67?7U(v&ukLy7(PCdBJiynf` z1RQ_+RS~AsgvBg=!l!KPoi#Q;o0a~iPVL$*TZNh!Y34jVj1sR3sn`QS41 z2Wi9>sJ8RKDtqHzsU7&O+jn@0)We}cv2<4iDrMrT@-*3SbR-=IDO147>z z+BHm?&`VR6Y^zs(!)v!k>34K!6JdHT6|lFH&sLGR;vy23HZtDhXQ`H7%NV$T$oy=o zr1Oqml}y**L92I_=KBQ{9W59d+Tl@sJGUci1#RpaE)zVu9ktYlcl?v*# zH26guhI&h99aoJD<(%g9<#Z*c)saC!PCjit5$q^lXZ=OG$n9g_$|p8 zynzqGBLTP;JMV@xgkA^xqgLEiN4g6Qe8{Q+Cl1i}q!1us%v{O;hG4=-3z{#>CSg6G z_+_TRe^N>>&?-jT4(}k$_asdJsbfVfQ)*(zU>}O7x$-wLt>4!=l~9`K=e#xocu1|k zp7mWPi@x<8h;}wLvyDtG`1QV4T+H`*`t``V{;@Io209tov3p4=^}C3pK;d_FC%AsK ziuWS%dSviJf35$zFXy`&Hca1naaZ2G;+Xw<&dp+>-*W8|o`D9p0O9}rk0#C15U)F# zw=rBFe0{M=8`R*(n9n<>&tGANk$@MNiA%P$e=p|LP)$M__chwt=7#A9LqxM^cNYGt+# z8*_7;s-8eD*-BqRO-B2euLy$ZYzP6+SK27twNhPF>zTjZH@#-I+D!PYbDP(txNHUq zTIv;6B)Q{lpy|9xfAAsNo_iG9IAdtnDcJI1XEXjD*q8OHO7I^=vj;-AFyL5}z~~9q zmPsrgi%uv2hW(tKjSF?392+u|vgqUPhnzQ7L8RN?a~7pc5FhtNk+#ZB4#^NgYvyjN zsZtAr!f>tuEyi=D%MY&83v@j5YVB9k%S3H^jnm=e$=hul)x}pq`EOE-K*C(K zg+XW6I=qf$c%){Q;B~~%C0Tj<1etr)n7~_DB69sc#=XST|8klR`3{1RHj4ETX62Tt zljiwN4J2H)Huyk3Nyf06Azf?#A-^DVkdY=Z9nUC!;YoYLuNg?D*nHBBz!NVt{T*jm z03x;+L}NZ01|2IC7{41{zJKL*Kl$73x805|Nkk-zb5v@mbZ-5Y?c;Le>aN9m_xH5JIkvocJV6998 zWvJ69-JMgaF>N?lEYudYvHQ0g#th-Olq6R9=^*8bg}nnP#EQY$jYV8xK@Nyi3M@w< z!V_z418T%T#gvn(m^IS@(rEmWWW#fXp-y$MZqZo-bpM)UF0-G!+<9*w6Z{=8Gk`fB zRHbq9AZdBB4%5Kqa1Lw-Np4{!NIi1Yx<*BErpHWx&L29=X|*n_U&$f)+B3>a#nqPl z`Yd^T_-8?d-pu}>iRh4j$6+9zVy2h~hxQG{C&DN>Th+J`-`$+udOU$7wz+s^0;0Ga zwJsD4(TqTbVZu$SN_u4(9JD5dw%Hyk;rR#bG)3Bd=HRpTVf7b1FYPObdq~8XR!PEb zHmp}%h;E9YlS`j>mg5SPHC2vaJoLo&)a#j8EVO_vI3YC+owF-WTgRDL z3x*L1nEvU0awWB)0JifI%td=FvR0pxLI$Wa3kVf35l5=CDavX`){7|Z4RAzd+Oh{= zSQg|HAx4yoSePz~W2PIa*>8!t8N$6&=?|j+gbYm-gH8X|Fa7CHA`cs_B76o1CAAw8 z^2k1~PY;EmTPJuBe2yLvRIji=>JkEF(EBmx3x7(A{%K_TOhontMJD|H6&Oe=Ebsp> zU3%EWnUHK>n0;3)Hhfo!@HRmZ{M;A;*K8(6`G`53@JKGYZ;U%Z_)0rC1t_L#&f{0b zK%5WDOK&vftACB4j6$X9ZQaYW`m4|j8n1cA?e@2up_7l(Mtx`pUCK-FHse)Y3r*GN zL9A!>o4A4S+OY;+pte+7TEuDr91~GJ&%lT62yR6CxIJtXRCH``W0WY0i7hYdfjP`` zuo%3~_aQxg73j{FbPB?HdzMmm0{O)wBcvAlxFAl*wtV}c$f;qLC(OMrgs0XWU*r%y znv^boG6veBnH&U!%PFl!v@fb%&Cz~8rEgrLb%;Ue7X#R5(lm8V(SwO7I=YRc`!g$* zJxvF3m$JW2s5N@Vulad$Df?O?i*Hv47MxAA>4g*CI z*NqYqN}2q>29n2VlD@~~@;eM1z>)4#$K*15>~SjvWR)k4{K#PUJu@966fzqKE{|t( z*i44or;a1xa@lh) z=nxj7O~ovBzflN)FHPo??mtADN3Ybi*+#jX6HV9AT_`@17sb)Ho!PrBw?PMp~gj;fn%v6ON0>}`V*`J3CTl5gs^owKC$^Q_dZUbSd&})Em8>hprAosx0Leg zYP_0Grm_otZAquXezQ&oCO*N^zQr5FCMiQ(aJq*4GX)C?mG-as5edCk&0fNlyU}bA z&4DfX08&bttj+b{7>k`hj6UN4U=AsWt8VtdbycaN0}k{SCoohc3c9sw?h;+2{y7d< zvT8ISGHlXSonHXdu9VXYa(uT0H!2=oF?AbbU zp9>_P8XuI`;npQ_&NlS6VXuCuzg1~hF;apmGv~FZKj6i7B`E}LfrV#+57?^>Gt_w( zQJt5d39Ci4ZSKb^n{B9U!WfVeclJc2l=a+*Ji(qgCcIw>WpgE52#dWY+VbhP^~cxf zwjdfpLmge@sA9-k;Cb$Sscef%$d}Wl3WexL#4zN|$YmXhNU}Y6#8~VY&5@);JF4m! z<4zg(65PQcE7HVYeV`9vz9ERgnvNuS+= z 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

Uiy53CSxWo^vvH_>4$0iNPT|v`wR6l^$+` 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�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

>1;O#FGZsDH5YX;g!! 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%0DqHRv*nwj;SE8|otpBmKGwhL_*nM&#SewaM-E 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

)Uw-q~F4t?gwW?j-MT9v7?oTS6 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%0A=(PtVQ$L?Ek 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� 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 content) { return; } - // Vehilce Status + // Vehicle Status updateState(lock, StringType.valueOf(Converter.toTitleCase(vStatus.doorLockState))); Doors doorState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Doors.class); updateState(doors, StringType.valueOf(VehicleStatus.checkClosed(doorState))); @@ -654,7 +655,7 @@ public void onResponse(Optional content) { updateState(checkControl, StringType.valueOf(vStatus.getCheckControl())); CBSMessage service = vStatus.getNextService(imperial); - updateState(serviceDate, StringType.valueOf(service.getDueDate())); + updateState(serviceDate, DateTimeType.valueOf(Converter.getLocalDateTime(service.getDueDate()))); updateState(serviceDescription, StringType.valueOf(Converter.toTitleCase(service.getType()))); if (imperial) { updateState(serviceMilage, @@ -722,11 +723,7 @@ public void onResponse(Optional content) { updateState(remainingFuel, QuantityType.valueOf(vStatus.remainingFuel, SmartHomeUnits.LITRE)); } // last update Time - if (vStatus.internalDataTimeUTC != null) { - updateState(lastUpdate, new StringType(Converter.getLocalDateTime(vStatus.internalDataTimeUTC))); - } else { - updateState(lastUpdate, new StringType(Converter.getZonedDateTime(vStatus.updateTime))); - } + updateState(lastUpdate, DateTimeType.valueOf(Converter.getLocalDateTime(vStatus.getUpdateTime()))); // Charge Values if (isElectric) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java index a54d5a164f09a..65479f9ddcb27 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -31,7 +31,8 @@ public class Constants { public static final String CLOSED = "CLOSED"; public static final String UNKNOWN = "UNKOWN"; public static final String NO_SERVICE_REQUEST = "No Service Requests"; - public static final String APPENDIX_DAY = "-01"; // needed to complete Service Date + public static final String UTC_APPENDIX = "-01T12:00:00"; + public static final String NULL_DATE = "1900-01-01T00:00:00"; public static final String MILES_SHORT = "mi"; public static final String KM_SHORT = "km"; @@ -50,6 +51,7 @@ public class Constants { public static final String SPACE = " "; public static final String UNDERLINE = "_"; public static final String HYPHEN = " - "; + public static final String PLUS = "+"; public static final String EMPTY = ""; public static final String COMMA = ","; @@ -69,5 +71,4 @@ public class Constants { put("SUNDAY", "Sun"); } }; - } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java index b533799f09251..e382339af84a5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java @@ -12,6 +12,8 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.utils; +import static org.openhab.binding.bmwconnecteddrive.internal.utils.Constants.UTC_APPENDIX; + import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; @@ -32,10 +34,14 @@ public class Converter { public static final DateTimeFormatter SERVICE_DATE_INPUT_PATTERN = DateTimeFormatter.ofPattern("yyyy-MM-dd"); public static final DateTimeFormatter SERVICE_DATE_OUTPUT_PATTERN = DateTimeFormatter.ofPattern("MMM yyyy"); - public static final DateTimeFormatter DATE_INPUT_PATTERN = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); + public static final String DATE_INPUT_PATTERN_STRING = "yyyy-MM-dd'T'HH:mm:ss"; + public static final String DATE_INPUT_ZONE_PATTERN_STRING = "yyyy-MM-dd'T'HH:mm:ssZ"; + public static final DateTimeFormatter DATE_INPUT_PATTERN = DateTimeFormatter.ofPattern(DATE_INPUT_PATTERN_STRING); + public static final DateTimeFormatter DATE_INPUT_ZONE_PATTERN = DateTimeFormatter + .ofPattern(DATE_INPUT_ZONE_PATTERN_STRING); public static final DateTimeFormatter DATE_TIMEZONE_INPUT_PATTERN = DateTimeFormatter .ofPattern("yyyy-MM-dd'T'HH:mm:ssZ"); - private static final DateTimeFormatter DATE_OUTPUT_PATTERN = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); + public static final DateTimeFormatter DATE_OUTPUT_PATTERN = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); private static final Gson GSON = new Gson(); @@ -44,15 +50,27 @@ public static double round(double value) { return Math.round(value * scale) / scale; } + public static String serviceDateToUTC(@Nullable String input) { + LocalDateTime ldt = LocalDateTime.parse(input + UTC_APPENDIX); + ZonedDateTime zdtUTC = ldt.atZone(ZoneId.of("UTC")); + ZonedDateTime zdtLZ = zdtUTC.withZoneSameInstant(ZoneId.systemDefault()); + return zdtLZ.toString(); + } + public static String getLocalDateTime(@Nullable String input) { if (input == null) { - return Converter.toTitleCase(Constants.UNKNOWN); + return Constants.NULL_DATE; } - LocalDateTime ldt = LocalDateTime.parse(input, Converter.DATE_INPUT_PATTERN); + LocalDateTime ldt; + if (input.contains(Constants.PLUS)) { + ldt = LocalDateTime.parse(input, Converter.DATE_INPUT_ZONE_PATTERN); + } else { + ldt = LocalDateTime.parse(input, Converter.DATE_INPUT_PATTERN); + } ZonedDateTime zdtUTC = ldt.atZone(ZoneId.of("UTC")); ZonedDateTime zdtLZ = zdtUTC.withZoneSameInstant(ZoneId.systemDefault()); - return zdtLZ.format(Converter.DATE_OUTPUT_PATTERN); + return zdtLZ.format(Converter.DATE_INPUT_PATTERN); } public static String getZonedDateTime(@Nullable String input) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_be.properties b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_be.properties index fcc030b42a881..6e4577565b06e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_be.properties +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_be.properties @@ -14,31 +14,95 @@ bridge-type.config.bmwconnecteddrive.account.region.option.ROW = Rest der Welt # thing types thing-type.bmwconnecteddrive.BEV_REX.label = BMW Elektrofahrzeug mit REX -thing-type.bmwconnecteddrive.BEV_REX.description = BMW Elektrofahrzeug mit Range Extender +thing-type.bmwconnecteddrive.BEV_REX.description = BMW Elektrofahrzeug mit Range Extender (BEV_REX) thing-type.config.bmwconnecteddrive.BEV_REX.vin.label = Fahrzeug Identifikationsnummer (VIN) -thing-type.config.bmwconnecteddrive.BEV_REX.vin.description = VIN des BMW Fahrzeugs +thing-type.config.bmwconnecteddrive.BEV_REX.vin.description = VIN des Fahrzeugs thing-type.config.bmwconnecteddrive.BEV_REX.refreshInterval.label = Datenaktualisierung in Minuten thing-type.config.bmwconnecteddrive.BEV_REX.refreshInterval.description = Rate der Datenaktualisierung Ihres Fahrzeugs thing-type.config.bmwconnecteddrive.BEV_REX.units.label = Einheiten thing-type.config.bmwconnecteddrive.BEV_REX.units.description = Automatische oder direkte Auswahl der Einheiten -thing-type.config.bmwconnecteddrive.BEV_REX.units.option.AUTODETECT = -thing-type.config.bmwconnecteddrive.BEV_REX.units.option.IMPERIAL = -thing-type.config.bmwconnecteddrive.BEV_REX.units.option.METRIC = +thing-type.config.bmwconnecteddrive.BEV_REX.units.option.AUTODETECT = Automatische Auswahl +thing-type.config.bmwconnecteddrive.BEV_REX.units.option.IMPERIAL = Angloamerikanisches System +thing-type.config.bmwconnecteddrive.BEV_REX.units.option.METRIC = Metrisches System thing-type.config.bmwconnecteddrive.BEV_REX.imageSize.label = Bildgröße thing-type.config.bmwconnecteddrive.BEV_REX.imageSize.description = Bildgröße des Fahrzeugs für Länge und Breite thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.label = Bild Ansicht -thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.description = Auswahl der Ansicht für das Fahrzeug +thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.description = Ansicht des Fahrzeugs thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.option.FRONT = Vorderansicht thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.option.REAR = Rückansicht thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.option.SIDE = Seitenansicht thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.option.DASHBOARD = Innenansicht Armaturen thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.option.DRIVERDOOR = Seitenansicht Fahrertür +thing-type.bmwconnecteddrive.BEV.label = BMW Elektrofahrzeug +thing-type.bmwconnecteddrive.BEV.description = Batterieelektrisches Fahrzeug (BEV) +thing-type.config.bmwconnecteddrive.BEV.vin.label = Fahrzeug Identifikationsnummer (VIN) +thing-type.config.bmwconnecteddrive.BEV.vin.description = VIN des Fahrzeugs +thing-type.config.bmwconnecteddrive.BEV.refreshInterval.label = Datenaktualisierung in Minuten +thing-type.config.bmwconnecteddrive.BEV.refreshInterval.description = Rate der Datenaktualisierung Ihres Fahrzeugs +thing-type.config.bmwconnecteddrive.BEV.units.label = Einheiten +thing-type.config.bmwconnecteddrive.BEV.units.description = Automatische oder direkte Auswahl der Einheiten +thing-type.config.bmwconnecteddrive.BEV.units.option.AUTODETECT = Automatische Auswahl +thing-type.config.bmwconnecteddrive.BEV.units.option.IMPERIAL = Angloamerikanisches System +thing-type.config.bmwconnecteddrive.BEV.units.option.METRIC = Metrisches System +thing-type.config.bmwconnecteddrive.BEV.imageSize.label = Bildgröße +thing-type.config.bmwconnecteddrive.BEV.imageSize.description = Bildgröße des Fahrzeugs für Länge und Breite +thing-type.config.bmwconnecteddrive.BEV.imageViewport.label = Bild Ansicht +thing-type.config.bmwconnecteddrive.BEV.imageViewport.description = Ansicht des Fahrzeugs +thing-type.config.bmwconnecteddrive.BEV.imageViewport.option.FRONT = Vorderansicht +thing-type.config.bmwconnecteddrive.BEV.imageViewport.option.REAR = Rückansicht +thing-type.config.bmwconnecteddrive.BEV.imageViewport.option.SIDE = Seitenansicht +thing-type.config.bmwconnecteddrive.BEV.imageViewport.option.DASHBOARD = Innenansicht Armaturen +thing-type.config.bmwconnecteddrive.BEV.imageViewport.option.DRIVERDOOR = Seitenansicht Fahrertür + +thing-type.bmwconnecteddrive.PHEV.label = BMW Plug-in-Hybrid Elektrofahrzeug +thing-type.bmwconnecteddrive.PHEV.description = Konventionelles Fahrzeug mit Elektromotor (PHEV) +thing-type.config.bmwconnecteddrive.PHEV.vin.label = Fahrzeug Identifikationsnummer (VIN) +thing-type.config.bmwconnecteddrive.PHEV.vin.description = VIN des Fahrzeugs +thing-type.config.bmwconnecteddrive.PHEV.refreshInterval.label = Datenaktualisierung in Minuten +thing-type.config.bmwconnecteddrive.PHEV.refreshInterval.description = Rate der Datenaktualisierung Ihres Fahrzeugs +thing-type.config.bmwconnecteddrive.PHEV.units.label = Einheiten +thing-type.config.bmwconnecteddrive.PHEV.units.description = Automatische oder direkte Auswahl der Einheiten +thing-type.config.bmwconnecteddrive.PHEV.units.option.AUTODETECT = Automatische Auswahl +thing-type.config.bmwconnecteddrive.PHEV.units.option.IMPERIAL = Angloamerikanisches System +thing-type.config.bmwconnecteddrive.PHEV.units.option.METRIC = Metrisches System +thing-type.config.bmwconnecteddrive.PHEV.imageSize.label = Bildgröße +thing-type.config.bmwconnecteddrive.PHEV.imageSize.description = Bildgröße des Fahrzeugs für Länge und Breite +thing-type.config.bmwconnecteddrive.PHEV.imageViewport.label = Bild Ansicht +thing-type.config.bmwconnecteddrive.PHEV.imageViewport.description = Ansicht des Fahrzeugs +thing-type.config.bmwconnecteddrive.PHEV.imageViewport.option.FRONT = Vorderansicht +thing-type.config.bmwconnecteddrive.PHEV.imageViewport.option.REAR = Rückansicht +thing-type.config.bmwconnecteddrive.PHEV.imageViewport.option.SIDE = Seitenansicht +thing-type.config.bmwconnecteddrive.PHEV.imageViewport.option.DASHBOARD = Innenansicht Armaturen +thing-type.config.bmwconnecteddrive.PHEV.imageViewport.option.DRIVERDOOR = Seitenansicht Fahrertür + +thing-type.bmwconnecteddrive.CONV.label = BMW Konventionelles Fahrzeug +thing-type.bmwconnecteddrive.CONV.description = Konventionelles Benzin/Diesel Fahrzeug (CONV) +thing-type.config.bmwconnecteddrive.CONV.vin.label = Fahrzeug Identifikationsnummer (VIN) +thing-type.config.bmwconnecteddrive.CONV.vin.description = VIN des Fahrzeugs +thing-type.config.bmwconnecteddrive.CONV.refreshInterval.label = Datenaktualisierung in Minuten +thing-type.config.bmwconnecteddrive.CONV.refreshInterval.description = Rate der Datenaktualisierung Ihres Fahrzeugs +thing-type.config.bmwconnecteddrive.CONV.units.label = Einheiten +thing-type.config.bmwconnecteddrive.CONV.units.description = Automatische oder direkte Auswahl der Einheiten +thing-type.config.bmwconnecteddrive.CONV.units.option.AUTODETECT = Automatische Auswahl +thing-type.config.bmwconnecteddrive.CON +V.units.option.IMPERIAL = Angloamerikanisches System +thing-type.config.bmwconnecteddrive.CONV.units.option.METRIC = Metrisches System +thing-type.config.bmwconnecteddrive.CONV.imageSize.label = Bildgröße +thing-type.config.bmwconnecteddrive.CONV.imageSize.description = Bildgröße des Fahrzeugs für Länge und Breite +thing-type.config.bmwconnecteddrive.CONV.imageViewport.label = Bild Ansicht +thing-type.config.bmwconnecteddrive.CONV.imageViewport.description = Ansicht des Fahrzeugs +thing-type.config.bmwconnecteddrive.CONV.imageViewport.option.FRONT = Vorderansicht +thing-type.config.bmwconnecteddrive.CONV.imageViewport.option.REAR = Rückansicht +thing-type.config.bmwconnecteddrive.CONV.imageViewport.option.SIDE = Seitenansicht +thing-type.config.bmwconnecteddrive.CONV.imageViewport.option.DASHBOARD = Innenansicht Armaturen +thing-type.config.bmwconnecteddrive.CONV.imageViewport.option.DRIVERDOOR = Seitenansicht Fahrertür + # Channel Groups channel-group-type.bmwconnecteddrive.charge-values.label = Elektrisches Laden channel-group-type.bmwconnecteddrive.charge-values.description = Ladezustand und Ladeprofile des Fahrzeugs channel-group-type.bmwconnecteddrive.ev-lifetime-values.label = Gesamtlaufzeit Statistik -channel-group-type.bmwconnecteddrive.ev-lifetime-values.description = Verbrauchswerte und zurück gelegte Strecken über die Fahrzeug Gesamtlaufzeit +channel-group-type.bmwconnecteddrive.ev-lifetime-values.description = Verbrauchswerte und zurückgelegte Strecken über die Fahrzeug-Gesamtlaufzeit channel-group-type.bmwconnecteddrive.ev-last-trip-values.label = Statistik der letzten Fahrt channel-group-type.bmwconnecteddrive.ev-last-trip-values.description = Verbrauchswerte und zurück gelegte Strecke der letzten Fahrt channel-group-type.bmwconnecteddrive.electric-range-values.label = Elektrische Reichweite @@ -63,8 +127,10 @@ channel-group-type.bmwconnecteddrive.troubleshoot-control.description = Generier # Channel Types channel-type.bmwconnecteddrive.doors-channel.label = Zustand der Türen channel-type.bmwconnecteddrive.windows-channel.label = Zustand der Fenster -channel-type.bmwconnecteddrive.lock-channel.label = Fahrzeug abgeschlossen -channel-type.bmwconnecteddrive.service-channel.label = Nächster Service +channel-type.bmwconnecteddrive.lock-channel.label = Fahrzeug Abgeschlossen +channel-type.bmwconnecteddrive.service-date-channel.label = Nächstes Service Datum +channel-type.bmwconnecteddrive.service-milegae-channel.label = Nächster Service bei Kilometer +channel-type.bmwconnecteddrive.service-name-channel.label = Nächster Service channel-type.bmwconnecteddrive.check-control-channel.label = Aktuelle Warnung channel-type.bmwconnecteddrive.last-update-channel.label = Letzte Aktualisierung @@ -74,9 +140,9 @@ channel-type.bmwconnecteddrive.range-electric-channel.label = Elektrische Reichw channel-type.bmwconnecteddrive.soc-channel.label = Batterie Ladestand channel-type.bmwconnecteddrive.range-fuel-channel.label = Verbrenner Reichweite channel-type.bmwconnecteddrive.remaining-fuel-channel.label = Tankstand -channel-type.bmwconnecteddrive.range-radius-electric-channel.label = Elektrischer Reichweite-Radius -channel-type.bmwconnecteddrive.range-radius-fuel-channel.label = Verbrenner Reichweite-Radius -channel-type.bmwconnecteddrive.range-radius-hybrid-channel.label = Hybrider Reichweite-Radius +channel-type.bmwconnecteddrive.range-radius-electric-channel.label = Elektrischer Reichweiten-Radius +channel-type.bmwconnecteddrive.range-radius-fuel-channel.label = Verbrenner Reichweiten-Radius +channel-type.bmwconnecteddrive.range-radius-hybrid-channel.label = Hybrider Reichweiten-Radius channel-type.bmwconnecteddrive.charging-status-channel.label = Ladezustand channel-type.bmwconnecteddrive.profile-climate-channel.label = Klimatisierung bei Abfahrt @@ -117,15 +183,15 @@ channel-type.bmwconnecteddrive.average-recuperation-channel.label = kw/h Rekuper channel-type.bmwconnecteddrive.cumulated-driven-distance-channel.label = Elektrisch gefahrene Distanz channel-type.bmwconnecteddrive.single-longest-distance-channel.label = Längste Fahrt mit einer Ladung -channel-type.bmwconnecteddrive.remote-light-channel.label = Lichthupe ausführen -channel-type.bmwconnecteddrive.remote-finder-channel.label = Fahrzeug lokalisieren -channel-type.bmwconnecteddrive.remote-lock-channel.label = Fahrzeug abschließen -channel-type.bmwconnecteddrive.remote-unlock-channel.label = Fahrzug aufschließen -channel-type.bmwconnecteddrive.remote-horn-channel.label = Hupen aktivieren -channel-type.bmwconnecteddrive.remote-climate-channel.label = Klimatisierung ausführen +channel-type.bmwconnecteddrive.remote-light-channel.label = Lichthupe Ausführen +channel-type.bmwconnecteddrive.remote-finder-channel.label = Fahrzeug Lokalisieren +channel-type.bmwconnecteddrive.remote-lock-channel.label = Fahrzeug Abschließen +channel-type.bmwconnecteddrive.remote-unlock-channel.label = Fahrzug Aufschließen +channel-type.bmwconnecteddrive.remote-horn-channel.label = Hupen Aktivieren +channel-type.bmwconnecteddrive.remote-climate-channel.label = Klimatisierung Ausführen channel-type.bmwconnecteddrive.remote-state-channel.label = Ausführungszustand channel-type.bmwconnecteddrive.png-channel.label = Fahrzeug Bild channel-type.bmwconnecteddrive.vehicle-fingerprint-channel.label = Fahrzeug Fingerabdruck - \ No newline at end of file +channel-type.bmwconnecteddrive.discovery-fingerprint-channel.label = Portal Fingerabdruck diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml index 0a5cd5d4b80ff..513311646a165 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml @@ -37,7 +37,7 @@ Switch - + Forcing a log entry to analyze Discovery Problems diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-group.xml index 2132ff98e6268..bf3d76536abcf 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-group.xml @@ -4,7 +4,7 @@ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - + EV Consumption Values and Distances for the Last Trip diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml index 7c5970f4604b0..152bb3cefcfa8 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml @@ -14,13 +14,13 @@ - + + + - - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml index 2225022922c1c..eca702c6a4d29 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml @@ -15,12 +15,12 @@ + + - - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml index 34032c583f408..b9de7d8c3e532 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml @@ -14,10 +14,10 @@ - + - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml index 62433f7c97d52..f4463e3deddb1 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml @@ -15,12 +15,10 @@ - - - - + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml index 2d5a220029184..74bf579b6bc94 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml @@ -5,6 +5,6 @@ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> Switch - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index d6f606d722103..e158c4f6d7d5d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -24,6 +24,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.library.types.DateTimeType; import org.eclipse.smarthome.core.library.types.DecimalType; import org.eclipse.smarthome.core.library.types.QuantityType; import org.eclipse.smarthome.core.library.types.StringType; @@ -106,6 +107,7 @@ private void checkResult(ChannelUID channelUID, State state) { String cUid = channelUID.getIdWithoutGroup(); QuantityType qt; StringType st; + DateTimeType dtt; DecimalType dt; switch (cUid) { case MILEAGE: @@ -202,12 +204,14 @@ private void checkResult(ChannelUID channelUID, State state) { } break; case SERVICE_DATE: - assertTrue(state instanceof StringType); - st = (StringType) state; + assertTrue(state instanceof DateTimeType); + dtt = (DateTimeType) state; if (specialHandlingMap.containsKey(SERVICE_DATE)) { - assertEquals("Next Service", specialHandlingMap.get(SERVICE_DATE).toString(), st.toString()); + assertEquals("Next Service", specialHandlingMap.get(SERVICE_DATE).toString(), dtt.toString()); } else { - assertEquals("Next Service", vStatus.getNextService(imperial).getDueDate(), st.toString()); + String dueDateString = vStatus.getNextService(imperial).getDueDate(); + DateTimeType expectedDTT = DateTimeType.valueOf(Converter.getLocalDateTime(dueDateString)); + assertEquals("Next Service", expectedDTT.toString(), dtt.toString()); } break; case SERVICE_MILEAGE: @@ -242,13 +246,10 @@ private void checkResult(ChannelUID channelUID, State state) { } break; case LAST_UPDATE: - assertTrue(state instanceof StringType); - st = (StringType) state; - if (vStatus.internalDataTimeUTC != null) { - assertEquals("Last Update", Converter.getLocalDateTime(vStatus.internalDataTimeUTC), st.toString()); - } else { - assertEquals("Last Update", Converter.getZonedDateTime(vStatus.updateTime), st.toString()); - } + assertTrue(state instanceof DateTimeType); + dtt = (DateTimeType) state; + DateTimeType expected = DateTimeType.valueOf(Converter.getLocalDateTime(vStatus.getUpdateTime())); + assertEquals("Last Update", expected.toString(), dtt.toString()); break; case LATITUDE: assertTrue(state instanceof DecimalType); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java index bb37ced88f4a5..73389cfd8c5ea 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java @@ -23,6 +23,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jetty.client.HttpClient; +import org.eclipse.smarthome.core.library.types.DateTimeType; import org.eclipse.smarthome.core.library.types.StringType; import org.eclipse.smarthome.core.thing.ChannelUID; import org.eclipse.smarthome.core.thing.Thing; @@ -188,7 +189,7 @@ public void testF15() { String content = FileReader.readFileInString("src/test/resources/responses/F15/status.json"); // Check earliest Service by hard Map m = new HashMap(); - m.put(ConnectedDriveConstants.SERVICE_DATE, StringType.valueOf("2018-06")); + m.put(ConnectedDriveConstants.SERVICE_DATE, DateTimeType.valueOf("2018-06-01T14:00:00.000+0200")); assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.of(m))); } @@ -199,7 +200,7 @@ public void testF15Miles() { String content = FileReader.readFileInString("src/test/resources/responses/F15/status.json"); // Check earliest Service by hard Map m = new HashMap(); - m.put(ConnectedDriveConstants.SERVICE_DATE, StringType.valueOf("2018-06")); + m.put(ConnectedDriveConstants.SERVICE_DATE, DateTimeType.valueOf("2018-06-01T14:00:00.000+0200")); assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.of(m))); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java index f45d701e09ced..a102d4390aa4e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java @@ -14,7 +14,6 @@ import static org.junit.Assert.*; -import java.time.LocalDate; import java.time.LocalTime; import java.util.Locale; @@ -24,6 +23,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; +import org.openhab.core.library.types.DateTimeType; import com.google.gson.Gson; @@ -50,16 +50,20 @@ public void testTimeUTCToLocaleTime() { String resource1 = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); VehicleStatusContainer status = GSON.fromJson(resource1, VehicleStatusContainer.class); VehicleStatus vStatus = status.vehicleStatus; - assertEquals("Input DateTime", "2020-08-24T15:55:32", vStatus.internalDataTimeUTC); - assertEquals("Output DateTime", "24.08.2020 17:55", Converter.getLocalDateTime(vStatus.internalDataTimeUTC)); - } - @Test - public void testServiceDatePattern() { - String pattern = "2021-11-01"; - LocalDate ldt = LocalDate.parse(pattern, Converter.SERVICE_DATE_INPUT_PATTERN); - assertEquals("Parsed Date", "2021-11-01", ldt.toString()); - assertEquals("Parsed Date", "Nov 2021", ldt.format(Converter.SERVICE_DATE_OUTPUT_PATTERN)); + String inputTime = vStatus.internalDataTimeUTC; + String localeTime = Converter.getLocalDateTime(inputTime); + String dateTimeType = DateTimeType.valueOf(localeTime).toString(); + assertEquals("Input DateTime", "2020-08-24T15:55:32", inputTime); + assertEquals("Output DateTime", "2020-08-24T17:55:32", localeTime); + assertEquals("DateTimeType Value", "2020-08-24T17:55:32", dateTimeType); + + inputTime = vStatus.updateTime; + localeTime = Converter.getLocalDateTime(inputTime); + dateTimeType = DateTimeType.valueOf(localeTime).toString(); + assertEquals("Input DateTime", "2020-08-24T15:55:32+0000", inputTime); + assertEquals("Output DateTime", "2020-08-24T17:55:32", localeTime); + assertEquals("DateTimeType Value", "2020-08-24T17:55:32", dateTimeType); } @Test From cc04aa110c903af1b2c19b4f2169144fc1d5b6ba Mon Sep 17 00:00:00 2001 From: Bernd Date: Thu, 10 Sep 2020 22:29:16 +0200 Subject: [PATCH 025/176] more descriptions Signed-off-by: Bernd (cherry picked from commit f98b00f57caa34bb56956f4ff654299a9cfbdd63) Signed-off-by: Bernd --- .../README.md | 429 +++++++++++------- .../doc/range-radius.png | Bin 0 -> 758058 bytes .../ESH-INF/thing/range-channel-types.xml | 16 +- .../thing/vehicle-status-channel-types.xml | 12 +- .../internal/handler/ChargeProfileTest.java | 2 +- .../internal/handler/VehicleTests.java | 6 +- 6 files changed, 279 insertions(+), 186 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/doc/range-radius.png diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 7d8174f44c1f8..875d57a009cbc 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -129,15 +129,18 @@ This means also the Construction Year is relevant if some Channels are supported Available for all Vehicles. -| Channel Label | Channel Group ID | Channel ID | Type | Description | -|-----------------------|------------------|---------------------|--------|----------------------------------------------------------------------| -| Door Status | status | doors | String | Closed if all closed, else reports the Door which is still open | -| Window Status | status | windows | String | Closed if all closed, else reports the Window which is still open | -| Doors Locked | status | lock | String | Status if Doors are locked or unlocked | -| Upcoming Service | status | service-date | String | Date of Upcoming Service | -| Upcoming Service | status | service-mileage | Number:Length | Mileage till Upcoming Service | -| Upcoming Service | status | service-name | String | Description of Upcoming Service | -| Check Control | status | check-control | String | Description of actual Check Control message, Ok if none is activated | +| Channel Label | Channel Group ID | Channel ID | Type | Description | +|---------------------------|------------------|---------------------|---------------|----------------------------------------------------------------------| +| Door Status | status | doors | String | Closed if all closed, else reports the Door which is still open | +| Window Status | status | windows | String | Closed if all closed, else reports the Window which is still open | +| Doors Locked | status | lock | String | Status if Doors are locked or unlocked | +| Next Service Date | status | service-date | DateTime | Date of Upcoming Service | +| Mileage till Next Service | status | service-mileage | Number:Length | Mileage till Upcoming Service | +| Next Service Description | status | service-name | String | Description of Upcoming Service | +| Check Control | status | check-control | String | Description of actual Check Control message, Ok if none is activated | +| Last Status Update | status | last-update | DateTime | Date and Time of last status updateDescription of actual Check Control message, Ok if none is activated | + +See [further details for DateTime](# Last Status Update Timestamp) in case of wrong timestamp values #### Channel Group _Range Data_ @@ -145,14 +148,19 @@ Based on Vehicle Type (Thing Type ID) some Channels are presented or not. For Conventional Fuel Vehicles the *Electric Range* isn't presented while for Battery Electric Vehicles *Range Fuel* isn't valid. Hybrid Vehicles have both and in addition *Hybrid Range* -| Channel Label | Channel Group ID | Channel ID | Type | Valid for | Description | -|-----------------------|------------------|---------------------|----------------------|-------------------------|----------------------------------------| -| Mileage | range | mileage | Number:Length | All | Total Distance Driven | -| Hybrid Range | range | range-hybrid | Number:Length | PHEV BEV_REX | Electric Range + Fuel Range | -| Battery Range | range | range-electric | Number:Length | PHEV BEV_REX BEV | Electric Range | -| Battery Charge Level | range | soc | Number:Dimensionless | PHEV BEV_REX BEV | Battery State of Charge | -| Fuel Range | range | range-fuel | Number:Length | CONV PHEV BEV_REX | Fuel Range | -| Remaining Fuel | range | remaining-fuel | Number:Volume | CONV PHEV BEV_REX | Remaining Fuel in Liters | +| Channel Label | Channel Group ID | Channel ID | Type | CONV | PHEV | BEV_REX | BEV | +|-----------------------|------------------|-----------------------|----------------------|------|------|---------|-----| +| Mileage | range | mileage | Number:Length | X | X | X | X | +| Fuel Range | range | range-fuel | Number:Length | X | X | X | | +| Battery Range | range | range-electric | Number:Length | | X | X | X | +| Hybrid Range | range | range-hybrid | Number:Length | | X | X | | +| Battery Charge Level | range | soc | Number:Dimensionless | | X | X | X | +| Remaining Fuel | range | remaining-fuel | Number:Volume | X | X | X | | +| Fuel Range Radius | range | range-radius-fuel | Number:Length | X | X | X | | +| Electric Range Radius | range | range-radius-electric | Number:Length | | X | X | X | +| Hybrid Range Radius | range | range-radius-hybrid | Number:Length | | X | X | | + +See Description [Range vs. Range Radius](#Range vs. Range Radius) to get more information #### Channel Group _Electric Charging_ @@ -265,7 +273,32 @@ Please check [TroubleShooting Section](#TroubleShooting) for further advice |-------------------------------------|------------------|---------------------|--------|---------------------------------------------------| | Log Vehicle Fingerprint | troubleshoot | vehicle-fingerprint | Switch | Forces log entries in openHAB logger in order to raise issues | -## TroubleShooting +## Further Descriptions + +### Range vs. Range Radius + + + +You will observe differences in the Vehicle Range and Range Radius values. +While Range is indicating the possible distance to be driven on roads the range radius indicates the reachable range on the Map. + +The right picture shows the distance between Kassel and Frankfurt in Germany. +While the Air-line Distance is ~ 145 Kilometer the Route Distance is ~ 192 Kilometer. +So Range value is the normal remaining range. +See the Section [OpenStreetMap](#OpenstreetMap Widget) how the Range Radius is used to indicate the reachable Range on Map. +Please note this is just an indicator and the effective range, especially for Electric Vehicles, depends on many factors like driving style and electric consumers + +### Last Status Update Timestamp + +There's a timestamp showing the last update of your Vehicle. If this isn't shown correctly please check the date settings. +In case of Raspberry Pi execute _raspi-cinfig_, select _Localization Options_, the _Change Time Zone_ +Select your _Geaographical Area_ and afterwards the correct City. +One restart of openHAB service with _systemctl restart openhab2_ is necessary in order to see the corrected Time Settings. + +Correct TimeZone is crucial for handling all Time information in openHAB and it's discussed many times in the Forum. +See [similar discussion in the openHAB Forum](https://community.openhab.org/t/solved-wrong-local-time-how-to-change/90938) which deals with the same problem. + +### TroubleShooting As stated at the beginning: BMW has a high range of Vehicles supported by BMWs ConnectedDrive. In case of any issues you face with this Binding please help to resolve it! @@ -277,13 +310,13 @@ Please perform the following Steps: If the access to the Portal and listing of the Vehicle is checked some debug data is needed in order to identify the issue. The [Example Sitemap](#Sitemap) contains the necessary items to generate Debug Data. -### My Vehicle isn't found automatically! +#### My Vehicle isn't found automatically! The Vehicle isn't recognized or a predefined Vehicle doesn't show the right properties? For this the *Discovery Fingerprint* is needed. Short press on the Switch will force some logging entries which can be [normally found in your logs here](http://openhab:9001/) -### My VEhicle shows wrong data or data is missing! +#### My Vehicle shows wrong data or data is missing! Now the *Vehicle Fingerprint* is needed. Proceed like before, shortly press the Switch and the log contains the data. @@ -319,25 +352,6 @@ Here an example of Debug Fingerprint Data from a BEV_REX Vehicle 2020-09-07 17:27:21.158 [WARN ] [rive.internal.handler.VehicleHandler] - ###### BMW ConnectedDrive Binding - Vehicle Troubleshoot Fingerprint Data - END ###### ``` -### Discovery - -If your Vehicle isn't discovered correctly or you cannot find the correct Properties perform the following steps - -* Check if your Vehicle is attached correctly in ConnectedDrive. Only if it's attached to your ConnectedDrive Account it's possible to detect it. -* In the below example Sitemap the Switch _Log Discovery Fingerprint_ can be executed. - -Copy the the log which can be found in general at [http://openhab:9001/]() and raise an issue as described before. - -### Vehicle Data - -Maybe your Vehicle is discovered correctly and the Properties are correct but you've issue with the delivered Vehicle Values -### Update Timestamp - -There's a timestamp showing the last update of your Vehicle. If this isn't shown correctly please check the date settings. -In case of Raspberry Pi execute _raspi-cinfig_, select _Localization Options_, the _Change Time Zone_ -Select your _Geaographical Area_ and afterwards the correct City. -One restart of openHAB service with _systemctl restart openhab2_ is necessary in order to see the corrected Time Settings. - ## Full Example The example is based on a BMW i3 with Range Extender (REX). @@ -360,75 +374,75 @@ Bridge bmwconnecteddrive:account:user "BMW ConnectedDrive Account" [userName=" ### Items ``` -Number:Length i3Mileage "Odometer" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#mileage" } -Number:Length i3Range "Hybrid Range" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#hybrid"} -Number:Length i3RangeElectric "Electric Range" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#electric"} -Number:Length i3RangeFuel "Fuel Range" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#fuel"} -Number:Dimensionless i3BatterySoc "Battery Charged" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#soc"} -Number:Volume i3Fuel "Fuel Charged" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-fuel"} -Number:Length i3RadiusElectric "Range Radius Electric" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#radius-electric" } -Number:Length i3RadiusHybrid "Range Radius Hybrid" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#radius-hybrid" } - -String i3DoorStatus "Door Status" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#doors" } -String i3WindowStatus "Window Status" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#windows" } -String i3LockStatus "Locked Status" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#lock" } -String i3ServiceStatus "Service" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#service" } -String i3CheckControl "Check Control" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#check-control" } -String i3LastUpdate "Updated" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#last-update"} - -String i3ChargingStatus "Charging" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:charge#charging-status" } - -Number:Length i3TripDistance "Distance" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance" } -Number:Length i3TripDistanceSinceCharge "Driven Since last Charge" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance-since-charging" } -Number:Energy i3AvgTripConsumption "Average Consumption" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-consumption" } -Number:Energy i3AvgTripRecuperation "Average Recuperation" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-recuperation" } - -Number:Length i3CumulatedElectric "Electric Driven Distance" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#cumulated-driven-distance" } -Number:Length i3LongestEVTrip "Longest Electric Trip" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#single-longest-distance" } -Number:Energy i3AvgConsumption "Average Consumption" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#average-consumption" } -Number:Energy i3AvgRecuperation "Average Recuperation" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#average-recuperation" } - -Number i3Longitude "Location Longitude" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:location#longitude" } -Number i3Latitude "Location Latitude" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:location#latitude" } -Number:Angle i3Heading "Vehicle Heading" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:location#heading" } - -Switch i3RemoteFlash "Remote Flashlight" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#light" } -Switch i3RemoteFinder "Remote Flashlight" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#finder" } -Switch i3RemoteLock "Remote Flashlight" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#lock" } -Switch i3RemoteUnlock "Remote Flashlight" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#unlock" } -Switch i3RemoteHorn "Remote Flashlight" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#horn" } -Switch i3RemoteClimate "Remote Flashlight" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#climate" } -String i3RemoteState "Remote Flashlight" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#state" } - -String i3Dest1Name "Destination Name" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#name-1" } -Number i3Dest1Lat "Destination Longitude" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lat-1" } -Number i3Dest1Lon "Destination Latitude" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lon-1" } -String i3Dest2Name "Destination Name" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#name-2" } -Number i3Dest2Lat "Destination Longitude" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lat-2" } -Number i3Dest2Lon "Destination Latitude" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lon-2" } -String i3Dest3Name "Destination Name" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#name-3" } -Number i3Dest3Lat "Destination Longitude" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lat-3" } -Number i3Dest3Lon "Destination Latitude" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lon-3" } +Number:Length i3Mileage "Odometer [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#mileage" } +Number:Length i3Range "Range [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#hybrid"} +Number:Length i3RangeElectric "Electric Range [%d %unit%]" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#electric"} +Number:Length i3RangeFuel "Fuel Range [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#fuel"} +Number:Dimensionless i3BatterySoc "Battery Charge [%.1f %%]" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#soc"} +Number:Volume i3Fuel "Fuel [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-fuel"} +Number:Length i3RadiusElectric "Electric Radius [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#radius-electric" } +Number:Length i3RadiusHybrid "Hybrid Radius [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#radius-hybrid" } + +String i3DoorStatus "Door Status [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#doors" } +String i3WindowStatus "Window Status [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#windows" } +String i3LockStatus "Lock Status [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#lock" } +DateTime i3ServiceDate "Service Date [%1$tb %1$tY]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#service-date" } +String i3ServiceMileage "Service Mileage [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#service-mileage" } +String i3ServiceName "Service Name [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#service-name" } +String i3CheckControl "Check Control [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#check-control" } +DateTime i3LastUpdate "Update [%1$tA, %1$td.%1$tm. %1$tH:%1$tM]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#last-update"} + +Number:Length i3TripDistance "Distance [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance" } +Number:Length i3TripDistanceSinceCharge "Distance since last Charge [%d %unit%]" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance-since-charging" } +Number:Energy i3AvgTripConsumption "Average Consumption [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-consumption" } +Number:Energy i3AvgTripRecuperation "Average Recuperation [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-recuperation" } + +Number:Length i3CumulatedElectric "Electric Distance Driven [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#cumulated-driven-distance" } +Number:Length i3LongestEVTrip "Longest Electric Trip [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#single-longest-distance" } +Number:Energy i3AvgConsumption "Average Consumption [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#average-consumption" } +Number:Energy i3AvgRecuperation "Average Recuperation [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#average-recuperation" } + +Number i3Latitude "Latitude [%.4f]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:location#latitude" } +Number i3Longitude "Longitude [%.4f]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:location#longitude" } +Number:Angle i3Heading "Heading [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:location#heading" } + +Switch i3RemoteFlash "Flash" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#light" } +Switch i3RemoteFinder "Finder" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#finder" } +Switch i3RemoteLock "Lock" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#lock" } +Switch i3RemoteUnlock "Unlock" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#unlock" } +Switch i3RemoteHorn "Horn Blow" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#horn" } +Switch i3RemoteClimate "Climate" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#climate" } +String i3RemoteState "Remote Execution State [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#state" } + +String i3Dest1Name "Destination 1 [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#name-1" } +Number i3Dest1Lat "Longitude [%.4f]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lat-1" } +Number i3Dest1Lon "Latitude [%.4f]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lon-1" } +String i3Dest2Name "Destination 2 [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#name-2" } +Number i3Dest2Lat "Longitude [%.4f]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lat-2" } +Number i3Dest2Lon "Latitude [%.4f]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lon-2" } +String i3Dest3Name "Destination 3 [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#name-3" } +Number i3Dest3Lat "Longitude [%.4f]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lat-3" } +Number i3Dest3Lon "Latitude [%.4f]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lon-3" } -String i3ChargingStatus "Charge Status" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:charge#status" } -Switch i3ChargeProfileClimate "Charge Profile Climatisation" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:charge#profile-climate" } -String i3ChargeProfileMode "Charge Profile Mode" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:charge#profile-mode" } -String i3ChargeWindowStart "Charge Window Start"

R?63}*Xs3BqrpL=TFp0`<<@dxxt-)^Iu(sLEv50%W~uX< zu2r&^;|9yiTIaSYVCHmUiLH#?snc$Pgx3=KS_M^SoF0g zqK`ii->@P5=1W!Q1SvN6<%gMP|CE08A=w0E)5gSB`Q}7o^Ty=8o0D7aP43(-8xC){ zr+jSRvf5dZc2}yQX3U!Y_G7NfC+t3bzdCraI&rmp>QM5*`y)HIcwc*RcpNZ&Q?AmR z*@ClC@Q~xE^Sx)H_idI3!NAb1_oiQbraawO$jW37y2HV$wSYW{%S?x36Lrs2>XUbb zJqmB$EFZ(za8KsN=W;d%Wb(okF-X6r1Z7L^Qa+sf?NBE)6*593omDB_3f=|N)MKY@>$2fpD0tb;XQ}y##-wr3>9t@*g z^@12e@>LRfzoA(1IOCRZZlO{S)#_15U}DkA_$Hd2i{|8^WVJ5ugM$}Afz(X)@+QYz zf?8xHAN&wR+RHHjE|@rb{PpCSx1#cOKDCxhMoY5jkbB3y7v`dciNK;}3Fl<6gr~t9 zKkG7~q(C=$GJBB`8fK z8_)?|;1UJ6H&u}JrZTDl^&a{v^}tT_o4jvJ_T4vPvlk0RCytE65@q5A3koe(eaMP9 zNW=+drgS3LM8cSgjrJz4Km&=ZSSO3tVlA90yDCj@rfiQFthT7^ z;83Xtv0)0}&J5M?AOftKS?^>KOxiexX4Si#xHGL|hv0AHl0j5ryi9H62D2_Wsa8{T zvL+>k)_h_H+A-iPTL?)=?}w$@q^ zVEv-yOSGv!z;$uqi!*Z{b-l8!Y1k!Sb{TRV*nlyR(~gYYa-N@@ zBsi>%q8OE~N)yFocH_pYS_wk2T|Pf3dwAgj;5J!iw<7Np8>?p5rL~G<%!xhIaorYC zj(CgJ@mD@lQqSb7nPyX%ztVGDBftOQfB3&lOkACw=?DA`TRRnE`Nm^bO&9~!YS4yB z;NXmPVOxT2OTsA(Q*B$;8oBXk98Hb$Wv4*k8n%Z~fxpQGlqY227hSf&(2l-$A*8hg zUPp$Skf8?LWU)#u5XuEoMgPU6;;v(@Z3j#D>`4m#d(kS-e?RnZ{x-S&VCnwDwJrN| z&!4q3?59(Bgkd3SouWvUGq=fxIzb>J%|C?+1teds&{i`_e{}{ilk!K|$YQNWbde5L zM#zGQ=YU{Y8Kqt`z%W*gN2t|KVWoF~qdm#dbZxQR^pJi~3~ESM9Qv!i{3Y(|>Illz zh~Or@X9gUy&laH*SM0U!8FC(~7@v_|DM!M-6UUFt&Q2)Ql?7Va>gun^Sa)6{<&v1-E+6)%;{D+2E?p1{FcboG50C=<#+RE-d$>V1qTB@X% zmkTmY*i6hutB!OkSe`6Y9HsfQ`3vvY3h9qO`S2IN_<1hqtT_gA=ikYlc{_9T<-+BU zvm=K>j=`nKRg3*p=&6TOk3F17%6C)|m*%ftIQ+r;k(r73 z=*5Y_uNdI=+hk{o5!Z=+`=QnR)FFLo%zkp|;+OFwUz84gmHW%vsYm~q+;xBMtB)$F zC47t&NNUWNoW+HK{O2ElL=#)?O}+ZOf8PhCtEURrPNnyLoY;C_bjOy+fe#ZWzlk3H zB!BE%4q|;rs^h(xFFsCg-I99wnYe!h;6hj-76UcHnHjPUxeZUVgnIF0GCe-&OHMHA z!b=UCgD_(9@!Av)1=QQM@-$g(C@OhWUOJOJNU5R76#B7H#ICkYwnHBI@>`_%`FQ3tvsc3}xvBQnH1h|AnQ>N$IU{xcvQ z0czMK-`D9~+H-mF8_*N*sYe^cO?1#w3m!Ry^fjx%VJGJtph#EAR!g@rHrZ2K-*zPf7L2k7r3wBCG+nUDifj=x>!31#l& zXssCp{KaxJ=sK1cRpNT&RL!>0(-p#3E4{KTm#Rfjy)i4DomGb2HW4Az+^;DU?^D|0F8lh z3}~iudP?MBaK)KaG5+O79py{m!%K6qc|G zA~)K_-n4l2NK#?no4lK!^PwK|Xz;rbcflTM5q04E z1XxJWwlbkwGhL`sN|M@4M{Y62&S~?xO|Nfo7|HprfCj%P%eemI1`wn~y_hpC6=;&J~IPds+#oj?2WkAL*bU;gq3-~T>W-983J)mkl-E|%=6 zYOzskwv$pr$yc5{TCz{Q_58Dc|M!2N@!1<`S2Z@<%vhUwce@&HHdCog$etRU@tq6p zeiJO^wJtQ8xOe6TwbRSBNV^znS0e2uW4m;_osQ&}rsfWN{_?!cw*kU7ZOpv9(JK9B9# zqCPLXLCqk_cW+Y<-VecK^2tY*mSn$pT$k}B0fjgPHo`_RR)PZN%Wy{x>7sZw1W>>Y zh8#!r4jLo|?2M9>$16C4s}Mc0NHUPZI_JPr@FRYxp4w|bmMuAm5dgk~`aGSCkLxnq zA6o@~I1DudstBfpIf5^S%BTb1262J|7|BsvQ{MBB<|^@GHIgj`O4VSc7B1JKrD~*7 zlP9MH9f3sc81?IP#Q~;8UZ<-0V9%KSSoo726PAPCx&PIF_t4PI6NP`%+6q&Zg9lo?hy|W?@&JZIorQ;@&C)8#=jWEa$9*B&9Q6zx7 z=1TGzcw{ccbW&N4s|np1#LkVRB6B_T1(Ki3iE74f9X^0Ppw`;evqmwf)s7kgOFftA z1S!-+3Q_FYfFps-WGFKwyL=br4VcyP-QRUIv4KJX7WUPb7+h-Ywtl2*-~i;~PL2=<<;A^{yq0c_biT1cFf~$wWH|4+ zanHFyr_B8@h|&*&0fK6bdhDX*O8@~s&j~u*$6v4lCAl;oyyRP*V>S~VK^Mqh%Mkm) zAZZbM16y;ZGl9{Hp=d)~uH^iYGk*Cjvc6?q;x2m1 zkN|jrwVR*pn2GZY7&^ycSw6^+2901^I7r;|91VgQprLVwCQv%wiok&mj9AFc`qG%U zv)LGs-4ebU&s%Un)Q2u~0fQ(*$y9L(EKBqN&^#;3I0ZbjO>HBlbN*HSW5ub_6B z^Fw81A0219sNZp<-+r)X>6>BKQGaSAkdm*Pfa&{e2S?l|`W=VVjPLHQyUc{pj28mB zh#~H>Y-cF*MkpE^CV-$0gL6a|&Cb)8Ry*BL`{<%C!`I*h#KT=Upe~Pmu=8kcA(WX$ zO&UxX8qtqdZbf)H11DY5APf&Z;;>ZMb;%%IKgAZp@?maT)zhedcj{d<0fd(D87t$6ZD8(7zq}l12qF$je3!c8m%p2A=sqm z2PYy~=uygmt6IY>^$m<_ZQTFhf2VLsD}KA8|oYXCSu$|>yXSfs5yHgxg$OZ zKh!T7q!!S4lsJFZGWz66*FC!v8^4O(`+;xAvkTjwx5&F7FIl&}YTx{qzz2OD@xqd! zFK8wp+b}6UMG@vp1|gqH!@m^0Chs+du8>|;(C#362)P-qXAs7t*JtAw)X#x3)LVw- zE+UY6)Ou?=s|nz4Iy&T`NYX8B4}nPR z2d*s1hm|y;ttsEBdNa7Zvg+j58^go>ciwsDN1uMcajBGj=IJMY|NGx9EX`!A(Of+Y zK5H*m3x!lV9p!IZJ(+E{1Hsx|R1d8}d*O z7zcD~wGypX<*_Fo->~8CXw*v$)oT8YH(&ey_rL${yKg0v5zgca@!{cXl}hgV^~%ah zHe0QSQ<-!omd~f!tukkpmov2W{(El${_@DBonLMf(Cd|IE|ZOAv+;Vpn5p?}@qysg zy`^IZ8XiYJpM?2bJ^}wwtyWlGsh3LWMzh#zmGk*TCKFBPWAQ?8K6GuucHB9CHWi$U zq`mI2#T8kIWdWzkBaZJ@aIB^dj&`&y}{9vG|1aS zm70IZd1S_aKA4&0FCkK2)lW-t2Jja4N6s!*-53}=z=^u5-XU#73Kcgd4iu0rrd!c) zW>y?kePf5AA?Iz;fnY{nw+v-wsL+?3NT_#K$W@>sdL%$feWSKql{cw%NCl^AAWK`d zdbChssOOBR?GiPI`LYvtRZnev#7zPXLt(;V9$Y=VkCLUEL}5P zs(N9ApF}_+CZin!0dn9LM1h>MCBfYKUgSXcE#WKFpwDE>PMOG53dI=oRJ|rDcV62Y z-M%IB%#$m49Ji~vYUB?ZldyGjekD|q&JiX+AD|FSPgz2;vx#~$LteC0)4dmf@1%CX zijG0nC}>-hSRCG0S-j|scb22Tmo+qtigZ!(qAQz6Kt>kJaJ`d4}&Ps9qdBQzpZFJJceM~1>;jM?5r(t!E_qi~nkN0179-KUMP%AY!+z#QPYaud3?E0&)U@3f6EnksGif{-bxw$RrOR?&&H3hzF?^ z%4gDgsey5+F<6BNHXI-;uBfW5$8XmzR^py1a@+ zAiX19Tw=IShJzt+damvu4}s;mjNoE<*)ok|#xaD0ieUw@YO%(ohy?OmYd<=oQJ{I7rgs}DYS zw^&Wrn?;9nk>;L$`pH%sU{`6kbIZ%d2Yk!GwcQ5~Joeb5J9bjxqlfnI&Sn#wZ`AVd z{`nQaU%Hr4uYJ@<#`<4%1A8BR@w?8@LLg%aW*04vsUQ95N1uK5QLN}4avs%E?OFO(y-6d-`f0C0 zjDUw-hY2EudU!E2e>KrNn7o!PI7>5E{rlc89N%3ywx`m6u9=qkWI%>kc`I6|y5xDi z?;O#A7_GB13QZSnwR)&rjTFixiFi0O!%4=1dIZd03_y0;Q>)!c&y9x60`gN7y-F&< zU^a81%#<%Fn{u14f*q*}m(zv>Q5C+;;8hTz;!tZ73@5J?)a9LP^`u|{o*@RQGJ&Bs zaH0~1-~b~H2&fjjt*H;Sk?q`xp)t>ianGq}ZjP9x0}X`pfMf9aY{`)*`Xjj|oJuo; zKTwge>36Es+w`{#i>wmG8~=?3{3^+ zt?|%II6M)UpAF4S_&ceTZh|Sb`vGyNM_VtA63(bPK5)&pNsy28zA5jC|`f^ z4}k#01xl_yY2q&Wp07CRX13sX~aiT#Hrf@k}{TtVSz!*?s92`0vzwXxQeSb9rnt zp8j#QqYcK;RgBK6$vkv%fe4P=5TLn$@e{T+&KUEanGIg%m`g|!mI4eiZ?O~!$zy36 z0g!C;Jdi;MoIx650qY}bvW_PS?w7~hoJ6_AfkfUy4aO~6j}*}MsR^6MLd<8(v?@}0 zs)&y$`?(3zpnXgcqq=54c+v7DpzWHy^Fe1bp+pd&%=OB%spD5|`-uZ6&RiR1E-rq3 z(ejmi-+AGS^9!F3IM$g#TuV3|QbG$x+=E*KIv9kHl6LH{v|@k4y+h*gVEejG_{v9IDqU)S}%@zw1BlK{a@pNF@-Yy$%B>y;0t6V@;ZI_roJ%?2+aVU&Vj7`MX){SBn2 z{HaL@|224^U;3Ed5x~`?a)(1YOW%uCFI;gu#|RT2D z)s_ie-0cpv$(&>(ogQRBQxDNFh_G1l`V$l6X?-Ug&j&B*>Gv)oj4s8`mz!#j%2n|9 z-iPn(-t)~5fB3`w2fk@G%kAYKe+3zI{|k44t=|E z&I^}LeZBjOU;OeHue|!OLFip z0t?7iqW0LhFFDOv!8>k6pVwGBAbTc6Y42EW*qy7WOR zD=$d^l^~42-iXYGBcs9kTqI;{lQHT!zYuZHM2ZX1--Em8zm&8ufC zv`F6--jy$25XU(KY$dtUBkiK(P6V!J8U%E%_RgCe(|8woY8Xv<4!8;~$<=*>scY8~ zedEzy1c)UFPP%*~anC)aW4oK`-6>5HO`74ZDK10}wjV)!iqn*XJ>y3E1 zo^G{(hEWLl)Ek`{g)V}BOLSz`H$E?O#=<|v?6FZKZRUz+N|Qf9*HNLRQRl3ZJil+U<}!2o8KDp)B%{gh9tmp@2Ih)ZUq z8UbUvN5(HrOkACu=qp!mJoQGu*cru+(JO09*)UkGBZ_J@}#;^wLwHJa!@cm z3aBDzgI|rRbPWKhO5+CSI13CIw|B*pYmT$>6j$D%kAvzxmCtwr}5Bu4KVy zrBdd(=brigKm0?!7+(wiKx2FNd~^MJosvsSQ~dns(~ldivT&$A*Sox2{o>0{zW4Wk zUvCy#?b6Ch?bFXb1~LW$?v<6QWLecCv7Y5jG8x&tdDFf3ZOhl&%PZ8`_|u=B{Oxal z6OH)I;BR@k_V^Qz{`}`ZpO_e--Q|_)vEzq;iQjzt)j$9LmbY%b?+?HHb@2SoN@VLwpU+! ziA(PAQYdGO72U7D@yh1S8|{HvdvsI_w$HZzs&(&xT`-?s>c?pH^xR)ASiYF?U-G3$ zjj~J!&&PD?&0s^lFhMAZj1Te`38(^IWCGX%2$pM+LN!sS_`rg- zX4n#oPWT4TFMKsJx7%~{Ip>8pVFt{nLk}*BeCV$~F-!Oa(E?1#>oAX4kfcIgL#T-kk^ndf4|HEQ z2Z3ft$(%=hsp1lKdJA*v*Nz}ABilxZcbi|$ z!(F`FvLM>xuE^z?9XJik^hB5sL0?fM-ORZ)sd*b!d!0wiO&O5vi z>d6%4O&!cYt*4%$n9&vl_|rpVPz#{bI8T>J9nO^(LYrzVWTe-oh* z8TptpalhlxIoax2;67s>tOAC;sm`ZG&4l%8x4=?!b;rst37y0 z>d4t>1p`}(TqOW%o97Jos$qa2Jh}#k;HO=I100{*5v(QD+2!Z25^T^BhQwqCMsxS z8Tp*N3itBfh6aB>|M^{idg_Uv{N%^4zWQ=Spk9ef1A|xZyz^%te)t~8`bFS9d%yYK z_r5neer;Xw=ddzBDPLbsrE+n8zVpr-`I7igBs(MUw48qX?Kgk+)1Ru^sK55nCm;Oa z2jBPkZGbN%;4hnt-+j+N-F^2zrPDHB zxV)U3o16UQFMsjWQ%?f&o_^-3U*2`s%(3H*g}JfOYxM5S*%PhhsxRRB{qKLbapQ(c zHJ>kq^3~*DK7OAHmlo#}sn9>&{f~g)7oLCajn`j;K#*J-9K9OKI^xB^7hit-hd=z@ z=9_oKCk5@PXHq9;-UI&;q%K*$?z8T{y!h3W?{uoTSgFU7MF+-#Y6%JiWmiHz$*Pcq zOerzA#J9<~m=q_`2wDRXatqLk@ro2CyUXYQ<)ix?5X~_`ZY0VFGgG8_>H+_e;lNC_ zh7YqNSWprhz^UAcp~cXJKzcl!nGB@IV!63d_mPF*CCBRY9u=zkI}u;s2pJA6CuKiX z`C@Fc(D~|)CL$nFmE@<>821titLh7Bz#Xs=utxDPk}NFZGr{x}1@I^+kdl{bb)&RS z8pg>boT&**&bZl&M7&!5$dhD1@|*HsnGa9n&lF%NDNl;kvK|QhqAmedHufh9V{ zUjP$Ip)iqAJuAfjWxF+9182zw>s@)4N}a{4 zr;?jDB|my&MUBF_1rpV?ql!bSzhT&jw3P35NP0mYH`(0P*X67wi0>SD+fqtj$#OhWC=89 z>}!N$ng+*U%pe1!hk`;hDgB@;ZHieDWcO3-nQQMS0jz$zDtp zRr*r$Ixqs!1_0bw1B{{h;AP~AOmG=2)4(efj^`|3UwT32ChMywxdL-TSxY#*Nc5*L zig3h6ZP5`FN6o}otPbnNFf{g}=C1C;54n>A7)D}f3IpRVtzvrQRM69Wi`V4~Z_ z0&y7z3Dkx(2#j3iUOdjQK zp5ZT*kGN03)ywZbu94sW^6&rWi~WbMjhs2zyJyzh!#E$qFe*{?$f}aAlLo;&T|ncA z0`Q7c6H>5$SQ=7$@ql-`?!|b-r|OJ3^{N;-$r(bTxkqLKf#E(3y!BE=q-0=pc$XGfhV5s>&c^^6%bnliOah?s&oax%KRx!ykAM8*a|idgg5IWWspt67pZ@eGAH4nN zrgNd%b8@+m-oNK-5ZKlJOKZX3KYZ_dfq-jyrQB>Klj(>7{w(31rO1FaGL*?j-+1Fy z(4+zWjvqfjv7zBB9Jf{<`$B*}s-nV!2luBctzKJ=YMXw+}7Xx=GXuD+u!cmx|M^6A9^SlcBhMJo73^T-~IO9 zdpEDhPJyXLtMu__A5$UVFBJC66X835_U7BKz4zhU1}!n-IfqPIP<4cTNs}_BuT}+Bd1WJqL=P@ASHJKGFq&$j8 zeb^;NZwXyxAYQM_h9=Y_U{Su_EwfN$EP{wt9@^T-)_PtF!as38QrC=MmON98Y(!9) zP;(6U3^g~KVccw5y;=dRA*fL;At0%~3d8V)@q>|*u&yrmrd_-awh2kPQ#gaMZ4mr> zl4IBv4e=B2(vw3XhpKFGBF!lvBHv{)woOu#otQBPx;f5sz~7`=z(*{mAv{f``7`5Q zc|{+J4ew50`imzr%&3&WK}VZ_+P& za!LqO!$E0LQl^!*5DtY=3R=K*33-Gb8I!1oEcAtbxfAk+jUGD!FK}|TXRN#e7F3_a zFvyb_qh^TPX)954Bx|xL7&hpIE`x1=mD}Y&?!&hd_uP~H>I0+!S5&yHhUtjTh<8{K zxs6x@s-_IOE~@uVpoLH`*#*rGIggPwuUL0a`%c#zqM&@)3E&`Ig|lGUXrbrR;^a|S zLR<`O88mWC`Y!X&E~MB+RDung&n&C=(&&`=F5(q_hXbMrWJtzQnXl7C&(gOS z7QRq#?Z{8_rL}~!qxUh-DZP9UaARCT4!6Ho69Qpejr+*dktvjMOopz>E)b@Z>g{08 zh=JWaF{b;@NqUM&AU8q^woR0vFa-!xKqWl|&Uu8;xzSV)C8?i!Bo3>uI_b}&txH50 zhQ8WL2|f&3GUXeK_Dc11tr4r%W0{If0m2^L98^1L|8M`H^F6m`UU+nJx)16ZKT59A zG1*L{26TrdcOF_ruk6M@!5V2{Dna+z&jMpRsB! zuEkDj^#JFofqKj(Z%=TA&?JfH=CL#=QYfTKS^Yx#9r>?6Zd7G~CqIWIk!RqFu3U~9~EVsd=1ZQr|z7oMtKy)g9kS9ksR$8SILbYptbd-ck1 zfAy=4f7s~j>1jG`GpA4f@~*ocfAE3w@U_C%pO(i*-+$&Qz~AK6o|RVR(MSFW_*)tt zyxy*@fc!e%oQ+=6I;)4(0`~E-tL#tg`Zs$OFZtoIU z^G{DdUaiVYBtW;7l>*QZibexqtXJQBDN}6~>lIMi=O4WHqaXdybMZnonSAH9&I=#) zR%zSzt-t%-@BDrz_pYqe`+6__>}NlvX}}-VKKbP1Pe1e2*YCeOu>U|cIq%Cb~e-!CJzZX`N!VEm4xc z{NzTO&XyeTiD!~2)qI|87%rBkKA)hY3_k&{1TUacwJsm4hCpU;NIl$MYlPsLW1Thm z3;Mw!jYi?0s-!?GLUtrbksT2iI7x=r{_~;iG#~?+<0@ntY5<=}Z3Vgc4XHgFYbeXPaaD*gpY8(VsD9g8- zNw?~JCqNJ-feVB=x=g=_hUubw-B@3R&=HN|zw{J~NIdaK;@-{S(_h;nSLrwi42{Qf z3+8Oc7&MW$AVBUy2*4)t5Wx|_B1Zak&3^FQ{HNIGm8EY<#`%h5sdUMT!Au9RKzBW{ z;5qT~Qs4@uotMy^yI&d4jPpd1X6nhEQ)qF<85l1Up>i-m)qVAT@p z9ao=B1S)^nLc?8!5CT~DdI#N6H;(b zy%f?QV^&)e#UiU8Nz#PNXe`odF*tNMOiwN81^%mmzBm+JwuG-XZhrp*A2k2G6`>mA zm|l~Zl}the6C4xIHB6T=$(5x&SC)47TEC@HgPC;+&arJ=7&wllF+ORvBN!(?*R_*d z5#bc?HaLX%slZb6UdUAV`&fK%CL-DoAZ5H&b3B zttc@LtK?j&G9JDWg$TJs2BTewlEyJ5!BXo!e8i!MDof!$98*U4&2T$zTh4okZ;e*8 z(g1F%u)myYw35Em=!92<`OT5{HS+trzxyBO=7wfw`X?v*V#&@2EluspYZK_*Xb$bC z)gVC+NN`@vp8lHe(nL44E8z}!9JdhkFfASSbr3`E5)ITh-xoqX<}VX=0)@K7UrG{5 z2#-V?_+jWmJ-(E@>6=iCfbh$@{ic2QM_6n6Kc!<#r5X#pX1=Cd%t)F-Va1aCPdE@wA9Z zmcdT?&rgl*aeVP&Wc!xHJ$Lgrf93qu!~5?1=}+E!^VN#q-bzIVFJJum&+mHu=|9!e zky1SL_#=P(`OkiK>g&%PgV!$X{q}di{?+zv_mypnt$^o|2kr;_S;vO2FV_w5Cok=` zve9$^EcMPiZPE0@aUY`Kzq<+Yc8`qQ7DICFl%y3pI#^PAuP`iUnV%~+QzA^)GBd5Zco z0nc(Vb4tCZ^6qNR~p6Jo@m%f86Dc0wb>UF745qykO#>939qk>J3M%Cti>p&h#=7OZf6)M0PwU zifKO~uo7{|TUfs*IffEZ91sD(frrSvj!ch5E7f44=y4?`t+E}Vp1Lg3Do zoPa+t83y1@j?4zmTO(Hix5Nvu4k2tIbh+2MXV7_+h{?S)jp=7gb}~0Hk))m~$TAB6 z4d?;3Nu2l(%F;{W z%T=Nz*bbmTd7PGPO$de=!WmN1Z+OrIC3SqH@_gB)F&W4F!3GeQGtaZFx;0l7uh zgYXHa8V7KahDg#fI@b@ixiarw8%$GFLBI0tyhZY9+M0adSK6by? z+5wIz(FhikzO%D|3#3>OGZG-CAXuyg_K-X>Cv*~JCcS4!v4gTy?o*)urNyr-vf9i? z0YaoRF`WucMNhx!jSLck2@di60`ei#pjj;f=hYIrj)=?`y*L5m02y7)G5lcAOYi6uPKS6A9iwp^ z!Ds@)F_A4HUH_~%gZeIH&hS#dG>QtiQQIx*(@-9MP&bZ=m+7%+yBbXG+@9F`sV_F> zP1$^@rOfIVBdO3C8yt2XA_x8McfZi!@8O4cj8627j9s$ZZagp6ggkW|Mm6SsP5I7| zHFO!Q2zLl&XN+$A)gk;}3uE zgC86_epqJUV!rL$xBc{|Kl$x%fAh0De|F!N&2G1CrCA1bJ@U{ldF*?orxoxXKD;0B z=kr-s1Wx4=YUWQr_C-kqk!m%#vQiiy9|l?O+q1ixO{6U|?Ls=1ioEdR^WXd4_wKyw z&R_rfS9jfY*TxO^#N)x0>kWU;8xpZw&zs%%V zV}7fN^a~$=zw6iQD=TRe_**K~bD2W){g2)OHU9FKzx?fQfBTDH{NjNJcBacwkY6Yj zfS-3id@GuF4?2#JUkB`m0e}7W1DL6P7EhGNG@)?bfqS?TGE0<}ukFbUFcwdo#q${) z)EWVN0E-9xP!jVcN@@&&T8YTjdg^*R1jKj8M^G-~DpFm%V8Oz$Dw<%_MM)%#*Ubmd zFNS;YTdGPGEg(YN0GKlFJwEL}Lqh~342BGZ-;!6z_ZXR8tRse`kSMUST$PtX^hr&T z+$>f^g&KqrKGf`v*t9D?!jP-22G&3>l9q(~x(}A9+>;n{LmvI2McoVA4>AlbT=#{+A;CXoLbZ1W~{8($kZE`B)ak@J8S=;_3*nE#GC< zDOr<7(nxP1+)H8eB}P8RAQHR|w!;??i%|gT;tH~y`%7ZOJ-!zo!)^7rnF6301_t(M z|6JgFsUlkjf;dS(+)myS#8YvRT>!*%AM64fLyn`@Z2LxB#{qwR)_pNGbwRc(R=ma3 zeEQIfrMP@XSym>gZ5;sw)PSzd%s|u+ZcsuF$MW;Y0l16-AT-Xn6T>VAc`OdmV{RVOwkxJ3;1f&fjS@{ftO4S6#p$ zV_rlLRKTnxY+Mf?LY9jckSydO_)K&O4ge0T+8}nGrW~|mshqAJ2 zt=b4^H^&UXG3L8&ML<1n)JR%MHCCv|jxaA=(#@?ICOX_k9{l&!Aboi4T$?dZSzz$d}yHGrj-n zU;S4gzkmI&{}0E{?iro9JU!i?&2|HNun25mFnGOQa;ICwFmyjsGTm z7QL4DzaY8dL&QJ=FIf+^iHcfWnjcN5oA6?O<4O}p_IFw$Br2>4xw*-<`nGSQS(=&}IdS~Rz`#}g z+V9G8ww;MjT{_=?>~PLG-*nj{S9=D|pU&q(*RNNvuN3Od!pO+Ll5@IHO(2(2*p~Co zE-z=fedo^Y_uad>nu#@QYO&X{Jm-ygZRakWI&tQ3@6}7OI6$_liAxjX!-o%@=dkhh+Q_+mj-e};T0w7hdZgi6sxQtjUOa#Frg9RjH>-wY1%}xN+l# zhwk6ed+zka=(T}?K2YZOzyJMy$8R!^Uj}Lym~s4bAtIaU9x-y`12$N=?>%F zcwQENVEx5fvf4;Tv-3C%gBz^{?3Jj25nv)j#^vQixhjzn$Oy?(0QKT3+5ust3(;mf z#z+E4ryuX)HlPr!99!2z4dRPCJ~Uw8zYx4gVutVpYVak;N>xuJH!~qSpAAtAi-hpc z_Ohx|ZBIaM)8Pp=u!nrvMSM4#EcQpRNEMc?ZNUu)?F!V0sGs zAqv14c#g=zP?)4eM5D8?jacZZUarA;Z*n4Ca5tKr6*eofyHKWDPZw*cT3sG!Ql3CS z>?11CWz7!&ad##D+d^9~B_)huN zOkL786B(riQx!{`e+bd_8~0-MmzQbgWEhffk1hJ;hlDNL?X3kNbTS90E! zob#rZqWLAIHCZ|1jF03ip-A52P1%aoa3XI3glUV?M98hwV~v)4EgH)~YuKKcRy|y+ zUttOZu-JRPI+5w<&3ytF1`u5dIVrqU}I*!uK!oL-Py>6src^T6Ku2PZEj}}k? z=1oJ08ubx3h$L{{RS85`qZowC^Hc7UuYSwUN^oUx2qAe?teTT4F>@sl5NfR+i7iA< zOGq~FL|F)JnW4hSrR2`-=|>()FO4J$)^uTku|0Ld0|>iP^@VcoYAyK3hqvo#zu*4u z=hHLS%o{r+Jwt%#H=3Kr0H|EUyLvOon1PJL@Q+>y36@Z+Ty93*5HVQ>v8yiTPv2Om zV-T^FM1~pbPSF>7ijF`g1WAIeem+TP1quECF8|(%3wg#xG($Qk@~KKm7TA-c09MZ#w6)_<>dgEtM}rVe!&ukJ zE`oUoAE`Ei7&Gw}cf)cZ;-SFiO3gk zlTKovylS@fA?!!=hr zdayn_w%pFO;_li=U+Kt!@|hF$*-^DkOes_L#)^(WVQwjUjpPj~YBd=aRQrdo{o)tD zxYTp8y?*$~ImczEVAZs&s09WvZ_daGyVP;Kx7u(Y5^t8&i`_pRL|1pS^JUCqMbg z#l3qQbJOJur%Pu~7LV-9z5Y^R_ve+qOAY&6p%5TPA}*BSNzR3`)^OGq$XIN#(QwY= z@Xg=5Wz$nnKjDwt(4PVRuG#iWq*hC?6)6U z3=fTaF3tyf;(2$YmBij^jdZ0E2jiA&VR@ZRjZdiA5g+70Tu7xNc$oHIOc!O}85~~E zM}jFK%`-nSo|VqVC9}nvN5?oS^d!fq3g<-lcH(S79vK(aE3VC%8E+!UMUSqv>^h?f$zuT0+4MBk z;#_zcj3F6fU{_%Xc%&!r5EO+eLwWto2o+-wSP1Gy&Xsy}Az;oiXPk+dV8-f7%*Jx| zM8TaZx*6Bin@Ma**H!uV4EvOAU*Ch~-9;?6@j^B0lW|GKY z49RXo7y!Wm2^eP>E0W9qDnNH7R~K5e-*WeP?h>8$mL0{MajcRB`^Z-Vi>!B6N&}xmcMNL5gaR_<=S+qSRpUzs2Q=yUU z@fv!Hy4N+xwS;A2?F?x+#w@w9a_JbzFST<=ZS-=hovJo7Fh&y+vDIS}MikR_~xsc z;D=CY*fz&j`QVd$PKLh-iUWq+7$-=Yz91rGNJAW8Q5+*%gx^&y#8r24lo7JoaWEuq z)SB(0Nq_#KW37jdG#>aowc`bO^Y_88bK4FU@7o`}J^s5rkq&_S$P>~M!*~Fx^ve|= zHYCg?k)(S4-(U$M9g_sHNhA|U%XT^NPjsy`QssK4R8Qxt+2!RV_=nq9>xtgMQPVY< zdSGYjj}Ns%jLfiIfnrE%!gm(?M#rR2I7<{3&{G;`R_jS;dp?V9-@;wZq+`;q;Y9)AgmsvN3y^tX0F+s(d;^pQ%mvrJsB>|LOajk%x2{SMk`M(CQ zYw|#lAtonFEsr;soR3vXb@{?Xr@SDH1Xt@-dB3$>i`&Bkw##1zKX@gvWpi@d*22xdN%6;=u>fv3fM;=Puzcabz-o(9| zQ}^$PJ@dHjtCvSD2M6s32keKYyywPTCnr2-hMh;^CGX&P@0)MF<_cN7>3Q`)O?GlV zH~%TY+UP~CA^8<$GbTut1PN7Y0c?V_4eTgXJXi@ShXlzO2qS>`bV>SEuKGb#q;s?& zv*HceLb<)1$W>!gepw8QxhG}aq`Uw>;5filv^*0yZ3$f*bsxR5^zESI5Lvv^kR{TS zzO!&O<~{~lBR!$)G>$6M3Hf=gFG#DBNJo0W1LasPo10R1Hmd&LX-A?**rtyPEP{h~_L+d5kC_)teZ@ ze?mDgW{ejBKGH=yXPogtk_~*SHEQQbCo~O*dLDx2V1{GOGrgcHWFAaUA?k2;j+4~P z5VO_{!U-{pNG*lAQQZZTBocrWx!j2OI3$%*UQg-K&1}i3R)q^((`Bf?T1R*D00=_7 zWFxhghj;b6Y6ej)HJHyBMErsQ2xhP%T5L2zuG60-HgEDj`|!m4A>th-K6 z)pv>zuPru^FUxXLZlO-HH4p^*qzObpm$6%{R~%6GHxaX;*O(lC8GBF_n&n=^g$Ad? znekwGA>tqN%Gc_QUf+te{Pki!4%P*K@IW6i30hyBV-WZYVJ&Nc1y!Lnu5!#@`bgxZ zA&@S32zTQz!bEhXnx|BYcTM5~ujhijw&<`oNwAg|J62X?)eU)0qouVp>FaSNt@&!a z*-8_v3RRqi8|4irYy&eJ(_fcYNM$-88>H8p(PYtUybcTzOpJ#H5Xxe-bDOD9Gl9kF z9Y_MTA|h!^g%K>roC37L=wrqe6ysjl(=p*zgyUd@8k`w~A<1~`<_|Vd5_>kEp+!zI zFwpa_w<1)mu?1!?esNo%i3Z(?VR9BUEA$PgXfq*^_lZ)WE9L=6o8u-N$g zd9o6Dw&|SI6=o_D0TeP5X2@}WYAKiFO-=vdk{v2VUT?gCUF}((PC`3qnHp5YX*^=%$DqH zE9VwvHWNr5UF(|hKGLgU&$^Fh>fpbl%?H2C?s(R+<0abzUu3o)D&Mz1_MeRZ9I*j7 zVW3EcBH$B{Wp+m92;@^wq&#A>wgKe4R@B59M|=ohrX<;o!tf90nM$_Rir4C3?(WHT zuHM0aRFXgNm3$1~&{x-GZHjyVBwt}r?qw*W^STZkden$?#%#x3?>xsX<(?B%WM+s~ z1%l*c4gPFs)Rs(z)k~C!9v$d15Ef9a1R=u|+Br}9Pmg7ue5?_+fWRu{0F>`Lo!a$) ztWJ3C>G{RuKoDzgaw>2kl$~m|1lz&<@^Wc;rLuCpcKv#_EpNtk!W=mX10^!1OF&rp z7BC&5xk}5QE~h8M)p*%et9N!b(WXq{YRy-Q%$2~MJGUn`Zb;m>IRTQp`|j-5pSJSJ z{%e;W+;#tk4R_zO;qI+l@B8A5PqUNb^|8TLyz?|cWYr2+D!#&GZ~FBY6A$i;Z`=@n zaK}R5XA`c|AiRG2AtDri-KqI#(HSecgE{Mr@8YoYs53SQK)kZF8_|*B$dshmSk8hS zBUOB|QcpG7X%IOUk9{Cj47Zbh6zY#==i@oqC@x);5d%>k$H15X0UW?#p_=d{WnCAy z(*!t@80Sll_AGrf8#rr=^bqWZobnO5%Zp!A?Ue8AeDHj!=AQANvqt)cT!(CtYcNJn zA?dPWjALVB9}lEXeAN=UHXFP$7rf#s%tcJ;K|kiBu>PqDkA+G41-yWNxp127$;FnAQqp;EE{4jc*5(NioI$`obXgQCGM zTqPi4lL&{rPR3=J1rJ7BknT&SWJ5|Fi)zTXt@34;9*Ql6`|Pnn023}pm@bqB*l`y& zpzozlbHIWt_~c%2ypiD18vY_VU?q_$+jTOg9?BqrS$SF~&>vGrxnOQfNZxDHPq>H+ z7(hhrx1#5AXu=gAisa-&cCdk_FllTaejxbtz5haD!#$q&pI!3x01haISHe<2zQ``$ z(*x+kx!_=V@n3YrjkHd9C6fWZVNAxCsR=C;gPP&V+`u=fe3W!WB}fJ)Qw3YT;w@GE zREV_kR)9#NU_n+?Zi@_nBq&CtW5hyRG~KBUz}kvd>j8L%H^c~g9H8ZC|K;gOVI~{} z3~8WqdjhE-A7p~T>xY=+P6gC%x|cB$ts^nykCw3z+$uz-O8n!t}*NpQJ_hQCMS^fGFwm}*q`r$Q5b?u0b!q~7DV6o!C&ASS8(M&+L ztHim8O9-C>&=0{d_T~%8E%(+2&Kt~>YO!3E@kuOSN)@W%q$Hz|^s=njLHKl}tDA_0 zkcG!#W5$hmkgOUvy{MBP0;QJ+Hu3MLMpynowu5m1uCR@8Z z7^vv<1ZAt)hRV+C3gHgYA(b}Efy|#CPd%`+6|vNs;anwvArg$p=v>t#o8rpzqY32Y zIrmlU-c8vzUO_I@vbJ{e8I-Ge!#TS>I*_Y$&*fqP^;!s8Heu4@k=@CiJ1YHW>(x-B z9_DJJ7H)+W@_%_dv1w!Ik)2DY|6+~zFQtbTx;dWLYH0O(nLNV2DSC^M7)zN|M8!uJHdvq*-AAD>sc-0b-rCt8{^VV-( zi9NJ4`q0jWlkfFgqikEZ1bk=px|mwNL)oP%zr3c3UoC|x=FAlRv8-)e9vWUDwNoeZi5IMDuh&!d zsO-AzNsJ;HFdS)^7}sb-3AG3W@S$h9V4M0iVK$l{O>j$a!K0Kd$+z2S9lsz;aaX%7 zDj*%gD&Ct?uQ_u&-Q=KD^Y~NaKu@wP>}j~Bof+*I;141P!w)fwdr8=c0`Nf$BF6w0 zg@KBb(61k{QJxHh7L*JfbU`?2#e8Z@FhUIJO+TB{Y;XxLKsy`|zart0?Axy~n#vyf zGM8JD=PV^VV{WfJ`{)D9P>AOiw#as9*~6(6dB<72HkxT8E<3nZB85&J zQWJ3lu##0{IUE^N*OiNW)RO_?IfEITRG+WZW$vn>wiLw~k#HB=5TYhF;*6LUoa;D$ zD>hInV%*SEkBdc{=_0BcO53r?SjQzU0o8qJ@e)G;6lv)kbRHfv+_3`+xkq z|NG?h@bt{k%V(?Bf0{;OXq(vC^BgmmeVa#cw8cqMSSZv81*zs%v&KvYGz2e z7TkkzF+a#WFc1z`f5M~=CdO5Rg!AQ_7LDM-gr>Ee&{+Vt8iY(>gnG?4_;1%y@L%h} zZ}K}|bIKIpJN|8ZviBcOUs&v;Fgiux+NV(HY*5nfcNwhSiWon`TcP4cTv#k}TZ^P& zkI<^^8EUmt(PC#iHbK%iD+ut{iQSdOArMb#_h*c#obeF^iaQl5;$1>@+2Lg_*i)>z zDguz^TB3um>+|`DM^H>Q~={cQx@c!fj+cSM9GNFk^UDk)zs@|ZZKmGjE0MPU! ze=Hu`S1$#sveY_KuSfEijwiQo&0Rc9CAt?tt`YaCF_j)H;VVP-1FmaF6ZdY8ZNGP} z_mkCCeH|Khofxnm?6>a&T7mh_&VSlx-FJHSqY>9J@{m0`6wBC%*MOKtGf}Rmi&e>; zpqW@sUU>^-rbxr&YzzYQ06NjuOmxQhFce1l75Pv{IA06Rs5jvW`UECo4N5^c)=1w{ z_zJWb?jiStvQtz`)Sv(Z-`T+V+2F-VHUAgQ&JimCUc?;=fKAKQ&QlM?j3fZOjxt)a z3*oDyv4LxetK;b*AUMH}VFQ0jx;FWOoS-^*pdoq$B6P+EVOZzOrN}i`e1tBLutC-I zJ(}x$2xQuSo=y=Zxsfgdbl_)l_4BO6Q~BPJ5&{hYWw2*$ewb6OL8uaju~Lu|Sx~zZ zUaB9^U<2CZs5w=XkEap1@pkUT+304bD0k5ow@^lA%MxS7iWgbYckm_Mr=)Iz5iNLv z8mI?If#~2$0)gz+E{Fj>b=HT~P<9&m%msVr{38qrz$kQztB3`?AZ;p4muw1qof6-y zx?vt}X|7(Ehu2ijC9*R2lAq#*1>F}NMoCW1RxFsF%=$+e*d(`YEskCwpdc>t4IDB~ zAf1yo7SwJpR14s6#fJnGrpKjBLq0nJ{sUOR1|YRsm&zqRFv^O}rjGx)ckat*cKV+i zwk6N`Wbdbmf)lT-H=>d3La~Z2$kXw1EeROHJ(GFIRG>dqbTk^VN-b2b1#Qt`OL!nt zCJ_qSh5?9S21L@Gxv?J`{>Aa-+34az)Vmm&pYq*u2^2lzF9PRYlCi343KY0@oJ|24 zubY4!gcgi3)mlP>)PpTih8y8lCQa1_mNGh0-{r)#5NX$q>k>*NJx~vpL%aAg^)rTy z<>qm1R0&Zz(HJV$QsRR(yw#`YiufDK%rP2)TNDIV(910vE%~5RrI7)n6w94wBiM`@ z%-rZ#SI5^9%)lOuflY6mbf3b1*NyP&60THlrWIPcvE|sUh$sOFhEG7Mxd}Dd)-gQr z5LXR;ZbR^o+hVsy4yMZpIg(K*dA$c}n#9YRvhAo|rY1zp1utPUMlo#O zV3In?rwo1wJCRqP&OGyEJ1wi3IbSJwTS|tE3Q9G36;!Al`|*$eL4&{No_ieFH$5|K zbuQ4yQe74ZYO%v-t3}O9IHo;Z4I-qhJ!vMc-pXtw-kJawd+9j z{x`ic1^BXU=ZBHUj+Z?NX_Rz8B14-CrX7^@B>mq?nnN8Hh^U%3tt|SbGma)iq0P9x zoMO~htOj&yBe7zNMln#?9f(E`B5Nso`h};H_idqL^W=N)`I*4wOwrCIU{gNlspdT~ zSAXQ-UlN-)#kStNc+Z>d6{iA9W=b}9g0Y~FXh?oC8Z#68wVJW(DC}mP zt+e8ayYDU>`C5ZN1{SE_xY~+Zl21PlI*dNH%Rb&a7xIpIFD=9`+p>L&;j5s5dLx*s zIyBNZtcO(X%Z<2;!*m4Vj6OhcbJ2=5l}J_PL3i=u5jCm zhLbaa!}}5s?o8ZsPjd67_=7uAkNz?J?4Q!FJP%9xci&kqcD_r2jWYNq%7FAqSNbE! zb7%h&+a`~X{VzN+)BlCfcWuadq<3j|&*C?O&O-!u;srow?Z^Q4&XrxTU8shVMa);; z`~`I(TfB?r=&51)gcVW+?g3cT=Q*R+M>67F$DNyEP{a&X9+-MWzIfIwd94UdmXvv^oDb@h*#+uC-m<$GJg0$^Pj=~r& zDmX*E;ZHQ72Es}*FFU~sOKLttbIUPhkUxPQ4mqitkYegHT)^vkQ-CR)FnrRNxWyW| zhBm1g@lsEv7T_S5o~B|EW!kMcu0gy5 z)?h{O#xdv?f&rX`A=Z3oVA|i~OjzcFz544En&hey3o-f$K`Ofd9!VXTYh<$JG2E2mJd zUwuqS+xcw>9>jy1k!nL6s_UvIz=ZnS@hKbxM|Q@B5H+JXeNq!;fQIOl?$57Tvxr!_ z&OitUE7IaJ2tgqhUE!^`(!^DRu`VLf0%s%g5$Z8uA5n|(EzYQyg4`(9j)C526aiva z8vhBB%gzvdbo7I6HB`{b!kz(J6oZ*ydIky5DQ?j-*7Oe7z-}4C>lSsq8g?Efyc;*l z-$uNa_SNg8$XKBQ78jfZUAuNlBftOdzx!{;$+PO2Z%Ji0x>;$Y)xZqQon%DOY|D_6 zaHr$sDoMt~>=`AJ)KDU$6nN;uhze<3k!91j*d&O;V1R7N9#jj6abbcgaeH?46*sg@ z>WSv&%#VG|MBkAB2ZR^2Pd&6nlv8XZkee1Mk}==aMU37JgVzKG#mDL6s5i6gXmi)m z#si0|_kSGQ`Lcb-bBjCQ4L*6I7S74Lvk+}%N_OMPPZ#~I4oH^?;Dj3e44P2{gAMFQ zJ0NWVY;@McARDa|A)3&^RYXU&A}*=FvK;&d_-oWd#Uo#XY@)LgXGdJeMqG!}MJt!; ziN)fT6Zucy2OA~sxjXgz(~-Wz*c@)-U)^mSDU)yVWhbK$M~nzNjN-w_k}Q|wwU(?v z#JDkZ3ODM}RNA-P3@^(EtZqoTHgiqZ5uVzQV)#i;E(eZOBGYok!qyiNR{SO zj{eMZPbDANQJKF6a)MQQM5EHLN>ILl+>Vv%p^9THabQpStyd_V`qN`j@{hX`n>WIC zanGmARS8c>4<{r<619h&N3JY=3;63_+COvl1OJPU#kX#W-FI*H^;ZHXJ{ua54-+kf z&g%D9_^W3rAS@NLhJbpQj;CRlQw*n5Qgr+WPqwfev#A*M&Uf|%Jytc zd7GH4aD}Mx9DqW)D2CN)%i}qbu&j^^hf0e}i7^ZVZ}BB3)C9&jJrY7-cY=iCLr1$z;s2pqHmROJ9CM7$*Ic)>znkcs9H=zz0m36R1a>J1eP zfV4{JghNz`d80cDU{n~1#6h*opuS5JaYO+!+0Kyq=@-mvo2LfGi*yr0_|%^{doZzS zL*?>uWQcxIHx*(qs1og?Twik3pPrZv$QIB;j-#~2Fs9#rAfs00(+W;hsrj)7J*VEN z1`F4|D*0qlBlTbgxl13H;!BoL=jkelKUZ=_GP3|C(j>+Jx0oW%OE@EbAp|4HBBe-< z;Q?AE7m6z(RV)pFNMXdtSX?J~0ug^@&N3k1Ml)_llFGIPZG#>#Kl%vLMFRB24CYW% zmn1cz#7aXgt6lG54F-%up+wr!XQ&h2Aa{Hio7Yp|7={7J)+Gb*p>E?PTux$v8m7yo3rFu&i${Ro7jlSdEW}fLaV;e)r(}4@v zFu??01HQmUSuM-vUVOn|PgB3+&^7x3{c1T%M3TBrOakko62cu4qr$8j)2g(4L%jIo zeDD%}t@mNzD)z~Fz(K7k4+rJ7Aq@i>k$X4)lLmj=w{M=C9h{vRa5&`c5VTXPh04`L zr2zyKY{AJ&BkoE}$8!sz%#Gq>D?@4oD&y_x$D*LLkK-T#&k{I_dQ@rCpCVx{xSAX&q_ z{?AOpz+c0EN=i2jTg7>j=>pk`+@V%s1$1OUxrBOJl#VN;&KMh;r@vgq0`=IQGr`Q% z4e*D;D*fk@_ud;@`&@OEqX1NUI1*R1mA2*+_$$(UYE`eF9_=b&vm!4X(9JQuo2|VcpLDLH=Z`Q*t{f#f_TBzF4@6t#0 zI>OcS5k@?&RB0|+Dx?&R$Kb8Nu9N-fEX+LYOFnl1NSy-V?n`yY&;^QP;6~+wsYPuiStB6K%ye zZU{fH)&1&Ymf_vNHMqh+(W_2r^oY$RE2D{PiGr)yl;{x4&*OO5qANZ$7rZp>KRM|;u_RMy=kd2(*@aB&i31ci|EWU?=6OU#8;J+Mr^M92`gQ z)mi{V2o^*U*ckFGh2~NZ?@B+si;}<&vIuPHj0LJNu51D807im8Ft zL6cmnZ&OqT!24x?M{p_4$%t+Xvl0! znvf^<&~*}iM09F*8?2F-kSr{=R?~KSIYu@Dx#H}YmOcrQDM86}Q--oCRv2CkX`8{$ zF~UMQB?m<5x;&_YvIcCVRd*4)Iqu*HkBmm8Z))4YIL+tRj24 z$ykeIs>d5fi<~!(u|sEUV8nGio}VRT6|3$OtHVkksX;m<=c4 z-w*{>hf6L+7&Y~glJtXes>0eK-3qKSKqWTnrqX6bQJyobqSl06C4Si6=T9YWd%xT@J;= zWjk(5Kk`uY(fdbdzrD7!cmCP|Fcz4GBvJVE{YFx)XJ1`5Sg8l_c|8$A0tOQ>h-XZn zEsGpWH8xiiE8BEYwc{5sGh6vfCvL7C{OW?ryVI!ozt->*GNv;C7 zY5y!&y_Do9!A{E-i=rVI10u`?duT|noP$sL=$2W=IXc3>?=Rnv{ z-=U(XAV|jgm2*k@#01GNNmxW$PR~R|Fz& zm&;Cv^5`mb3D`GaKTMbyb)Qh7Ts{&2Dy4Vmh=_(HxoS*(&5eE*`~1PG<$SZ~YNSR| zM_;WJ1t!*Uy?Urx4^o4P)xS>jq5go{AJ`EeM1A>+8)OWyAX6d=A`jq0mn5jc64gu2h+V`qeM}(YMuVTV#MRZ6yEo|a z;@3S(yU)yha(>~nKHL8D^Pdelk6l>!e9&>w9=)0^S&3{&2~{fmccW?eq<1=65{><- z;e6SiEnA6E`YO#$_|E76&QB^qJI_4xh@STQ)vxZ<4}6!F#t;RUbhT8-aI{oU6Epdl z%KC^Bsp4WZC(}TbM07L+0}UP@6DdPODeN zF||`;q7bPTd&5F-|5VBAPA8WV74yqC5WO?zT&DxFc_)skzv>2I4|u393G-d<1`$$p zN$nSF;Vdlm*!)`$6z)G5?gCrCwebDrdgOCFqcRybiRG&U2E z#|mWVLdi{GdKHux{#VUNO#v>G6$Z~`Uw#e@l>75508o9^Ck|jKTExu`U z@VOUak@;k0JX@BnJE;WTG$!V+A_b9wk2!fOQwpdl)_-m~o3bZMuwHP1Uz1z!%Rc{1 zVC)1IhUO-`XXKf${ou6k{HW`Mn*TfDSL>HaNE0*rEeGE8y#8eDzRid|`SP=|Q{U7= z^BtvVQh}0zexm3DxRAVIn;ZrlB%Khs6k}2bCjns)WC5KdcyDfQHZ?wz9+^)KkH-hY zSqD)Syh}#pMo=lZT&BT-mnOWY2`l#4HFsi^$^+>sc*916>1m8cV;3sVl^vOqgM0Z2 z7y<;~aYC)~uL!?l>nY2d7 zE32zjGG$rqL3E%MJ;z2#>esU%_%l&}OL}D+jn*2zOl1-!rYjSLx`ldB0clBBj@@!E zUWfd{nHh{$v(%C|AyU=4>~~P8%FG-w3*LYQAT7Fv{b-HD5=2j_frw*|4$wy~QEei> zlr1^b^ir54rx)Dd9g0ID<2)T9jZv7|09%OBaKaJy>1qG9MeoeKca)(m@r9^OyR+(x zpQ}vDcm3n}1rVW{DC*^aUhvl#L2@J5NN-Got)^?XLN)12b%wmeIO;^j1R!TjUP_If z-JRI9DgW6A6jtf{S|~fC;X5S>I@A7B{q_TtM~s{&D5FXNe`Ocuy>29OOz%s5`Ed5= z%kg6`RYH@(iL7VnjJU#?SsjAcqf>~KE|^b_x=*`P^JpYpv}KBRYzF&;Tf{D~UfvuZ zGahsz7I>p;Fw9SDL|$Y@%ZL&AQy4PPjB2ZUu91`U6hV<}IM6d;{9Vhl&N{|V3$!b$OW4e88xQ3;NQ`uJ;$4rsPX|CkM=qZWRoZ4bgzT4Lm}#qb#7 zqAR15Ml_RnXjN_O zrGIL+xherft&yd(gass{9*K6k1}Q&MVHWULC+rK1Ak-AAZbYF{@{PiTJ8I}k!oLR>{zGS$g+kR*b(tofr0hO*WYV>VB6 z)PSDfkp>+{`W=U^Sod7D?Z0N1hrgU8B#I-*0@DtXLvBW5HHet0cq5cqjUc88{`>5Q z2c5@o4ZRA5lI>Rf-~QYGs|J6&zx_mmzhpwBWWHA)SDTska!Q_`$RqF06I*==jq3xV zG(oRRO@u^Tg9wQ~Ch``%TdN7ev>4`1t2G8S^@Pex)TK7U zECUkaSf(P3(YiqzuwoVFdJH0r8|K>SS|fmMfRd33KS>~aA2lkhD9wU)>+e%vxh$j`>h}{Hk>~IA+v+L@zdkwEf`^@xr_-Jyu^`Wko0)^_-mvxg$Ay zx$LKY{Y=v;t2;YWl$c1n;46Ike(L@mG+H{oXSs0GAPm9ja9~KVbJ74t)lg|+Ao<)A z@y#1!FF)m!rD>DJia!)~xxIF`-wysOwd6H>$v_QnvE^YLMo)89`S?M(>US)hiaxe0 z`M^%swUMb%c`=^#rsch-)^b`xt(x1@1RL@<NwSiOLlJ_avmMRjco@J;GpBMngTpL>^#Dy!TG(D17CXHewrH-_ijo( z^kDA2KR1F4G)Et4LS`SAK@u{BL&yWZU~||6-i}#|Wy>xYVo$_Yf`T(XI2*n)7aN<2 zjnBr%!^I^})>^5{dR~Ay@R6`iEI@bu)X0SA1lA^R+N!m*AiNpBe5e4}N1c?>ad2f> zR;@8YBAL-H$0$_LVR{;ol2f%nIG}#5GC0wXjYute)Xqt=8m>YO8aC;>H1RWC3K9$8 zjh}QURahd-0Wkq0#foe)M+Aq5#faVogFGYyDVQPO)S8}3!x1fx&IB*a1uvzmQ}veL zp|-xHHtq#<(ypE}QwKK&$}mIzmaU;1QCnn!?$ciyf>q$M7^>_6F7u{D3aa7~lH?d6 za30lHYeGnvzDsTD`>iO8RHqX>4C|-lh>HXAr7>?Y=00b4FStE+m&ZEolA%8_f_v#W zWe_R7W+)X{)Kyl06-a0L&@lQ>Hap2RxCdbmw} z`Nv$}?nc(GUnGpCU6pEQqeLtUg?8PdiEt03CX%{j31FYmO-s1Xm9&sB;DM9m19S)T z7>PSE3`!;(8UiD8ToWnoMF#XH1(va++ZnoeG4#n`l8rXq~i<>Y$cPh&4l zv{J0dhqKjVsZL3nKuQ?DJ28T##S04>)|lHKu1VHRt?Y3SV=?22d`e1#AY5 z7^7ctcG)~!cAe03As8w~XjFI`q8GR!mPu{3Mu?ONx*~Je>QO|2i5j2;KJgm-)S2jh zGiEgj-K2C-xMpuH(Q!BN%#zW>?yg>kSvcv{=j3 zS6>Gv4Wm1AxFDV&qAoB8afbS7kr%5D+jV8KEnzY2qXnLig9RrN5c*ckKlR!8v%{e8wP}*3-0@ik|jE z8bI~|*U3TW(V4)7g-{Ps6rp|c$y*xv{m1|P|D%x~B(G+!sS^_9Ctn9i7VDiyz^zui zP?NVnpmIIaYK!_%EADJ?j)E8no~b1SVVPL9F5KmzM0H{p83$F8 zS#+ZYwOSEk7v@BZU6;@%V{+~_*JjY#=l zE{{`m;|!|Tg*D04SQE^bZMReWbtV=^P1q4jfb{VlwW>Td)A+AZ^0#Bwz{P&Yz5&PKQTNpepF5UY)bc_!`T)^eqkRmQF>wLojR27gt*3If zLeZTmAWhjK#1iUF7A+_Phi@co@{YxpE$Nq^t%oMeV_Z!d{g8?bSEMhrN`IG?RF63u#KML{BT2@e7a zO)M2p>`QF8C;0aB*^~uMFNS&%<9DI{`8|uDJs*BZo&~2Kez4}0b((NX{e_y$fKr=G z?5Q2aNb_1IAQHiR3Q>V704u0qA$rYIlqs=z&0&oVq)M_+71;~^0iz1lfs9+8? zA9iIfC^?KQ?n}vMe@Sfg5#H#vp0TE8yv}H`)t1d!;EHjWFu9yem!xUHAH0cy$wPKE z)7%JSGt>htHisCoNwvCBKbY16fjvS4Nls%OJt3Eq^`LSKevY6>^IQ^c-KQqKSEqef z=KLdp^fdf1qSb*w_2tHbEi)0yQIkF<5uytKrJf{1l_mMUi%YK%Hxr>Yl9SJb!zZqk zI=v^caYOK}=cetl>X}Bd4J0gxGd46zd9Up5!HwiCZXwu_WAp;h*)^Y)gHTrTsF zv-A|9$Ffx28=?SdjDepnS;P~UQ<-uE<3#nVU6aL>h?-bIrc)>!iyyuX*hz@*!}kXb=}qSpz1_L>bUO2Tl1hzA%Q| z%mp;5U=k)Mt?SEwE4kw%Sc18JdX%(+FAO=4aR#dh ztJg*U!+-eSH28b#&o61@XKd`eF3GfCI|bCMH8Z6;e`On5<7%rd^Iil}JPYeW`veD^ z0v%yF1X8m(DUXmrK0pwcM+MvhZia?F=b4<)fM|#+Bdx8fNlX=k9MYtgV zD_gRQM=15-ytGc!jJok|7{edMenOWQ!o5UYIHXessHIFVROCC+YK_o^0(Vsq}VqcJvt4=49Q4~Oorku7j z2NF*_65p~p^!a-(>w-5o>Mf4gGXwF`LZ~oB$a5t6W97M2(NbF+&IG63nQ6z#PZFCq z=Kk_lOMUMg%9Z2sVk}ySdoxK}GU-YuL-~9#ms^Z^CjyHzAor0lcP)YA!q;5oxxgl6CfAXPTCQVVId(VGJVQCPyOs#9)ksKKK8Nub2v z;Mqt&c&V(hL*~t}9=n zCqX&Z#wO0+mW^OQE%GS8pe93VtAzgv*$zDdZqL{g)L56=pxIKMAGGs)2jZo!I z%mmW%l^vsuCekqVGome2Jm5tX9sK+?{C)A*2iTQ>RCzcxhTfyu`4RUC#(UI;RbVq} zA}0pMMZc+n)zAwTML?%rjFXezqt6w_4llPm`+;?+DVz2IH)FX4l0EoF>x=Sq9LXSC z{+6rqHn)1k&t`ORCe$Cv$?MoKOfaP$YNIWERTJVeCJZ1nqJ>OJa5hrqq){RHgTjPt zm1bnK61@d3%$PxdCPa#v(L4Is^#qCv$wNkPgS5rcH4u-vDvHr@;y76r*#cP@9%BrI zY@>`Og%Jh#q6HmVHPIcSIYuZ}*NWkBSTaUMF^~<3pQg?AtV_l^CkV(wRj$;cKP~U! zA$(3E0i{;?rZe241zngvYFX(r#>4}$U5|wfJ`FP59Km8*tKjk`8uOl^3FH7L#*G{s zKO3!7y_K#v*V%*xYplx_q2ype)o=xSScoaSh$P^h@@5n`jcA&5Sb@~L61^xzrQ z6KO%W>vqr}J@wLPb(X=cOQ?(}r0wuOpDf{C?8m5_PJyBEAP#i*vHWCliNvkf+i;Q* zI4(Tplb!QP(4-{w@`t>uj$spU&Yan=k>CIHKmA){+OJl<9lBaplYa~$%3yS*k*)%S z3u?x083y3F7Ue!@iYSB^8&go4v^T*X+T^EpH-a-~@KAJta#0GV&Ls+x0Ry;&Z~+LzwQ+EBR?>9Op5&%aL))KU-1e${ z)7~^cw;qTOyXBEL{x#`4n^Q)DB2W#jn0e;dWZnr{ByVz(u&GlL4BQ_7LC7SOwdSkx zhA*%igr}us5Z#Zd{W=H&y0$x#TklKm+|FP5l-b>PhaTFV9=VYG%WH{yH_!Bbj(sqS z9d)0G!{w=XVQwjUb$an&>i!+>W1ok%P=fQ=xS_ZjVc*A<2zyi?cWTeoEP ze1aCoJSR2U8?YZ3^PC!X9UpWYu|?!_RkMMM>inTG&xs*t2NYhl?isNka_{*wKs@vM z^NoUh{2o+Ys>)6QHhPpEjOXV`z*-=ss)s<3D#?}s{6rntZX|E7H{-IQLzz?!hzT;X z;SysSt~%p`_Sn^>h)nbNQ^Vt)<4cjA37O+L4!&2AC?J!0ZFy=VGmb5JwG(>+{Nc$; zCb6V^v_rfdM2$ytC7CtU$ACYsrb|{5wm6>J ztVGYCK%^gnHN`ZBNan>u^o?+cWs^1ML-M4oQtL!UxZ*GT5aWEw3HXG6XQz@5-9me z4TY*Fn)j`ZcZ^&kxjCGOlnhIj@HNZaiSQ#kqmS*PFk=HEa!RcYXtwm6O>d%Lp>V3? zX)l+S+v-ismiP;h2+rXIR-Mt=*}xSr4QOU|@|*m*kK3jA(JlT z;l@qs@oZV_9GgcPR06A9A~)cDY9GoueyW!f<;4ztBV~-{Nb1->hNqc?s7iaKLAWr8 zR+nE(=#(1Flkr{DZp$O!u2o!kD~%E;RB(_beR`^fL~AZ)5EhHg8$aQY6pO)NJdl3e zv6fIeym=BMI&j^JR4xblbieIu5Y3@A8p4>aRyjI0OX*{*dX#XfS&U-fg9?WMh7|8zP~QvASQW67*J^@3Cl!v?Wf9C zWrgBecf0>kaO0QJZ7(ctdvR&wS24h!#(x(UuaPn+K^=J>-{47;P&{IP2ndWPEDWFxj|CGYMww4ntKRgwU%!@^?=&# zNUH*vjt@DG05}*5faquZ7qBOC_OR>N zu=D7k!oa1Na=g&AO7!A4`bSpZzI;(;Gb zhmjV&gGdiL&ERZQ1qCzmjRa%#32#(htohSLK&LEvlZ6z7hN_oJuwb)`!a1SPFn20J z&Kxkx*WaHeQo}6=8mo~b>76*gOh`zas@DB*qVM9bxpLAKT{GNRw?Y%R4S*8HD6gc^ z`OY^Uj(6c&+5qS&_wo~e(=&ghKn}RXfrcaG7+eU(+G>N%`Jg<21MCulD>YeVXap~a zw1g?%cp^O}tY93-4_ab36QkNG^ z;sseKO?kwEO}Z1KI5u75FO8A_@)f@|vd(HS(lBTnXb7u%d>PKn zrz^o?HI>Py)7eC!oLOG3UcX*nxn9rYW09z@+9))dvZ9wr9bfnpNCIlmT&KDoBPKNh%~}I*Z-HGj_$j6u?SRt}1^@M+UMQVL`($IWL&zGCfi@ zOlK3sH~QYFbske7TOt+p>+-iE$yGpPHN}Yb6*q-dxR+mRBjIzwR1iQkJh#QzC zot;vbpb6Xv_|Ygaq86#<=QGHqa7oRGwj4vq%VO>#_eW86xbnc5kvGXT}1am zetK6qgJ=i|7=6(M+YAoP#S9Y0Oy3KTP^n%ZLn+*4uEb0Pe8z8*w$(EPp*2uL6G^va z+UHLbaR%cg!eFK7k=sF9H;_%Jhww5H)di+9&UK8{L_m>HC-e@?V1d{_Fqx|JdJuUW314p%X>TWJ=KT zw1j9-kjK8FopfINv769X8-@-^|3;A#HJn8cMBMsAdc zl$8z{W@Ge)UXwB~-R0$2s^Cs7~f1aJW;7cwx)ms$QMn82#Q>j8E!kJn# zl&*rnWcH}79`-d_GKr;2G7hfSLK^%L7Hd^G1_iDx$Lf}${8t|d1l+nM{@6pV51zAq z^_uuIatuO{1HjZXT{0dA0Eu_lWQupx+8 ztc_+mG<o)Eg3jh)w)$HG(Y#5vT{dNe!P(+;g`ybpLkW8&A$3f5#fRVhQzt@GPM- zmhidhzzIh7M1(@s4G>8d78zdx1c#hQX8mV4<4X?Poo5pty^*|cOYW^#3QH5Q?A(;^ zm^FIdml`2*VFc0aT)F0T#s|s463f(-7%`o{xk`wz&R`cL8p_U4k^qENrDb23nYq9@ zPhw~>+%w~s#kPy#%fQMxS=rDFumCzx3CzIUTx@_w8V(Tt3GDq>hdy>A`s4WMsm~%(MKRM0hA8n zw3raEfSk&3oaBUdq&8(39OxT0bOT_)Gne#9`aa{oNWV}ea4jG&Jl?b+mawGOl9H0~ zH+o9Hz`;li(1u}Sb$~OR5FW4rBtYz=1{y+Qm;~T}lcaW-LEyw+XKY9d6GMvS79g&2 z3q2xgQ(oFdKFhI0ev#f`hcE^bC63cH1-O?QI0@$CFR=ru@|P}fV^B79MY+?|%t;J@ zF8kAyum>*Wq&b}%M8u>ySVblPR?gs__Vb^`7>~X1L@eWQ2W+2z^U<@k@$; zb0TWv_5&AFP*B%74{j2XOLZr8Uc2kg|tNi+z0Q06^|vuHn}PQ2dy zB#vYOI+R<~sxN)JLGVLJp=L~iajd>&Ev-;b^QMQY)Q^*zfiIQdr{*|g5E4UHNDSUM z<_spMFEL=F7e*xpQ5)y6B@B;Pp`Wl*IrX3sqj#D_j5kmFQ8HOv0yruu=?@N_lhx9V z01-pa-@vU=9vPZj|1Jck>00qdv|Nhd(IUvoiwtKwU%_Mk!i)cn1+oU{E`nuQ(ZwB3Pqx^s8{81WD~6R7mcVp?+>|Dcq-( zPIDHuaWwZ5nqUb9k#2A+%D@SZg9f#$QXa4D@>3I?+C4V5;oHQP_k3GlwQqaLy8XGu z?ax^@|0S^PK>XZ7ukI-^1jcO90f4W8hPA}V4&+Ua2@(9Q$VXN^`somS>cth1z6CQT zC6TI#Fd$k+5&3F7oU>2^zN}MH7f}O4P~1FKuokL*K+YZE?9`0^jQ$D*G~qd&EH11p z$MeVcBsSbrK6|j%4EWO$LxH`pYuJ+}xXcu-{?wR1J!X$yy|VPpi09&<EEfj^V3d7jO*F9wVcxshXwI zlySc%0AIBN?CXF(4FqM}sh-uY)FbWqQu)~4_TMWAGOp2`$TuuDTe2CZ2aD3szjNbE8^wLosgWrzS3O zMxwB?WBRV2RyUepAQ_Gu#dIYQC9zrzT0h#bgyd@wG>1lH$gAGY(22{!ZIs=aTenOj+@K-X6)%Zm3k^(2qa4WaNZ7ODl*I<=E5q`129LdNAFqL-I{Soy4j2s zYbkGXI+&gp&@pH(E?|C)dEgNEV%!c| z9dsV;S^O3uC-S5mn|9|eYPBM0ncIyUy9fk>qB+1^5lGkVX3~497(c;1FpPN^8|2Oh zd-Nc1EfH;URX4Gn&URfQfDl`Nu;z_+r_`R2GEh;kogo3PP6sX$DiON`c@zEv_Nh;t zAx!lt=VjTT3YT2#cQ_i>NSx7DNEw8A67CeHBV29skXL^M3~U{fmF`FOD7CqrqP`yZ)zHyNHm*_@OLsd)x$n zzYAe?#6}P{(!d}wR6-&dfsknSS%ire@ExpfDSQpsL`O(Zx)K5lw_yCZz>TRp1>>*> z?G&VJVhB1VZgUACAaF#4LNO$USl}T{(Vw0`>B=T$)g6s83Ig!KRo4pRTanEF?M`g? zCbs3<^rlb4+n-;AHhvS|elXc+R z;j5^2YHUC7EB@{)Q??W6Nu|%AO}#_|bNuyZ?DkZtEL(s|Xv0?p`Kd*9oFQUjXWI9~ z{nTFoU%eKVbujArZ=)v94r2K^YBn>r+>A8C3uWtEH14R?!^y4p1zvw@+IG^B7;={e zd}UzPsCwDQ>ra#E1w7HB%v+c@c2+?JnnN(?E;FW(PXUXHcekw9vKfT+h4rADCA@?qlnsx4cw z%P#P0uVZWEQY1Uw@ulFoaqlr)B9xg}4EGK>4$b<{W0Cj<_CX~YAt_stomuczj1SB~ zRseta)3T=;34;trLs%^;!)++cEr_dF@pJ`r&I9OUd5eNUQpUKHDMv}|y4|&evBE#* zj?cg_#n6#vjC>3d>M9Q`qY3#xb*yLd0bh1+!j-4Mdm2lP~FO?*RHro0cq&>YW? z^UZSM}{A1~NBw5?_cK47IUgZOr5(pkX*SL-*m3+VDv(#nh|Ncsr6onByv- z6V~Ak(!iIViutv|aRp@%EKa1-k9=#63`gbKpUE-AEIf;2ay$`=Itc`nELVM40_lW% zI|bDCq#7tdWIN;us!+*$0Vd<#tN(x6{yfNzT%VP^#u?R^A_3 z;c76pR&V7K_WpWyglgdpCL2x;%aO==qs5EQ{^)U?_WRbi z{(~aFm6eHsGG9V8fnGK?OU<^3V&JNmjPU!TdRGy2EiRvtlm{J}ytssIV?4wz!W}^X zK&BIZNTXyvE3fwwOSxngpU4c3&LeOY^CLZBw<^Z@#2Gx1@>qi22u>*0R|vV}P0HgA z6hpRVfHw{s+|IZ~-i?sebth!}bJID$>j?a}Lst9MZ+*Y8>!*>uk1yTv$5pV2t59;fqurD^8Mq#L&$RE&3HmLOWXiM`P&^0@L3sQ|lO41<)N4;SPe zUNS|ZG>aFLyi7j~8y0Dg+_wJC^SRr0tQ>q1 zIWkxzBhojwt5eaD`E-6JRZLXyBKfF8ye#jZ6Yr>8`zclRX9NWfg13}U@SptJA|w2Y zm{n@5a7ORK+BSL$$oj~vaNphKXP&BL<_oozlC?(A4CN=5Q$t9Wl;5nqYOZb}wFPtu}3W5D9G6h`gFUAI@J{%UlGst!FOHn3W%-&q<<; znI<7d&?D`>a;rooSgNKUv`Is_r7lz=8)3mX3$HZ4um)u5&6$@RBLO{w~m*p%<>_YXKxcozzAd_dNe19DjBsQkaBcMv8=8>}|^= z+|VPH(^It#GIYcmuQ&lBK30m`BM>9Hev2Ff~Mkt1=1oT|B|2i<40~?mf zzg~tch?Iy;Dh;v}g%y+ajX!c?JvXY)+8{zwqBKLq=MotgAv3(Ak93C|4n^&DpyK?fggLmJt`|i8<-MxP=mu|a#$Ky{v+OR8*(>QqW{aw3m=j5OL*`Gf6 z(09jYE;sFBuAF$`$It!n*{5Ir#n1lgum18|zyGbj`J2B!bofBiDs60(aV01$TjO50 zvW>2xQvwUJ0tLE&_{)jlt|{3Y%D;TZ`*P1VJ$U-hRNcbp%N2znb-GpCFK{`|xx+u6Mb_RRw?WmNrlG787Tg-GBFgSMc}xYcDO#Uk3c?#?D`z(8$JS5t4b(UJ<+6jshjjnkf~2;e?Lsc{;M5 zl~E|kv|mzI>|}{u45~rWxBv!eocD8ppsqTT?wGJlVeOj1$Dx`P;1;o4k6RHdD5I5g z;5H2*A{fW*)!FGz_Vf0<($JWUNqrbaN|_*X(t)8+!5k**$jzPQ6)fu7mvWQWYE{ z)R|;*GEtpLtd57ixVZZMYHFw|TZbfYxlnF8oe7!GtSPQaO8-r_l?~~VnarmQZ0N30 zuA>TVX0P`8i^R2G#Ru;%J@!2(zo!2}#I<5AsC}n?>J&%n$p*iOSj%ugi%_uCnna7UjQ+i-JTWp z$(HVGhep;v)rqAMznmYNc`y0!z4^O#+wBB+E>~Y595<{GgB}J<42FPBRBL7;WoB6R z-n7FdTNaSHK2PDZ%WqADKZ}(nXQH2@dTms9qVc89*X3usRGF%Un)hgg2USn*)f@apD5K<~+YL!De1IOjhQ)8?vDZVqsv1uOcOq0cT*0 zU_|9Q?542m-YyYtz%h&>&>%<-&aq@tIKhr_AwYIDGeo=8^wbqws z{^~Ekvw#1-Ts~PWrXG6efjjQp9SW~rz3N=LboSfd{)6Y9|6x24@~tiX#b18sfrswT z6r%M;;qk{G{pL5ndEfo_%q>jL%}?ywwewH@~vP-jLjUOd>&;{Oah%E$~&ym;8+@2#;ZY01;dOuPoMA(Ot4U1FoVw1ZDB5ja;fc zPgvh}uh3dr7PgY}++I@~Y7&bTz$XKzRy)e=SR*9~cZdR1k*>~Tz*q}C)dX`xnh49= zHfqwFn=+%u0ZxGnaGtD*WEeHUKMgU=qpC{NFAma9Vu1uD8XfW<{(Rxpv&(N&A#4Cg z=o)ZVpwG56ww-7~QnHB*_^&ea6$!j$b&3sJRvO@Iv`&RE$+(CJ;5sa0>_!LMyFuKz zA<6r5W(Ej~m8QWWG8ZVHw>jF{e$ntsF0pyEN?h4{6Hr9|Hl^87yiXu^- zm3vJnpau=LS|P2t#pn(L!W&MAqA3lAD2Tzft|EZwIH6VQl#QH%fvl_xf_aL8$QP66 zicMJ+r@>iof!=-hRYiXP?tlEZb8{nev%~XqBi+tdh2sz{TCxqT9*ac*{=ADIIc~Je zcBcewZswhCvEh^&PPx+)M1m*?q>OK=hkxlEVU`2|INmMBT?!an!Z9^6U`V;zQn?}98(~+3L{bI@PpCn;%85&y)aMfF zAe^B9Zb%{^UcEb!+3|j1*DEo=-yMG^;P39k3B8eGScSF-=)`dbYW5P|MEu7LFi51N zd1^al>eaREI4BFTP?+F`B@;9V?>d1+mj%*neJ_LflYj5$UmIFG5YCTsiZnS;V>`Z( zzir3*+s_`I{pp3(_d>;4^08$;f=>BvCuNzJEtCKaDoVQ(^QA9>J@sEDm`K0;qukCN z*^}=BU#Prp$t3nv^wLr$wUEwEgpZwHd2c#CKa&V8C1sYIyI`qdHiB_F$!d4K;4C$| zfvZ>hzAg4)CgeDf!rctu59C4r`M2C$ZEw8?K+h>gL#lz;St;sf_NnHBA3wY3ia zw$*=Scx##`-|U3!j#AnZ|>^HP|?AO!};58 zD_{H+19I9)+_m0bY1r$8B*RH+V>4ZEFISv}WOZmV{OPd&!^z0e$;c-l6$YSlu`|=L ziwe$^R^F6XGVO8M7D0w1`B8uc_(@-w!1Nn{!rD@%HeYK6X|87HWX+2CxEYQ_0hE%g z%=$A!v(e*g=?l{l+2JgZy*L#)Iu*v$j)V(iKm^;7w_K$cW|W3NxE-Q**dK_5U>7xS z;3i5k;U|hPPD>nAXod7BY+&Ldsszw*fd4R%B|iyHHOm1h)3g)O(n`4G_hlz!KHpU3 zN)jB81uv&A73w$GYm|~m5@&IQftXaU*bd@vp+L{5(&d9U0}eC+0!Eu3`k4tzbo%s@h@>7ne;K` zMurv_6X#)!xIiWb`cn_xSDq;Y0-*drR^W`z2Phz*Blxfz$Rz63e54Jy3dooGWJa6_ zt}`Ey1Qbtg!Q3bof>}~5E}H~Ju!N=)A-YkL&_EZk98dxs(F9DCnTwz8U2SD^$@}lW z_uGH??ce>~-~GY&ABmnhwWOIy1LYA*Y1DdzCZbsKOP?+&gNs;V(islzVeN4 zd}D6<%Jk&eAN}zkz543Qzy5U_dgt9Y{^U>pB$fQ6oO1ecapri-m)vt2xM`U@JGU!E>Ells&Q1JF_U0O2MKfsiT=j^!gI zMRN3oo)TW&yEp(u(sxekCk;3t{-7)lfKA9mOWu$O?pUv?EMLQ-WbLoFfJ;=BD$C=3 zRLL(kW@gmn02Qp~E{mq*S)Q(KzgEejY$SGORd9c_-U<&qE+nZ?52T<0!$T%|iLT)$ z1OY6N;9Rppc$s_S4G9;}5d}d56}a=!+2zkyxGi%n(>i#TQ*dp zhPCX-Xz-JBW~Dg)atmda5<@iuLVop(-7R-}>QK`d zIdXt)e4I<1tUBS|Myk`hwi=kWkQ?J19q_nBVYf~wQjk~RF(H>#G(~vfM#JZ|l91Ca zWos)F5m6<64SUFt^F&L_i4r}Kq1J%U@{30+he{@BU$^N!Ih$KBV_Y~-8k49n6Q;7$l@Bi*+YoZxx&Ea;J+KNRBpfSn>{? zf{Kk5^Kl8XbLPZYX@c7nMpUd160aGO7KIbB)E zR+r4c=>!5NT$4>O=2)@6lRTz^QBetgt)qJHPMPE#DI+Tj`vXYAj_A~hygXFg`EKFP zXZ?GhSi1d}3Bcd;XZu@bD&Z_dV7ncg-nN0C>p?UMFhv@~H^kC%V(oUS0~sliu(l4; zNHtwuEVt%*-Ehke(GlsU&WUc>1Ehi#o>#6E_wD%__(tbZ72K)w`-0+X-|X3lyxOQ34o6RdXitx z@T>oZ^RtDzu5A>6sP#a|qVm({3w!Q#l1q99Lsam`FD12dMuDV!t|Au8$);=N)m&pb zWi4e(v2xmWWa1h^H{^Al$|ktb90#-o_G+9yT)1O*_Q+d|1JIMyxtXon3qU~Z13{4z zdc9Pmvr=^yW91=#?o6${l&p=UD%0iGI#B>S8=H+R=_x8km}+74j>w34FysYf zsB_Xyf@ajb)&v`PCS2(=BaMX0DId@*r5GCof^p zSrR8&MjGHzhzzuv9;Vln#3aaDS|??iG6mb8U!<*GR~{14Q|uXI4rOP-OmqRS#`mJd zNp69MfO$WQj+@86Gb9@-q~jPoY)e$ijv~f(Cjr6$7RQRyII6JM%`~kDz=Do*3%vlF zQUih_6X+8?CD4FO5vBXPo{~#|GQ?{sW*$WWXBo$Xbym`ssI4kHE3J{jIj^@25SRu> z1GNz2=*WEH44N&}RuZLI6oCpl@m-L9ldhtx#yn!*6)97 z_l_O0ix-?~?q{zE_zTC@>doq{J8u2vH@~@O&z<+)dk^&2fBjd0ztIb4lc~rpxBT_~ zd+rW}S7Wi@{rBIq@9sT?Qo2yeKKRfBzw?c6XnAPo&K=a|Tb*w-i;q42$nX8$@0D7q zax>y|D?=maxpZ;pbgrJ52;aDO5FM|Y)t?YPJ(h4_vp&JB0l%xq6Y!oH|h{zeU$9}~A>(};D zfh&}VYhXxJsM7{CfpY!12@Kd}8v-tnei*aCvnFh6TS*BgbOgnb&c)-**Hdr=co<*| z(#QSYYGH=K62nD=*6w7?{+fN~!f_bD6MX0h*;jm=QC6=&g14M}xe=R*oyC9=8sKl( zf0)`9lY(41gLt<;9otT`ae4K@3xl?kxR`e+Xr4+D@He;OL$@bu76BO?R{pJ5@onh<=F)Xbp|yx!xMcyrssnKA48Uro>pmvZWd7#7JP93ek~!7r~IR zoC<+r6wveAsnS}T3V%Kp`~)LhGSk%1rrfmnT2%u2`3*V>h7_x^W_XXrn5)xc0$#=xDhq zt4on5M(EEBt!IZ4rAcBPNo`KzwiGs|-oFcDij!XMy^@r397+@b*I>L;+6W$ z)s5?HTfN5H9i`Us!}%Szeyy!*K0NPIxYRDLmw)j6+#S14``$S1dsDUmOvlDSiB-O%q3^f##+8c?;r4Vpk&*RwxFF*+>cBlR+>gsS3YUfpCje{?ZkEFkFZFBB<^Ht zvihFbfq~MZ_Qgv8F9HhI3~3(HXvHsmtTg=sc1`>RY9Jyq8ONn&g2-szV7)T3eu(_a zkOj=7b#ia9zEW(g;V0fF!ceZZL^cH;A=`XyMcoy#!-l}h&D;Q3bP46Ez97oeM+gi= zg)KW4EzD3Mu?b9%5mG!j0k&U+Utouhy>$)iySp`AYiW!2_VWqi?>| z$)|t${BsKans#HyZ9D$-Pyh7n*)Oil3{6c8O`rdCW@@CFPhI_W_wwc8Klt_^eCIoV z{uh7o7k~3Ne?2-jym_@#t>zwl@cwUo>s!+^V_s_6b)EV9{Xh8qcCT5t5)~^0?4zNP z%NOfT0Vw0`l$Vf(dJu+$MsQVn$3eph1OAY?J9$I$KyHW^BNWtY-q5PsK?Fi2zT|oD zG|vDb8I8`AMA4|21A;Qhdw@3-p(XWS00d@3G9bP)nu5vo>6g8X`Q3i88oC`=6uc;H`5&Mehccf+pe4poJ>tr&9&w*{5*>#}FY0HgZi9idFu zY^ha4v;vN#7$(6m25YI=#Z+afTn}0nqhtzp)M}Rs&0MOU)6W8dx9AR;1@M|{28Qw%rz>NQ$%WVn z4lYL0OXJjxtKCYdnI`mr`Z=Hru9OCdLDWEA>-MrsNlof9b^?yz`-S?7FLgm%!Pzkt zI*YrhiE z^!e5Fc`yph%*MU|951IYp(*a7Y0BJk%Xbv~-Fxp{`l`oo+}L?LUEP!iyPaOi?tIxh zzjPBzg9ki9@eP_HP;2*5q6SQ)q$|JaEKY=PA`o@qiO@0N9k*jYNnG8_osb+EqY3E#fwLU+7h0r}l=uwTF>QZ|D(B8iSsx9GTR!e5bz zO!4=gJg8N%C=tDFJ878&ZJwZ}+D@|5PL-_0#zrx>?c>ha8+Xwi4qW^LwN4)??A!A- z{-=|G7)4swkrl7M`%4hp(DdsUR^Ag?uN_)WUg-2>Arx%E0jg@-^5&h+ZBTEaE^iEI z8v|6l_wLeT-`gk$wO2j)5_5!vov$yI8|(E}aDMCc9EeNs09PBmOu=5PcKzB1ZAD3! zK72)T@2$N2LjLZ(PRfTk(7JhFCSut!t0i%e9?`B`>ST(o(sat1O*gZ(WW$M;?6tZR zRN+wI*MQN@>jqw0e@$kOCzGe%%kRED{^FAc2VAqfjm>ney#&s~Vj%v#dR3BE)mh3m zMxy15!|Ml$r{FesP2PzAFf+}*;D?mWc z*L{idRIW8yY9+`M1S5au67V8dTO>9CUl!u0&n&+^6FreA%fN9ZefHw&f#uYNL}>z~ zC;?Zt*O9qWesK&mn~`tfk5TxBk6$71nftB=ciHBRdiN@+3nJX`D+#y*DvhP8;dn{b zq6MWn3xNG(U1SUYIaN?eUF)C+#Mf?IN ztY+jRu<)RT88s;)B$gqTd~F$wlCR5`xHZVqSxi@S(aT^kaN^dSEU#Kl&9bUj%|qLE zx3;h}^E==8#)pUA@6-#gJ^w72Y+-hMW5asvv4{WokN;?5a^&h&r{fg5Nxzi|T-+l8h{_-zIu3QL5*L!AzXsN2*_{mRx{Pk~qeI+!{Eu4`XyA1$exmtMYsV4z{ z6{`>_F6A2u1%E)p?nX_Yx!jB< z>-K<9;k+y;^n$G~CvaP=B(Kqd+R?R!?13^aQEXXu3p*Ax^K%??7ikOwz{u6kaVXd$ z6Tl3b>d9MK0=y{3jWj1qdu@51MPY+$7xalRD2McbrEwm=AOg>s_szWwcnLnywIVa@ z4b@|c*fVC(>1G;ES*OsHDlLD!G($0r(`qN2cDC7;#cc!-*-o`B5B07}D3h<*Qr_!# zAYE^}+X+rI9(Vaj7gF2jXJ%qw&6 zG2JBc>#QCfArz>xAOPQb=0eTPo~)+NmdsK-h-!f>1b=W3|LW`B+|@R3hj^sapSuD# zXvrH=rM0?}Iy18VF#wcEMci1+j_?c75o%alz4A~0>Hiw!_s{;>KRtW)sDi&6ZtVOU zNgwj+0Wgl^f$yCFbO=_A^8?w-#7xYa0O&0MHLRl9n^y22oo(15SD4V48DEVBKfSbe z@biUN&n>@mcKPkgfg^a0J0F2h>G(0^FA?#Cx%lP2UL*CNybYrUyAK{DYp0VrTxFi-Sr`He_f-Pf2G8liGwyY{^*oMm1D>{iVXronNB?JtYS^!*3v$RKx(~ z(((N6U7=?mI=T4EFBV@r<9ll~aJbl%WeQb0RBru_WhX79VZnwVnrUvBv84VkF^BDYp2E_2#LM+$rID!%wk%Z^IPtuh;%nUXbAapvuA!0Coc_FT=vY3n>aaUQC?r&-n#D;kUmF;Nl1VpF9fwOFsWZJ~D<46d2hNZHj@(* zqt8D3%z+QyJAVA=C!ZYJzklza{n?++Elqa1t=C?C2}~9^e{Lg}nwT2;!$11Nd+ynP z{P?GrN6vrt!Rv3n`pU0=-MRYf?xT-A%q_oq;}`F}|Mo{89UK}y*Rra={`-w91B^mBd411>&g;S@APF&s z3**Ee{zWoGYNCI(<^%JIoXs;4BoCoVk_3U341~<7Fj1P;7w-N+1i07rb|5(h`j7_w zFCi1+COO+Yn1&e*%BT;mVXpK-wzY4{>l$D?j2zdaIV>D}kGj#C`>r?j0L~I6 zS%(c}x4!0t5VQb>1aEq*1OqD>`Ajo4WBE8c3CYa0XF*i0j=c6EhHYLWU`UJr%XT7N zi`JbIkQ6&d;PQ}klLTM3yE4rKc~PU1n=iK$JmA0XQ&GAP;UKsSn9u5z%2u^zSBcog zR>kR*ET>SnGo_}4P@x`!x;!!g=MmGy_$_(ZO(-b0(wduN#p!Z8JX{>QRJfS72n*Nz znzrbgnNjPXVYusceAvK3ybOB@MT56|sS7c)B-iTXXX7`1Wk(5hqZ+B!Ed6vFBCi+f zOJtLDWhPM?2juB_FEKO?WQPDBpb#Wam$8$rOIctF^?ToA7$EwXt1Vm!eG1Mi)R!4r z=)5ms3OfOQA&2jM?;f4@`-{K$6GeVE+t~T56MfVHbNl*DxiN2s)@JQc0Lz3E9k#hK z8QRz^w47|q5(I+7a>gjSZ%cqbc?jk|4EQ5qU0(nA;@UyniV)$}fax;KLtFqmx`~76 z^an=bHiVg>i-`FoG?@`@@jEnY0NGhGl$6=b6LuiXgW&Zc!RkHlHvoUobgTw%>)DZM8RMOv-P$<)hJ=R_9}GZ}S9jsZct<{8 z^R;Z*hOF5M>%1EtVYjmtE79nLy50VVe;`da+Fxu>4UgZA+?w^p$JHM{o8Na={k_+| zrpZssxuvfiH>0IT9?0CWbNtAU4o*CKIdF&=)b16twLq{iZgpbZOJgX&^{BNB7JuV~ z2+fZV6n5|Gq-2i<71LboOtdg%TQPlhERSFLwZzqxX$G45Hn9eAekD>EklHi*KYO`_ zG}n52gcU~1HCfEGb*A*lgT+T4%*HM^nvqtk-*l}R%+?m9ej`3?G*T(drJYhuUXtf7 z8sa>pjM0UGrXkLYh|Pm`dugX%~kFBf;H9ZtO59n_DsQ=EL$@r zd)DrSORed-*yngGA&jBYi2tx6KbOGY<4XslKl)yN$Bz7g*P_`grRGY-@{uR-@b&Cu z!CD|{7aDU5artJ{bmTZeBwQH9tP|x)v?CuB_8-IwCnNHf$+?wx@DLn;9%&#ZzU$lx zvDJVZ*|>x=^aAmsXl&7PVvIuQ4xJSwVFeizW3N~(7D7Gv3n2sD>h@ZZ&`rd?WZZs*6hOf%J8d(JYB=d1lZOJxT#8ZyJVKl+0 zBT<&OLE#@jgE}Cw9CNit&tL9zB>%a$YuP}~o z5}jAlm(taFD%59iE)jspd^(S->gbC%HyRdbBGXz_MX(^|q8D0(d4d#m!n|Q-I#*wU zF@(%WRAX7X7V)jj-L>bAZ+zn$-~8q`fA@EPcgK!f&R#fKYvt{B^OwK+C73KcIpK^C zJL|ro%cpkkyzN{6@jrh1+u#1fKm5ZVKKjVt|NVw#RbG4j)o*;K_*e;4|l-}#+C z_=Dg7`7d8?w5xTibm`LhTWA=)I&T84_TS1LwCBECJvKPAW2k;jH=6Aa)3c5+BSuCloEJ?8I?@u&L9P9g$pg zjvmbt&+F#)5D37Ldl|bDglnxpvA#lzT9J>V$ajR%I4X8uE5@P(6O$)QxW*&6*O&w< z&gvVQSSI7V zSVu!T)NqQ~dOcaKW$HEXU$f2VYpL7}+Oq4uI15Y)tFlaL0rr~W@4`GDiW4!CDKt|m z9FS$T6Ad;N3oU>9`sE+=9irE?OI4g<{D1AL9W~F~Z<>|4O6w7`{UI@@(29DmZYONA z-M#V59GvqjoEWG?j8cAF!ZuJYpu|P<#fJNkF})%SLyyxJxBLJxI1J{7retr?C7p{! zICBPeEF{knnf-~&|MFk{pA`HZ{NN1*e_wH9=PxJv!Y@ODrg@9}+WD;!IFSk`RV2Nd z8S<9lYP*wdT5`a@668Ax{X!2zCSUT@a_Y>Cydfbnp?7pjK%{xM&#eKIKsy*4q9Z=I zVIR`zYS?Hx@}eZHR+@e)!L~74{3~ASe|ANDb3@ic6E|R0Clqxp2jSNYAg?K!Gq^3) za?7dZrJcV_?s?L;@7dtJA9wCO(gpl6xS~!v>%Hqs2!04M#DTVFW>>~(-Av6{CYalH zuGmNvnwerNRd?cT&mO}N#jtSqMy1Vqr1s*o0vm4I5qkCMSZw%f10}YTGky-lmU{TU z;QS{p!edO<+c49-TMvuPST>9_!6NP>-~noV`e9+`&URw4(p-z19pusCVp29pbIj*D z96O;-2>#qWK$ z@`EResTr+Vson}k&7vrp#&gzlE7K{v(CSAt&eIl{;D-J362?amhk) z*A4-Uh~2BHvy7NkO%o^s*^ANQ#A$hn=L1YXRi4jT{*oOetk6viu4FbhN8riI9JLYp zm4BTY1hsROh>UOGFo=ts%77lk%q?VV$^#kKGV)?_KNgs&I9aRLkPn0uYoSU@c1y`r z=2ueZ@Nk?*oe<1akfnaIgqFOeYv}+(__GGGQ0@v$LV!PFu`hM0)C_cbIaJ*4=A1U_ zi#F|ey8}*5J788BcFV+%C|3~eD(o>RBx(>Ez<&TivZK?9Q$TbiQ{b`uIu)HRD(5&W4~vbyU0*#71<87N@9RZ!gs3qg7e}j7a7tUdy7WR;Xb`$_+n(5Afm5 zG=vz?81)dd=wrM%Meh(M($LT&RVB_Me57Rl6?@P%Lo&EGnU9ianc=eXsRZ*3IuS3V z4@TqV>2zg5K}>9GhiU+m(Fxna}&wRSK3wv>jHhEW%rDl_i9>(Qm$&mT1=R}YM#quIS^3}1LG2jM{ksoLnrQC z6$6oqFlK~<-MXke@5Ih{pX5-tcJcJ3^DIxyxWOH+?9{ z?dHJ|4%=`_PDke9kUuB~A;3R^YB>?4p^H1IlYbfEXuqh9VGIYE$|8X%*GM9$XmNJK zNp3d7S34=IQ!2D7?lT_-NZ1e6N*s`9VInbinFj*@^4yH2(JnfoE&g3hT+B7X-U42l z3?E<4TtaSiMC;#98=L)?Y*c-&2K!exvf=zVDptZ)UFjine@4Cm&5dsP?F7Crnf;J; zE)(w{ycjPK4j+1IuOh#%fBk=&nY{$9tlV@S@wX<~_SrN4r-UAt(+Fo4k;-iMwkOwB zOCDV6F-C$fBLRYc!;X+*(iNFGUds%*v)}+SWa8cq@h^E~BJw#Nq%qmOgg_J?=t(MM zbfL${e1I9wpzc^{8r75IXptcnS%X_JCk@xAhEb(!NbgT(cmJ&a%opSby>-R@wOO5y zeJaCWk#J<(nQ+Z-x-u_oFuGBz6N^`>@oLHH$Orcs^)*}9UJB_nW7UGcR+G65dV1AK zZsh$NxwT$)wf@$t`5m`LfA}ypYu@?I;19CSd{WrA2OQIj_rDBSYWnfj%}w)M*+h_b zCq>l2IT?xKV>etJ);#oXe&=mz|E01#8q0GFgJ6OztYj)nF7o4`?GUQgs;!{Dge&Ak z5jW^Wo71jx>~#Pb)ARVYo@eA5t5l=qTCP!Q%V$941=Zp`cUNEdkyVnHd|k>{m(!Iw z6AClQN@PA`he~xdL2eP+dbi_CNDEL{I4rM&GRxn8xMxQ8oCjWz&J)$CVsp{%h8i7z zv$IyTrm~GI*pokVDU`pItPWS4`D|lsC39*%{>7RghRdPc`RT|pA|qWRsRL41(-+pS zyeBXJzWO3z5lv@nG9hfYv4hl7;ylJm0+@|Sz+$8Y##+mqFSphrg)2@wQEmCLq>=TH z78A0e31PZy%d;o2okTbJw4Hnn34!OTODKYx1+g{c9ScGUeoL&xset>$P@*&HCQ|n{ zvIgP#NYDIB)7h%*YNo>J$X6@m^EKE>qC6kS%@EW1H;@~lUAV$gaYf3Luo;m@3sW(f z!@snUI7b%8Eo~_?3etkrax+kE#nRQaY-7D*#XH?%-AQDs{%)`6bm>AKs@sXWm2BFn zhAmqzgWkZVq$1b5G#`T}s8F>GpY#+o3}Z-@e}RC=JW`lgOr9e%EhR4y5rDh|7p-I_ z_65K+U6uui3XTyVXw^k*glU@Q-pR-bj#tbROughKm~f;W528oPEX@`_4Km7hA3BlTSXr z^Y+_H6^a$BRw0=1Klsr7J9qA|JC$-P8ZXTi8lm1srQu{kg}F5|6Uo@D*Q;!7RBCn% zq0!Kvk`+OI384%0g1uo0x}=hZ-~?X)e(6l4>IK4JFmif? z@nB{xM<310T4dD9UEGd)VqmoHwJ5BDu5FJ$>WM6)*b^=54N{O89hB%xwUYb_plo>&JohvQ-w{6Y$pb>lo&-G4F!Iirpm|uC$ zV1?tQg{Hid;af_c3+E?*xm@L!IzccnMq9)jgg;|;+#vX<+=v*6jxJL&Q;)A@CrgWG zN+*6^{p|V1r8iT)(M+RkcCnGrO+C71gW8BB%7aTZw>74^0bvPP4!0OnOfM%df&A#W1{v|)BdmO9aeQTl+&&=-gS>G3;&o6#=@wq3=X(UVlG9i$}j z)9@o77vX?_KNkG#zx_A=R|S91JonfaLx)dX`Y@dyd|lwTCK;`nd0DeUpvbX0vP*QW z*jSm1of-gJO38|RWk8Rq1cyb-=#GDD)_S2X@9vPBFh9Z|J;EIbhU6^z?sgpSBiiGM zgfFbctxY3I*Q{>RlQ$$v8evLR?M|`R6E-r{1xaku@ zmPs*wWkjfxnMR-*M^c5l4|O)2$Xa&9TZ2;LwU+^2R#N5#fr;L%2B2mD+6MO7iKZ3F z*OsOuClEI^)5&t(pD0Z?oseoy3FJpTkXt{;7!5&voEQ-)eCleW!AgaHi;ndTBP>iQ+CHzODF}QXTIL{MaviF z;-3S~0Dnt~FUCWkWb3m4G7)lPDVQ5t@E-|2{oVYo+p$H<$(CC(prHUkiYP`aI844S zpCgMD#=wgV(B(l=x4-WR0|*8*s~LGGG*+A>Ov5vpB|%1t6WQ7#DTH)I>=3aCxLhLl z;A8RPH1LaRF?|K!9H4adcH9FAQ!@utrGDb-h}t-V`Q~aXO9|Pho@~S~l~a}7?Joh* z^2YaMu8snFSJetqzHWu94fK`l^fDD$sksWcLHN?H=UeG6ao0-f5-xm!#5K+J^Fp`Ii@S{%^8E}&Yks+BN zD9BY_Hsn0@lQP{JloV}DgyqFjQXLv(zz6v7mZ3uMccr;bGz2cx?GPqMD&iLThHNhd ztF-P$RiHMG=B)wJhLotEte}#CXX@c9K#GV%m$}^%=)B1An!aONOXuFq?z^M>v%l*$ zAN=^;-~at@?cTlX@h2X8_>qVH>Tmw)JKy>93zttjy)wf^ zc|pgKJ)saaNSfxz=oqb{5YRt)4oidoVqIRDq!&nl4w@-{@lE=R;n5vJq02u6^YWNA zan_9|?)iq<8DFP)uvIyhk!q6ecuOiR%lAE}-G4CyD&!0>ivaZ{-~bsa^qh(uPnKs9 zJ{C*(LQS(qXh;?Fz$sSKBW5du{!$+N4k1vOWAz{$0Va_=cX`$11)Zoy9*A4=Kzzew zBaB}&5S8#RzZ!)Qmzn{@dGAw5+LGHDyqPBz9r?l&pi?GYHaGRXy@>ZsBaFmdtA{`^ z24#<5dI1Aeg`6|>3Izg?5d<$$Wh*7?n^jK-YXC8{rSt2AAkYIN9Nm?^&o6#({L+WV zFCJ`KH+_iw8yOoQa6HydkDP9?-H|6|?sSYx?+t+5{)P9qet$dqw7<2LmBl*xKzC z>UOSfXKS`hCk@PH(vZt)vRvGIptkoJ|GsDZiu|BrQ}(QJ`TU0xBXgnwx)W`7i``nZ zG=9OldpmyZ_$^e=`WxxBs%su^R{`Q^uTW^&IyZr9DJ$L(U`CD$ues_QT z@%v*xc+hw36)*CGz7qI@kWS}!vC~Ve=f*~YzIe&k+mK||?#4<_ zKUR9=p-x_2?4=8&Z5TilWCgHhAUCv>6b!L0pY2+RmnK%y7c;fRWM#N&FJR&E9Jjl^nUE|{Mqe1k+8{lh%%;(lHyo4TL5?meYC~CpoJ`SC)s*@2CKy`(ZCJ8` zkbgl-|#(2vmg|14e;Cq1+W&Z|6zsSOOphnc(n9fBy~Z-DfzH$C>rhCco2C1^fzhB#hs z_~Fw%xp3jl%$_?+kAJuN@r%Weo~a}zZCOOf_+gIVI66A?%Fkc=+rNG4`R9Ll@Zfua z@M@`oMb}g)~NrwgvvPY^))Zi$K~|Jx)r4FqTEg#k6X=*RIJp% zkifWeUrk7f0gtzpn-TIK;KwD-u4AFL? zHuyos^p2+aWoUt}3Bp)Kw#Hz75Z%HCipE^^U+yAcB5+(4b)X$oV|C=cKx#u2R8B%6 z0#AgGX#ws69>5r8ES)m>f(p4s>of&29l?bn0cwEHO|wW;UmL}w+gi4H{1gOL zxbu#}{(WFOKwfd*-r~Lci{HIBfB!v&y?2$Kc(jx9b()d-@egA^elqftCugs`$B;=z zP1lc#mA)$Y6WYu*KY3SPV)*X8))$BE)O@-!TWdy;1wsJ?MDkO)>auOitA)<>8>s_C z0@*9_y!FK&Z8oBtn_$6(nPg!mnenCPL5g^L-DbF4%r=&zrAb0br4^WroS%tb0R_&+ zX+WkkGxY@J6WkL6?X5cA9}Ov z$Tog0o0OC7^z#0EbRpB2kp28x<)*A1bdBt0v0A^9 zs9s1^hi79a%vOJgrlZFIi%ZFK7gs+R4IH^V{buyBdvg2tf;BN{WKOCei4sO}s&+4G zcY`keCg$RhFzkIlTFly$c!(N|4kg(){X~jzVVszb%uT>ORciQwZpfDCtixGa(Z^Wo zX1Jw#0%aiTSx#L5d~k+_V^D03iVp$j~% zCNNz#wT44#h5=wAS9MtL_QfzMED=gbkTNUd0a%cc{M=OJB=x{EAc^=0CNq$CK{thl z0a899B^3byIm0c~7A;JY!?=WG$cuC{Rguw-KHx)%)CmNko?1&D0n<&%nmQ;qgL`5Y zZ6OnqAK98A&2&^A2Xi~ffJ;Ox@E>;p1m~~+S_4T7en2F^2yZ|E5eDwG~XL(p-<2kH^3& zasWvHo>0ByEu%-ou2ZVqh`1mHru>W7zyq8ZNcTBFQw9{l`-x!?O z*p%TP>WCEO6KZO-E-{#ioA0@SqKLeqdP9afLkXc5N@HQ zo7)fty~8#zX5_3T`Q^M`74YX-qm0lDE>Be&>&fygR)jqp?Of|Sau$zhthf)h=99w} zD@HKi*yw+XmkQlF$qUt131MxMwVMMR6s!ThuvTWFC1z+_man#`GFh}ukZUTfmFpr#W> z-I~17CdNLA_M1y^hMbicF9v(Uox^29HspBkcUGBR~Ep|Ky*5{Qh_U z`~U5s6K|Zj^x>!H-d&1bRB2F;0xY+Fsd;OKs5d97L*0aAZwGlP$7}((?do-e*C0c6 zY84%wjT9GqCYyMP7S)h2cx;<6NSvfcn5A;t>895*W28~Kj0-airZ6(0Fz8t;p(Bh# z5QU&jvmk*oZeK{0Yw|@Xd4ZKktD{ZStyf*zkPi%st0EcfN*Uw)4^P+ce76Mn+xJ>- z*9Vn5KWuz3)!+YlJ55i0;QQ>AwRfJ6e(i%)-FX7zUL zC_M6D{r%U=Uwqg&ak%mMq1L%in?s+KhmY2;9Jd#S+l`oIMe{WuwoOLEdev-@DmLt` zTGG?>$^T z_;~)-TkA*Ok(DmJT)JKfmm9vEe6(#jZ-tAohQr|aD^0=!VVj-xdV3jAb@gh0BHHVd z3`T9yAcbSZZ(G$5C@yCktjtHSdD{=R=#>3GCFe_J+ z9h+ToAv#(_4vc#7E^|ws42mN;y-K4FHXf#z@#y zjuvutnT{e}5d9mrd;@?kV}Ur&WaNY{wtyuP020OsN#3{?!G+sJ2=ewx0t5zE$QEa# z9&ik7a6qG^e2OWnFlL!~7nKa%fpd~ELB~KJd6y6(KW$|ZnefvC&T#CW_fo1Po4Me0 zic|zD8APJli!T301Orjhoz%fG&7{`~;CL-FnyG~?Ct*8@a&9K~y?gTecPB0$ju+(< zsNgxIHyc0An1NV46Fa?}8k&utH3yf<4ZlA#jBPVaCoY5M2*k)xTbWOsAxeme%7+$Z zvpPKw0d9(o6@JStc>{osxR=NlRK?hdPH_uBN++NA7j%xLA_u-<=R7@~J51xb>kXy}HLSK`uIdYG(CUocumN9xcxSC$%J`-p2t@m?mf!{c-S=&I0@FuIwNv zGbLsdX}n-rR-PRP86#U-wA%9CE|(+-bQ16%D#$muy>kcnBQB30RjmG0qTMZlDvX>3 z`Qe*o-=)xzAB_7yaoI>#mK-N%ubeJ_{KJ-iv{6gd8kux{J)2n|HDV8DmbBl55}Ame zx;22ABmkNZIV3A{3=cR)1@t0UTMy=CM$IiuMq`v{@><_WupiuqRwNAGWUAsfQnJ$b z6y!{LMHCu#+ycmu_=DA9RM=9xBTH)}2pgqy2EigsZm~@c`s2U)k2>x5XMgkUV;9~( zdj7q!`IA_MT8P*{55-+KU5A{#R-rVYBPDJJnW0%aPOpniS%l4bShCCmknMzz54;xCl;&$#O1Oc%0QNByW z4dMeVkpVGvakLPQc6qy#wmP|VEnaA*BIRJk5~r@TO80%z+y72^@8e6m-puVVANDxA za)Y%56RSr8uRW8#=dSE7^Pu+DTQmFaNI(DN+L4#%F26H1cX0mvugWJ6mw*0Z@xJ|B zEk1BxsFwdqv&a>v4dr&PHRjFqfZ-AXx*Y!{^~iwMQx!g!)Ig9U1fn5EmgOaDOd zXXt7>**f%2>B0L!qs9B~X`MJ^H&Xf_9Bv5W>X29=^2NslJ=mer`@hKTx^3;yPbVVR zy|V^Y%_ePLikGGc5VGs9$$VG?2Q#sAcw@~9DKb#%w#|k&X0%#)@tOROb`*bcPxX^$ z8&iijZG$NZ5Kgka^)^XuX*j=oSLx*+bgJv^b|z6RO{c8IOu?5Ln@fmI$d)487AQct zmP{0Zr8YC=cCgl!H_q&CxY_A%(K$d@d)dk}PnMs4yw?)HA|g*mjt{LJT+3XL2?nzZ z5jbxm{7JZQWyCMva0B@%&IA0-#!e>6)1mzEOyt9GXG-nS7&^0jrc$DUwS`( z`;O96k2wWDZcoqzVS`s}Cr(58x{t&_@+0o!hxi8Ffd{x!AJB&vx!O{?B3ljPrBuQJ z)|06%W@-`~Nv_nUsuXRulgYAdJ0b>Wgo7vq95hzIvbee^Wg{a`cG?NXh*TxdaLv?X ztradb6IQ#}-6+GJ<-{ln!X zQ;47mw|b2Hx#|T63Kx(zg2h^}lSFxjaFMAja-&-eFo$^%d|{?;g|SBP5ON>~BQDfU z4FGQB%urKYOkPw9Gpt9>)WcPDiiEL$?0GgOZ^O8+x%@_=hE?-&C9iSyUn0*@7=FZe z%$S7VrX$a1G}3Y-)q49&LkN@OiSTj8V2DM{70se7yn{+)BxWX%%B@7QvOXKXJiPw- zbYkej>cP>#Cot^tFO2oSuPvIwhN*lZaR$dhp5k2QMKNrz?#P56H>Rpf`G&j*jB2En zMkxEM{R`v2a+!n}cY!_|PPtK8x28U-oqD-)=&AbYS4sySE1vpUZTe`f7_mF0Zui;> zIXX*xFxDa)Mj}$h=roFQ70@(gtxGalku7z!Aqs=Lu7nBEx}Kr?#8tZ^`l3bHrcs0j5vC+Wo0D91%OgWff-_UTGyl~;|KEW8{d1wGpfDU4)3KrFb^pX;ypa8LvD1-&7qB*Z-!vRgpuQ|pAO3hHa zTf#Bdv%|}&^AzK}7E@25MSZs55{3l4(_Nzp#cIQ3G>)m3I(3FyOES`RfMUWQ4#(TtH8?V9oVFudWjFfa9N zLI3sagxx6*2kL;oyI+j%eR6sCJB8f`Yj+<`XaO%x&3_nu?$P{?9qIe_#(wnZ((zaQ z?>wKme_swDxMN5DmRp2&+*;hbr?7ih`TGwyPJa074T%zgLNH#OX&aCS1KM$ZX}Z%b z*j8da(|;#S(+7U4(E~D%eXe5z`fb1;gh1{5a^m<~smC6Gp0{(K>wn2DbDhEbxwxANXbdMR~bI=(s_I5!rQp6J7`$p}My z`G~5RxTzec1BJ}9t$jx^7fQOX4BM@EbLw3F_SyL^{*=`Kbz}3z`|m0J z=qZvG84hiQ@}n!M^E0x|;}`zS5Li(6ZC*_eMGE5+Bt_Yn_w!-@A;2HS7UgS|mlhLe zICFXZuok|!df?KzA2Vnu+`HFW8irMdq(m8lDS!`1VIYWX6G&fj)ukNy+X^5wupM0K zrU`vVWfbLvab}#5G)xD%g%AT?C(Bk^esU`Hn+Th(x5BCNJS7o6niW5keHP_$^K|qJ zS$nrBFXi!X!;(e%Fq5mvn?1&L1F~N~W0Zz`LxpTa_`tzv8b>0;xI%-_sj9$ya&f4aLR&K*K&V)89hZb8k$3ZV>`p#>@5)Cn zO)efbHatNv)q7pWln9z6NbeaEGZtkAC+o;?Dk6Kx85K{hW`-y~6_r}tPV>_(gt$Ct`Hrn>`0GBLxpihUt)X3N$d>{ z=?)f4FED$&l~j#cUhA(6LI!P&YT>-;$ZN~W81;xFn<#+|GnyUpe>fWa)O?%aomlbO z#v-P$Y#Km$nudAJ4m5-pVDN+^nb7K_t9FILjf>jOv76kA$K;)Erh9P34Kzv@Uw$>VU5ZAy&%MF!>T(6I{#&W#^YDbZ!(4AREb`4^+2TB0=P-P*FX zMf&Ty5`K!+kpyu!ycm-3xCJ^vs8*-ExmhSTS0=-sqH$LpKx#r6po+=|9Fsb=OiQ-z zlEJXrq~6N`E>AIuw8bg!*ooE$f(%XICh&toyFFRJfEK6?>%~W~E_F{#PPM}&{9PZc z>+M<(Lt+6W<|!)WA=gBez^@ETUO4aE_epo}Q!D$P3*Gynwfmjok5BbyZK0{T59f#8 z@_qJ7;-UTdJ9npl{@mRBM|z3WP|VEKhmKiaeB3(v0c4#xY@hqgzI>{eUFmgVZ6{u_ zlJkiXA{##9dRbYvDlE`6c1s@-5xT?JfO-grzOQb5ES?zUWmxIAn)$;w+KEJUYAJIe z8yT+t>ZSaxw^m;MvD4hb^@b0KpaZWGl$XZ}`}U+CesDILm`F6I64|-xjm4|ukx`6eEi*Y8k>@7CoIF0GW~^NBUq{{r<`*Q_c2ezX2-IBo z;N5DgUsboAlJ_~bX8u5d^rB%q4~ZJ?gr`vtd}Hz*i@3^#0r3 zEZY-j0e_YEUn65dU=9>R5CrKC`ww1T|Hzj*KOZ{{q{EU3wG*LF#)6;fz|CSAGz#5G~9pk`{AY44;J2dGJoqW&CfpUb>ssEm?k3Pms|8MP-C{Xq%#eeHR45R z+CjWU9fp7oV1gMCl|*f`aYMP4UCS2`eyO=iF~woFd_y`2kseS@dn4X4uh*&8NLQc) zU-AM`BVAb(0rt}Q+A<}vLam|I7U*1c68`LBu_2ohAqpbV0PIr|JC?C*(QeC@W29S{ z#E4DTWG^~=7}TZaOUD<@E>O51z6$5CP55x_dw>8Xa0@f!MTWv0;P40^|CdQqCk9vK zMGyuJX;dQC5blXV6ec~>9OgkvCe4$Xl9d@wy7h)MPb!dNAI{-v7i!>&=oHP$Pi98^Ncwecuzz= zpN*X+$7x|IX_%Q>6PM&OXy!PB{o_I0E?#fG#=$Y&WUyz}q4ssr>B(wQVh#ac&)`|B zTW_t+#ZG(iG_oS>%+S;NYNaK+s8WV8IU@=!K8n}a_WM2E1w$@Y!jMD3i(F<-Xq<6-m2_^;(^q?dop`>%X8jaZVA5mTs$S~%T>8BgSy?m3{a_6BIM4-Ww8ojjUeebB=i(X zfnd_^m8zC`sJ*3kd=Qf`kT>VzS7>`${4HnxkSRJQg41fZ5w5=Yqx|k&)guQsyVqeR zERqo4X~k=AzY0L~A3rglE=(rvnPhq?GN!`ogo_TK`1{oEE@GVfiGb0e{ukUoPBr zNBz=q$4V^ct+}Lp-qdaVhU7lc-ugFRs4p!hhnCYBwb`EpkM z^N;d7Zfy>qR#ai|Ulb=Kf6yZEPQe^RG+a)eOOS^@_FSD zWusex)98gPG;Jq#2avh;(S&Tb?t>kWSfM`G}nN(m#lN zN!f;wh(^$F$`{hoP8*%3?2bO6&Sq+Xnw4SfBokfhpGAK7z1+?n@yG9Or<7Q+M&dX<`89i$goL8g5F+p#bD<=`Mc+l3o1#RgJs7pu{Q6L0*hYgGR z4B|l-n4D{hco}J)0}{NMa1wRsr2#S~0ce)x0Rxu?h+;SwC|o8F%qP_=&2`})5NtjV z#lI+s14hNlKZb$E(O@V)*0Li=1CIb~!6!ispTz(uhIw3-7anDAR5WP7-wTZ%fJS1>7z=LfO4cA0HqEqdHKOG-19AqFM&uAUzIX1CzVj%UJWr z%AdW^nmN)bEScS*fg0EGhCC53^4EVsB>aMq@J(Wr8%}=<>U1)-S{${yl`ApK(~c<3 z#7-%QM7G{ykcyGpVS{dB{0Ki&T_nD7o~R`YLd=2$V&nIpy;qUnzx^No`%70oADcLR zY5a5G7s!$u+noevgR?9oWW59uBMzW1cYhxU2lP&Uhs;1)FOg*km6)+EzvIm2W}z(~ zc@w*JI|#$DrvX!mM)l1JqOlI-Tp|}Zo&NhG+=%YnyTDs&(&`b|Fk?tWWV$b$Qzn>~ zt#$|$S_9PVCeG*2L!pu^`ot6IEG4x(u|f~9pT)#^7nphpSeY!(AXo|`H+aSuaP2Ra zQ}=w_+xK^oy-)Z6e|vwh`tZ|}>3jEp_Hwu1mbr6R^1-{4kKPyk;lqokUsEptjuQ|t zZ0wL!s~m1Or(`v&a|e)^oY@V-_@L~M;dF~FD@g>{ej}prE_q5<7iEO$ag(ogH{v%N zmwX8Uxiow$b+aqw#~&%|xvM=TU%0wf%m5T?;%wp0J1Rf=0pMmib$L3zI2k@S865)8 zP0EW)Gj*$v)zFjT)0t!u@T|smF@@_u0NN%ZksXotcDu_ts_DOWZE?i*1=DtMXc_ zydDdYenvx=#=?`);*xx2$gFNL9$2W^m1w20kZOhBd>@QoDoU2>gFibO%8#Oe*~syW zs|OU%xiqr=@obE+C|jR14#?Mi;EdVWiRsA6(e;nD%&Dbc4PX96;jTNYKYmUn-|40? zAb&<+1VI*il~mM{nGdYQ+a1`0b8i&mzyxvGC3QY=b}hRypNcPMV{6$f+3F%=T=hn> zn$?ac%1i0WqSXyyQp93z!LRTx*OCbRARaTpxfU!~dhPr#{w;(WgxglHFmm2<3GgW9r z*K?E9Oz&Dw!g8`TJ8wC01!og09|wN&*$VWsI7Zvr-l7sif=qQDg_2#wDSA0uFtI!kX8;U30f^IRp|;#M`%{1q00$D{ zBQgwNut)cCG0YEmhX%9N{tmr33(iiz5E1r3F`O40<0{d{4d}E>7~!sTWg%6WBSh$X zSL)0B3jQ;g3}cHFC+P^S(>1pX@S|0^ME#C)T`u2FRON-vREw$WQ%-7tN&JXFq2nL; zM--U4FLeQHSMUc4RK0kKVw}gbR0u9Lov_ynTtYZ1?RGm;Y?iw1Z27?V3#+ok&@BUR z-oyq8W-@7#nrVwlU=r_xXIUUy^C8B5yXAAef%_jUvU;%o3vIPywNXCf^Cx5mgs9Yg@{MWstBsOU{H1ETfL2qOzcW|PF>SsJ#GLb|uZ}+N~I^Ar;k*rF!xCsH) zy$izYJZY80JbDe2Vf_J2ITRbR|17ksZbcFjNXq5(!Wk zL1|1-LWbtw>x_!fs_tob68g~ip z3uj*+_YclYLqr3_>lMxxkm!pM3YYZjL{c8@;9rCzY*-7}ZM<0KXk0twfGCPI2$gOG zz~dOGU>>AGJp+Bs>aMqY(VK0Xax;QCG^&Qnf%HE(Q@DF?>Hd3bxoa==h+=Ay;{Lsb zd-ips^Vs4*tU>5aCz>qFzVn1LcgAHpIz68b`?K@dJ*fg5gM0MkwaROa(nC4W`M<3> zgKluztU>%4iHb5pWRyQO5qn?$nU&u!+ZqK@GKf4Wv-?#om+lq zDRFKkb>WQftxIbM0fHwNU%$Be!SLFLqw9zKvfl?N`65lAX73y!Wv0dt7IxiUdFM51 zBl!VPFkjbX8L2RyXgIR!E?t=`xBLw0+#ad)WQ$AlP9NvXtu?Y&wH2&3154TLLV7fm zpSIgE{3KhGuem^UmLU#iN?Qz2bPkLdiZ_z58Ry}Xli@E`bBWb_B9NcJma+~1O#J*@ zd}Ja*+}B5DF_YKj#TN!`1P;;zc@*hkl!=mWRrW5C7gXtsJc)KH?Hb-+YslF2sDW_51hfSIM_IkGaMApEJTzyPswB_&_i1pskOs0!s}?u`L7 zJaZ#bCDnl~Ec31mGEv+>wP2B;Y~c4fXqZf#ki33|8X$B^osdL#H8q+<(S<%T(FH1^Di4Z|I(HEA376LgD3l;?=LeZ3=HpK)e zj!5T*zb_%U(p$Vl@}nUf3bQc+5#dvz1eRVlU0rowhhiX(Iv5~{kITyX`iNi0eX zNji7}8xKwi24Ga3hIf-)TNuVcnAS_bn2E~{B8&6?%#?!QWyLA50twYp8y zQym5j5Vg?|C9^f(z$FR$cDUFS;ON!^;q2SzT1En&Tw418NoojfI(f@~vH0%yDz)q0 zZQ4#;1xahKi99$XCy@;22`_{%yoO7_6#X#qRb*(#dgayD^rw}N|F)AFoD}Hx^2vJK z-GW5(w0l*FGw5sJB-D`4hLgI#+F}?%aa{FeE13E(J zAiQupYDHNLP(g%*Yt%|m!px$D3Csri)%!0h^845S=YKUaesXyH5Dhqtv|3Tp{8lw?kOnT>R`*?DT|;izI0-r-9V{fgfxT&G1kf z!ttr!mmYjcf-)d%H{)+^$l5jzT2B7%k9v2%UfBDC)w_S1xbKtRy+=An=C0c|NXZS_ zO28qnD?#7~M?OU+Gx~Za*N~UAyb^ zfOPN9;(x8#SsQ5nD-z8p-s0EPo3}@f=Xc*;eC&~CExBo4?7!N{l%IVnzjJ5n)W^6M z#qhet#QD)c|AqX;#5qm^J_w)$0`$R2`iaG3%4D+XL}V_0x#c8_&B$hZ?bkioM_wVF z^wVHIMQQv}6pJfzXSZ$>`J!LEHp}}O6$zj<_U|M!_F?h zJ>vfelZut5r^25NtsNwDPlb;v)SHQ(6s?CiFaLrRkIwycb@psw=g!7^Z%`q@D_WQw z@Ct}CdGn$Gw*#a|75$`g)r<+~i+P8GlkJXdP)A~jmuCQf!Qwnn413@bB{>j$W?oe` z(@tOTZ?rgBH9HRIJQkG`gJx1AYlT9-8JmqWoEir9T?t*Ya(W700Vh!*j0Ak%2{518szZ;->-vr`Qj*6a z$#Wc=Ab31&7TBql%gwb+Z2_}X08N)ws-!fI$%4QX%5c>M8Jx^k7wHAuQXB3^;HGAp z<`}L3RYYgTWH=;Z$NAl%7{c^tFB5;g3gt#!8n|vIcOk+P_Os^s4k_4zIzeXc8JMAU zJy4(e>clOm0Jsn-$?mu~EXtxb0WpR#924-W#;gR+rjN<;j6XZ#KmTU#M~@fpyQgr+ z?)=?*a(nO0@7|TaN`J{8*d$`4W(>fzD40g|i&#Vp1~e-_5JJ;u+!!Gy z0S+Mk0>sG~n3H~F9YJ~J28D8Cgct7_$PKYQn4U5Y&emZ65xcAWOSHh+=6+ylPe$tOtfR(i$@EL=;%H@!qMQ_ zD*>7VRihEC8ttedQ78PsA*2s&%p zP^T-yb+?#Oue?_L{H5C1!Odo0DNwsttlLG9{ncJ-vnMl=2w^Mz^~-2J(qoz+P~aLq z^EE=Wsi0qyk+B(WcMtRyCCpn_?k*(GY>#`41A%lHKbl3DtLaO67Xu-5M4Tb+8SNj( zQ_L_`g#XQNe_g@f0}tH2urNA4buOJ+!2yf)m0WE}o=0s>FL?>GBmlw>Cd5#rYF)Eu ztm1|+7ebzZKNXH>P<9C`1Y;9HTOF#ERKj6P}6u#pWuO41#ynO}}s}^3<8t$lV`0 zcfT0h`=sxl_v-f^=|22f8>di9{t`l2I-TSam192*TYwE?l47$=fw~p+ngKx!d176d zF~#am8Jw-R!;%t#MF+$5C0|>iPS6X#T%y9D*)siW?!)GPJZ-j<^|yYWzwNf#fj6C2 zmJwBZ@UN_xnhje0zj$vxep%cY>?uHW=#&J?QPf(t@ zSh)A@>d*d8L@e936&AA1rA)ADwjdI5oANG!N*j)Rvw`v=JI~yS2mjM0E)@imPuneAAnxLMkwjh>Idgn-c_ilgfxf(bFtGS>mQ$5`qjm? z1I57Q{B1j$M?TOc^H8p~EE7ux&by(|fQ%qHfY76_7tjTOzSRx(He~@a{BRY}i9!2P z7iZ&_monM4>D7ya)o2Y{yAhBEI1K+^F+jB*@vs_+n;mB64;- zd|k4H;EFV`lss>BVwu_^S&cYC2BIw)GqmFz$IYv(cnhL{Rjh&>ITbk>H1izUsysv+ zsP@Zgd--+GiU-Ef_&oR(57((CVh7!EHF#CN+vq2HDni8u2n4H{Aa94Hu&TxyZEu zbnqho>UrcDlf96xbq#*N1OQoxt8QYTeiQY)8GZ2Sm=dCJz1SRRb9N$964Ei<7fFhb`_s^ zBzN{hf9wKqjbeaZB#bbrlYY4=LHOU=vRJ9y@-L?^Q3g9fq(nVT!a#?!X7W#<7@b0f z1~K&SqMiX8aHYy6bPdqw7q&UTs;QatdR2=lVYl8OzNn8lqmmEY2N9$MZU@7m*@hK& zx@9;duS^fF%REVf0s6RRrtPk#hvZlO?q zjDaGT2o&al`$?ohRHPo|LEGiV0ih`Y*^xPN(2+c62xa(!J9koP1pshZ{)WWHv|}?S zk2BiQ+ed?+UR?VCzZ(mEHWoaJHtCwvPEW7Eh8{ghT`&u69CKZ$i5Jyb_@xj-4G{1*v5Q9-i1f1 z@sfP14nqoL<;yWx4pABdz_1A&*an3UpL*>-|Ih!IAisb9&;P4SmrelwAlvFAColjv zBFXLVH_!z7B9+X^b~dB#vRx=yo>M{bs|PMA_;auFiv@!1CL+fx4oSK0BZd&z$ySW< za1FF0A0XJa6&*yskU72sKd%g>?tZ7X_X*$KFD3SVWZ&^&{gvT3q8n(-rL8djIZDK{ zbe~HltO8@eqNv}J_nqa9uBKVL?A}gtXQ)r&MphJax3a`sRAoyx6(!W|W*g%diu?Cfe)$p}P7Uo&I$bNzq-+FPYL(HU;JF@-}W8bX*BH*v`_N%eda?^^{TC&WX z_@chyrZ)&5+c3K}tYr+G?&WFr&e)q44RanD{OEr z*&wu=N|k3ZCfWi?U^gTuojS&uK>+L7iRmbq@7!Gc@}xZH?K3by`I-+zMS!C!L`1a! zJ|Yfq$BmD3@l%=@_%*wm%7#qpiZ{$I{~&@}7r{VONIXK7WKd!sppA4+0;YF5r~*~M z7y@Acihch=NFJo3i|eVA9%=T1ZRANv;&$YQnlK@{*4s$qc>07w zC%Oo!GWs;rRNx+VyF{IB*ApBgXTH%2dNMz?mEdy~(j7Fq@Fn9*5;qz3up1Yi^ z%mEmzXai)VaaN{U%^IDSLr#*JA zV&Q#LZ$@jMAI#srGq-DJ?ty!2~s67 zpch6m$ONlHAjkn+B9nII8Da9~<7}#>e)nHr@&W@ed>s2%Uq;I}%MdUCj@R4OzW}e` ze&PT(Zn?uLMkz3csMA${Z==}hCKcBX5PElC3TZmBR2;2wlHOq|oNU-3YD0`LNe!-i zAX+asWUf)e7YP7CfnVL=!$?p0m+(ziI7T!bi!%BHi3_lVxdZ7{rU+T z`6dlW0)uhkFGNYrDUGIVyoGt-=GA(j(Y(QONhPY%XvSbbb%)#1Qxt>`3Ipc7Z))b3 zMt9xy*E;R@H@AFedgda?FB<7TGlet}m}xe@H-kt+X3@?KaSZVdTb0|de<22vkA7_( zE8)Ljao9$TGG%LUIdY(<1Jz=~?p<_;PSFdyQwSI5RnZzV;gfNcD%T|p37o`m2-_PE z9vu%IUC#~=jFY{DYimyLCms1vg&(iPROqq`Lltl6u@dEFM7p)wVgEtl#>6;ob2YPc(W7&!UN3b%|g?)85MU-&UvG+Ys&GN8SibxGrk2za7B@o?s^z3-{ig-+5bed93u<_c(U1 z0{$FFrV5f}c|?U{Twee9?DAWSi8I06D8@AGKQtMcyb_W)0{9yZ$VMmG+PoyBZl>jg zo3j1_&*g8u zwf^=mx=l$i)X>L&TU~$%)79oW3Cv8N00Bpa{2!iKew!X$T04k9hW&@fLZ^<-zBKGV zn651O15>&0-B-B(-ieiuXJY5)(_^Q7Z=UwOF|>Bz_`)wvE&U3_tXju{NolwNj!i?P zYJ3|ae8T{Sf=$HCcWlb7fG<~E$*ke$j5q-|n$&Ga_R9sA@Nc~pqCDs`RhG}4O-9g> zW*6eZ>CwQ6vEa$=bAB!XR%pl|MTV#S=M;s;3O=T0jX#6H($#s_O!GAf`drll{JPJdhhB zdAko}x9U7iM57)U4&}$lrsQ@0Wn4~{#bUc1`93u!P2Pf~l-ZaU`4Gs+g&Zde{(Oxz zd^wVzpk4J?ng$|7jlRqS@d@soGapB$avG%ofsFi(NQsQmf^1Y9$XzKn*GtWSjA#wH zGBk8-I(lj?b6F!k`CIi4H61|J4ffq|2^C-)U9zz0n;ufCnf592~xLadD{Yg-H#dt9Hpj<56YDd9djG`I#5H0aI z`p%6oBcZ7)PktA-zS5@Tq5(b9UduEb=$YZ|a|Mh?Ue^BuE@*B@hOrHn*)oXnS4*wgT zd0ax@cCRTLPdTjhn*y_C>aA74i*9a9s7~IMdT1 zS|M6WH@9qql3&BT00jE~KZb+}Gi-94MCHP#@|0))zQSF1R9^VewE`xu@LOvJS7lw) z=fLy%_=RA8DIhD{k6jLYd|`cI$baNY@aTyD@W}c{V}Vbw81w9Mid0G;h)`$(VL^n> z(ZI*&SKd9h{5D=uZ1}K-T5GBF>faUayrX#WEEeN(2wAm2;pxW;cki`lWksN|dzp1_ zIJr`*l&M$OiY3|Aqfqk|YV#RuHP}EB_9>?kIvZ&)qf7Lg*grROF`wJR7grA~#xG5TQQ^^{*k_Ua%vx$; z%>VJqyU*tCygm4f9{`EO_m$B8-Nsc$#MP9{9TxrwRDv zUpU9#7``l~eDj&cQc^Z9#wYO>R0)%qezhfAeIj;qfq)pPGu? zV2$l|k~GtiHx`Muv_j3aUbR;<^_gf{zUE1$$E9TuY2XgNkf}6J|OZcH(u#U^vtl8F;hH9-qwz{MM8oSEW7G){S^;0$O zu}i3)GzQE4rn;FVt2@HOyCtX=U z?^8xfkQx#PNPzf`^xz811pBJ}Kp;gmV=j@vuul~QC>#?d*3&^(-4JzBA(GT$1c8PV z=3Wd>lL05q6Hl=y%wWKtT|%444Ns(X^sd0sM2Ub|xhMtzrqsSe^4{?l9A^|nF|3yZ zH@g!#o3`wc&b?rI_vK>r$N@kQ+2WXS^Lc1RrE8gqPAgt|_j{cT1G6-FK_A3($!$v& zhsLRd-=_JRA}A9xz+zE~whnMX9Vm|DtFol8M84SAD5h%lwL+70(CdNb3#C&(4+kbK zN8o;2cDt0=XkxeoE7alk_lATEGc=-1qBMggGXUdXVyWZERE;1%Ls}SAfiy~W`R@4* zRRGBr5N7h8+K3_Cg+|Q3viXQ4N6+Ra^zq53A5!G^&2N5VZ1VK%?4`i^j9!H+2sRJ` z2mFGJy-uXg0&LyBtP}Ro2%`m8n@Y%VAnkfd0#`3XXeEfD?v=EBJVQ1pzABDPRHSum zOba6@uDbU^)Qp-64L^poo*PA**su-)y~JH4);!WM%H>~r;e}9$PB5z{t*avW6Tbbw$lmu!@1Bp_e|ze>m$h$5U{i(!_=0hN z3G%c~@4(GqzM5Sz2eL&r<7Z-y_g)ywRu}u;x8=E38$6ejCkZ|I-nSd>$h-^@VHge4 zH6*Ovr0-wjGI>S+|3{LV@=|enG;<;S(lhy6Zpq(vTm99S+yb;h8OKgC;7(QNCd_W1 zGs(nEsNG#A&vG4EXo%A-2%14KB>0znLDgE~$!TfitU;r!sjL}@lw znqcrW89tJF=8?jlJ8P4dHashNY1*Hi3Jf2FvEqIE+aY-t&Ux_`@+-(FbMi! zn)U36`!bQ2&?5~I{s_mFWx^NEVh$At*`FZA5mPtH(Q3*4;rs*&#U4;PZewDENC0s~i}C>#atyry zHKH#;wC1CB-pB$L!KKM(aI0rHz|UnMYo=g<)P#5%BKL!OxtAbIo#a2nNQzpDPtjbj zmu3ioshE@U=$2|b9T|#XcvOW6>s{q6j=b`#!`@`>TJ4(K5oRWvg|C=M&a z1`ww9j*_$jxTieFAiSF0pDNbDYDvC=gP$J5qF@-)LI@B@of_a=<>@8Plb;Z&PR@~{ z%xtmTXgjk1r51yEij^B{8c!e+NkLYi%I=kJZNl@`8}3TvS{w~|x@RDGMpkq2Q<&MJ z`L4#mBoL~h2~$koj`BV-g2T1!Fpz~5?w*8m{6+6YIQ+Z0DWOACGK3}L3o18o0P5pF zRq4nl_J_fXIAGI?f-^ADRAp{9ex}^YG{+A%CJ%MmDdJMgj=>LhsL5g?LRI}Gst7P% zoK}GYjF3akk`D^I97^Qh0$$*}X1h$%?evOWg97z@dEs2i2M&QX{7ZVKF9Q~PLjt2WWcQ_r4!|I+ zw{C^KERody&42&jD){@wt3TG&e&zCYTeM&ddVo5jg==^nN|a}GCpe6OK_=FCy^BdC zWE7;gD>d3>Ds)w>1e1CO-q2$pcNsuQh(kU&1z3E4Us85g_OFIq8cEiNz$a&J+BRS+<(5V7@ulUfxvNr=WbPt2Wp_^p*) zKacNzE5Glh#NH=mZ@>Kqto^*F`&wOF;OY{imU^r5M3qUJ&rPVHX7=-kIbkZWj zLRcNRk!mA_NwOrp#yhr9pv+z?pIjm$X<v!eda<**3V}v*%$F05 zm8?j?3RIk6tCMhg$&uo4((+S#`JwL$%zE^pfye)tzHP~4uWmOr5xF>#uw_5z$m;O= zk&}zBkFFmX3m*Mq>AlPA*FMn=liG)9fy6A6XIe=z9klK1_B8Kw;_D;tX7=7uc=*9` zK9Z@H@^vI4moUC$WvS3uw?h;3WG0-{fNU8*-jDbP~BzL04Y z>hg&snkLA)ZS^)7DT>3id#Q!$RwE45gC;Te)#`RT`- z>*KZ+C0B7C>m;`cR5#Lw+>w2;vmCP~YqmVDg^2re@#CqgZ$3`0m1o?(Pkx%e^%mbx zAD#*xnmi-EuzJ9tlT*RWQXsvE+^~B$TVOZ13OpCBc{8OtQ)`7Ih1vOZ z4n-`a*5=}p!}7Id8pS{L{R|kcwL%0h0#l;A0%9 zG^QR41K=13ch=41Cj0ZpoR)Ir; zs2Ki&khZ&uk}j*_K-o}2P~1|rmwl=8D2_{WvPHr&Ab>8@5zfE>nsU1R^&dE!-V0Q9 zBU;t&e{nc>vd6HY00JblT}`9V{zlNT@_)ub{jHa!MALNTq0b;L^>As&p=D zE_S+MMTn{}Nmv{Ud=mN5!91kntPE zsD!q#L(SO`cut?pE+x*n^J?@RA)o@S0S(Gn?)oIH!l4T)Rk{q0fdP_YzknGf!Whi~ z6fhnjNU*qG&V|b#KH;RN+ND6PB5%uSD-cz!Cq`D1eb6aW9kKvUb{iSk?w)_qk*dji z9{gu_1O@gsion5kE!4dH;Z<8AfYYI>KC0+$^mFaah**JH!UHyDo*}Gfs|&4Gl;q-= z74Wt#OEoZQ1WRyZFaW&94u7MKDG>=Vw(WCr?#vnV?z^ul^7|kD?Y~jvx3V(fWt(HN ze@uq2=TH^~ptu==ZFr*$@-abPBK+1mggybaaZE6}`CyXF%-NkH3WYa9gsX0vppVqh z-r8!8{?fEA48Xy;1lwAt3;w+Nq5!|uW?*1IGM_kuceurFNaPyzeI>+8%7AUcpnUw$ zEROV+=U+??e!_+6aw}T0(2>|720sxx_KTBO?)uwR`I5&IzW(nsYy01=?*F*G|Kr}X zXId&i33u_+UT1W}h)Y~$prx$?lQuT{uWoQgPr~61CsUNxvm@A;3Yqfq+OHW!K*|FN z&f9S%WDdwCAb%}co+&n#kt~j?KER!duDn3!X2gxrhVM#Y8@-$Z((31!gg<*_HW>$YOeYdoLT5lQBkLaxuOGV@Seo=aPsGGY z$+PiO^5Uxbc6A?$4a@=9$=1n_ijO{6xMR09dI}&ME;j?ECJw9x=vt=g%avwYL!TG+ z?J4ZJt9ADCu5JM+ABaophd^B7-%Kq&lWHZa73CRHD}=H&C);RVmB;gWtD6iIC&sgv zrxTa`IeAt{TTU+#t}mr(%Z18P?t@qJcivIBXJ7rZ56anD(7M21BV>l2NSiNZUFD?xKG;{Zz**$kmocQtZ`lnZdUtC^4enDOqmX(6D zu`_|pTqL^|%ubt$837r%90MI}f=CVX#Arrrk>c`dF1nh_OeL+EbSPGu$3?*+fGriW z(}|O%fF0|($@%zDtib5`vS1gp0LYXPKtpFqPN)f#1O6aJ5KUb5$(MgT;f$CO8(I6uCZsmOE}v75pi=&yGchkGFkP(#HmU4WnUtMVGJZ!_yG=L24H9{HWfKe=F3)>;FbgNn(E>}xJSR(AyQ%} zWjhk<5E?|afN5-ugHBJjF(Mse>I_$q-c(fHA(Pq7kZgjjS!!czj=+t95Wdg2OF1Xb zD9@b4;3-CbQs4*Z$1o?05qhWi)=2c#aH7vZ?=x`ah-rINv`Wa4JK((05u z?ObE(h~>Ws9CW%eF?02*ObY6+mz3xJvH6sR=3uDWT!-_96_!=+?NrxnY?SV@W_`K}#BwtU_+rK)Y2z0GHQ2Fov?*CW8-w%H9h=RXDzQ4+gKnK3Ta)?N( zK7P@HJL+3X^*`C5p$~&}FS$fgUP%v`8R%2FMyhI8s#gEaT%3y-qB7xjluO_ujO$f= zic1YgR)J$7$R8ue$0>l!S$s1C_vkMGeAodb$S2IJ( z42`;#V4uZCE?lTUp?t-cu8xIr%bA)#TN(?keKa%ny?0jkJiWU2NqMn%|1WdU_SrCQxYM>b*Z*C4c!YkhhE@K^uUE7Y%0(s5Geoe!D#A#qwxJeZ%Fj?RvU zWtBI)5^F|7W9L_oo?U+Ta^MK;PDalJ3-ZX19yaU;oiI3 z^OrU@^36`EY?YgxO53ykv|$Cxt(7h~4{Unp9mRcnn;*SPWNEi$wG)-&kib3;0I6+x ztdLpFm*&!z-PXODb)sILJ6oMfzFF(HzL{Pv&dlW}Qq46CUBP(P30%mZAI@JKDGnv_ z6Zz54@_X;f-@dc(%;QdER)Y>iTL?$Bz+D{BggnUauPjN&3S;^5Lgvz&={N3=9DaOp z`1RH0PeSM3%ox*OrrJS_q3w zR^=UGe5~4x%%<(RbZIs=ITMo|j|c?17OG{(6d>A8JS?sw(}F=3DI;;mI9$60k^JWW=S!x$Uz!)P`f@fuKqLrCsVomBcS1ApBte1R(qn z#t68OKXZ8|cAE0QIJ983Wg5>s8XjX%PRch{K@9Z~SzymQ{X>i>HP%QQ#20i8KSZ=z zOWxkF+BtuAj4p@r6XC*QsOS%s=Fluae>LNqjmcao9h{Ai6dQ?BlN2knR+t}7x;@r^ z38A}bGo3kb{x=f6BZ_s23|Gz+_uN%^{%^a@{>X|~?rj4;oY>b3-ogI3Py+l?()Ce4v;e+~qA_6zrYw!`Rm*@+P z)@=!=+^b((*ASsZq=pj++a9SjcvCd~F9ybjRjW)bRG@yZvkw0vi}z0&5UJRKe^ zRu5QHA31?*?-7f)iplji#;Y~9HZ~WRl&?M6G8mI~IpeiS<(c$MF&8_2MZz91fR1?% z2%S6oi6Xy$@h|?5Gc!X9{=l7jmDVvHh6KbScRh^Pe;FxhNr>p`jRp)(h)cw9EEeB)KWsCD06J4V=2DimVsMnL%R&*HyO>3`F0jVFTO|~U* zz?Ifd)BSJza&$w}{|6B@XiRab8=fmZaBu062c4{})x*a)Y1{EwaWYyYAuWq1IMF~} zzI`+uJw5FIcrrXP9zJt%?ZDZU_b&O5jRlWRL{7}bFOl=)eGW5QcD=9WH_E~0k@pI~ zzB})zz4Y8huK$f>9919qxDRXmxvqwGPe>0ugmLk~WQ&k&pF0w<00%d3KJd5FHOXGe6aIh7dZSGU6R z30Y2usqinFa@yjGxJTUzk&Q?jM7^pN3Kf<@1^J>ewnxpxf>>#a(FmXiEo3U!P0YX# zV-Grlcy*M*fR!$oDV#-6nzt~7B=I+Z9VwHVfg^Q03`b@SUG$8x|BG6DdT^qP-J5diPieLDLRIT(^a{p!?!mq5PGM+oUF{<48YNsaA92Fh3*V`qt_U3MyME@msSi{5aX&Mj0Nx20H;Fy3XxCNvlb~M2G& zgKL8Z$k_Y{@`M?;QxGD;3((QPLsb{|C}G12{Ik{k?D{E)1$d%IjkAQlSq3c8pLL!CBo6bTo+cz8JihRWa{$wQJjDvPr4 z$qWyW2?5GGn}zLRZ_AFNCLHS`@%X@E{7%9InBo?JDDp-soP!w!b7I(IYypCGAe}rHl2Q z2TFH;WZ!$Fv*%!A$9sia-xs>;P-EAD^3Jz&d!F>|ePU_lc z!z2pVYJqfRhDfJaN~oJ$Ne#_JFO39FUR*t(6MpAcIOzA8GZ)uBn2sESV~OKi0@~Qf zbwe|yCmt#8xs$YEkDt{>Z${juJoMY`r0vLTnS8VB_VUkvT+gj)wb}(ez|;!O;#ATO zm&%TA)NF(cjA*rs&25`2dWm}#!=dk7qZBPyw0`Q*1@7ecFNi*G;J$;-}66fQS|>8d<(?PXR=Pd=L6cSnBexGT)n^boOtP>a{K zY=4}I$>5Tel)Mu<9{yrJ zF=Te(7C;GNBVbjV>+|umfF9f%7h(uV8YW<2-;8O91%z(`ALvaZK9FM8?0G>1#}+vQ zd)!4nrXGL}g}ICDt{R8PXAED!l;ktUmpDHS(FMkQT;&&tNz%e3kTX2DJFuOr+o@`c zs4A0Wszitumy^RpF;cjGm8;TB)vc`6P8DiVA}{j6Prxn)a!Ig*PnQ!V!YlqvwFGxU z6_Ozd0R;$Tu}|-ZDcFWd?iEk*C=snu zCx%2-RH&UIH8R-42Z5y6-qf|X$F31g;C)&Zzp!0uth$~B;d)rLo9bMuw60qSOFc+K zFPYpUx8MkB(r$&+h78SvOF6?;%TC}dYVdTnV!nlngX8Sw^$EZq{)pSsgl-y)nMLy> zrRsRC*55h=ZEkuP-cH``Z2#A#tL=odcD6C{jy3x!fX|9f@Ne_-yUo!LHmdH7LmE~Q zsY(oSVT8sdmyO=%5~VrKz6gy07&gWbkzk^%D$U65%{S1+%?OPnH=LSZms_9j@_+eX z{xgu@fAL@ZuTG!-M8Tic5;f7fYXe>qsC1)OrU*m`-#vq)aZ(khB#F3Jv^(;It=lWD zX7Du^ix0*M&Sa}g-cS#rH5|lhM>jSE4@s;uagXtv7Qm$G9jdvRb|49orfX=yHr|B5 zZ-$)c5usjh3>7Mme%=A(-Tpy&|A*GzSJQXA7`o$y;I5xWpxrM;?sy@z=jj!YpYG@4 z!oEk2b(T^UEZMDgHg+yo4`Oes3;0on8+Ig|mzj}vx7g~Gtxn1AmaBHf?v`4ek}+v{ z0JvQ*-ChbS!a_)wYTm?HuT-%#Y^-jFtxkWvAgZBjgau6*h5;GAn(4;4W=78cCkB6T z-|Hl=wj*6LeZrZmPO`9nPw~-*T3LB>hXR#!;2P{xY}CsNyj%TXEO>M*bad-!;I(&G zC&HheUwtQ5oFIoOshGO;X#LG!~St$OH9Z4sg{mrU#Oz>7f@5n?CwN^^2D&rgg%SWC&whj&C%7%PrNPJm0HF zv^yllu&d_rn$FY~5!43bCmTO0bUK-KJ6*T)RcD!A zAT+9_a-tQ?qcw7dLjkMU?qqByU2jREB@h6b6}ZqNa*}s1dnL+{BasqBB!UwreAP^GwasSN>tb|yS~8&X&5JmRx`t5 zawe1@Te~e0EmM`9?c5u;6F1V?aMtI2GZAuUo95(WXoKMFW~9#x+<&>&>R9csdR?au50qNq)Rl7FEG>rjUo20KJ5nqCP+m@Rcucuw5qMZ zviUsmKuM}~pVdMHWy%P=?v&6M_6%r4Wq1T^bP2n%$&uh2tasjQGpP=u#MQ0uy{1TD z^2Ytv)FTN7H*p(M!d5}UJ$Vf%X0m1;hhofz?~o6?HjKe6CCvq898f2AeM=G2loU$qL=D<79We1d-&NrduY<`g*ts@nxCGgo-)fo@e6JL7n6A8YO`>(W32xL!FpPKkSN1D0-;Okc zo@BPV2r7bYOp{7npP`b?4f)_EC_!TlH6sB5cH-)?;&^>)-h~^<7UjkoxgVrUD(dt~ z`FfJzm9H`ZWp0)-qLB;^C)j*IXnCgrv48YsGXLmir(q%XY z0%B(H4{B-J{a5WcLwrYWt@EGdZ@smA^gTcccMWuqf4R|n2Ar)2z%_4SERYuU)2R8{ zGTD~{_bSA{hU67*+Tvc73BPn1%;%O&l&0|l`h_mGBS_4Zehr*teARL!B+@nYQ+03| z+HGV6^;YEDbR;=du1i`BeQ__~iSarjCDyBmyj&^awup2-aTc^kvc!q7VH82~!`(RP zmQLp|dwty4dYB3>GmBzOmBuB32Mim|*4G2+`YmsCj)ZQ8!BO<$m)8tFKz(AT`umUQea&6*v7}_3E++{+&YyS_1M4qSN~GM-}~>q zrr@t$>wjxtd%uXW=n<6>WH1s2axGgx72+E3I4}fJ3p1OEog(__?Fbfe0c#k#U?*2X z$IW*>PYfgudKxZ_<4siSJ+DNpxS=SBc*-!U7uuR0<0JtM5fMqe+N3W;xq(Wy({k!U z-Ol`c*uL*b7bLgmaO?KhQhR=|vgfJg-9HKMcsF+0H#ySH>76b^Cz-Y! z*&35$EQH`Afz-T7Ee2*@Z$JWeTks+WjHcYL_HmbY6m$ddhfK9U1H^fJ?}nEY%|P{b zpkVv;*e$tH3X~pssQB;$t#%*$QPsvZxFccC9S2NA&P_%}FRZ?QdHvJbIN(pLVKRJv zB{kHr65Xy$FZWxF&DVbRcg1_|?yOJINf{H|$gGv5yjjVv|5D8AMvBg=)rq#8P^G=z zD+jATeZH{g&ep|an`R$7<)2&XmVm!#d2o5kmk@AXAN-r+YlCBYYQ`>o?AyHfd12S> zm6xC2*!o7K&iN_wgQ~Se?d&gFbDuh$e5;*nIYJz7noXyaHj4hzqYo7yyswayO}2>6 zco9LFp_10A#3eiy$6idHUrJtDN`Xt{lL=S@uz(PcC&MR=(q+ad1a1alAVMFhF>-BK zvz-We@zOM%YT6NM1JkGvub7X8R9ox%9E2e+4Pk$TKcqoA5q?a#gyD2$AySx(6lBg) zmsR1_(c+{mnC%LOBsr~iHa?WA1rdTgAMeR-d?d)K#V}eH8guV@ZYJO8Pc0))yB+su zr`B^zvkCInlrK3m9hVn)Nnr8Ps%5^{1lR?VdLMZZ+9*IqVfaYlmDI)g#2MPc&2TEj zg?uVaKgwc2PYj|J5F|Ge99wNka&(i<(gk-l5(ImQ3#TPOa20jvdCq`-5Qync5xt^)L1AlZ^I!9?p;X_DWHcI;+H~sMAZLK9<{*|?7>x`5eekRVX~oUxSK9F z{OFX_h;r8qj?_xLgz)Jg>I0^@JDwemA!#u(SQbYKZmQ;c< z`hq8t;JxQTC+e8qlX5*%XRrsBbT_I{CDWFF}p9{-0i6B^zc`l|ij@L0QK?pfh8YmjU%dsZLp55b67ip2UsyXZye{AUSHk25TG3w!%fxah zgXv-bSPqUX61bZ8?lmz$aBl88c6xdGzEA3V4_kMA*w}a2+WB_w&L6FT{C55#0qnc~ zljtL#1(hB>7JBC0mA`xR>hmG8t?1~2*KK2gJ(!nH6H~C;AO3G$^2k_HIh(+&@uS14nML0CWUs$8UeH`O}wZhqJ8 z_2HB5EnE^$Hv2^}9wNA4USk2-+wXGV$fdP|S3*bC8OFnBuLM84y#7%+Fw(kmu6gXE z`hj0no_)G_-~RlayK5i4*|QTHH$kN?$yGtu;Ro)V6|4NSj(2iKQ5j7RjrH6_Qh`09Yi{FXd~9Z;SQw#_7{3Wu}=Vn8E|CkQ>5+H!L0OTZr?4{iys zR7)r)W4U1hA6rbGOO$2-Qv8eaYeolig!2gPPbTYh^?x`s#cCVDMNgjik!;TWj+sNmaWHteXHpiqEfsZ^d%Q3 z!ZLY7*SITEiE+Ct9}obSlqi5eU`8MH!ZTQq!Wb=%&A)VwE|7BYH25UL!5%%Dik=|3 zB4IpjF>%&pz5)0mLD22HQXo5qqtbD*Y2B9BjS*?KcI}y<(nDp3eWPXUy(UyXs%`j5ZzY!$5c&ST8kdcyTkngE~4u&N!?r~F8!9|vyqaR>~a z@GLc%pRh$<+EOT5p=~;WF?*3uuin63q{X zvgc_I0Rr_@%Z3;+_P1NAv<9bLzar&p3yew9)oa_c*y^ zS-$Rr!VtzxMi8iDR-bR3mpPhlFI#OEEyp~T+$>t1{(C}7l&@Ps;sXpLYMhRfV(@0q zCIxEzOEDrR1pt>wlD04^P<5+K9?UkJJSn5$X?;Z|U*JI<|=B>eXDULn;MuWMmzT>FrAD z;)%uAF08(XHH`R){zs>LAJ0u547~ZH^xb#nZ@o3YP%D9mWVc`q(#A z2$1IGj6u3zE}~GWm9E!yc2_A~3V=lfX(1C^c!n7&vCe%aE8GvfZdti}XeEE~Wa($m zmwxzE>FLKSFTYrL^TAeRj(R9h@}@iob{lKJZsZ;EPA@C#y2=5W{JVQ!cTKFvC5koe z9KaF#066Aq%jwEo!;TOs@Ek_rcp%PCoq#{7yeHp*AbJMPoF9Q6`%6{B;{&tt!K3I% z-^(G4f{E9%gAm~>5?GM5x@dMw(I%Nt6&rcmk#{B%o;{H9ic~dfIVsyoH!Qq&ZXwZshKK}k zNU9~p@mtc}KfC1B4G)O*xABLBD)r>&o!<}xJ#xV)OdW?vCW~Z2-d0r1ucwp_C zOQP18>{3B_M*LKWG@^yslGUHy;0zIlOJ?oS5altLN^@OztJxlD`4_`mPF=t_5gJXv zZK6Dbsc4Ht{KZ7yI0wiJzvN#cRZpBbIEww|DU!$fwJRD^ZUR$YI!8N`y5$1nz5wr8EJgv zmMyzm$J#7=EFF#9R&}ddmZk1?cWuPJ1KhV_vA7oZB8x2UJ3){jK!R9^9moWb3FN+K zzL#&`-;1~JYbIEl`F;0$83?>gfUN2=&v(GccsK6-?zjHG8xc3I*$jlfXo*|l1!#wH z8I*bP)1db={gr@^MFr9WR1WmNv~=ypE1e6zZPMn0S$c{ZH*CgHQ#d!vonT?*B3?J9zde!Xwf}*iBweTK7 zIJ9I$CmX6P{w>sccP;)(Vp8Cw?h4#m5a+dbo>AoYyTAM2De{}0y=;$;d-~H?WL-8p zN>zg#YAq{WcG0au2W^HJ(G+O{#O5?12s74@LPEp_oQBuzWD|u2eKu5aMrSF5h|mJn zORn7gT83KJ(o)Kk93YRJoPDd`_0iF(m(R?p8D96gYapbL^onA|SkV@1-`p9_wz`{KFZ!+xtRr%ij2>6Kh;6MmzIK^x=C_n>VJn zY*|WQs~m7fq(K~TvZ@51f)?6D?|i*wUhgpP#Ms7w0G$z-(goG5tkoS3XJsoyT$q^> zFsbwPDhMZCOkS?ZbC%tGj4t#&7NwUx*{_9JWC*5b$o*(7s0(^(d#2{&YVdbqlrT8N)JJ@ zOJ4gJn%_V7(X+va??|n?#oD$dasT~+m!I|SJ>dQL)5K@*`w#tW;neHCNMETTw`^nu z(Uj5lta?b^MKX(R3jWNeIs3C^xnW_ym7~EV+aYbF#^W`AHdU^6 zfhMFSseNG&EiGjd#WMO{`7>qKUF0f|A6g+U>*dQ!iToo!%-p`G8kx;L`EYv6=G4~B z={s)C+-Vqw)w$3e!WcV4;L z=-$-tbTZ{eM(;l3ezjJn(vX+r%QZh4$eS7@?&$Lq$Pg>UcIDTG9|t3laRz7zEG}04 zBjIZ|ye_!+pP75_qWhy$vu{(bMdhLUapG4`fcToEx1JG*Ss{}%=EM0BQ=6Wn%Axus zV^PimR^U_a-$hR6%JRI0NN+hKk43huQY|qXy|#jdD-vtSbAdF`4FrroOvH0jQCZ28 zyTklMSLw1ZRSFhsD8;JOt#~0a5KmpS5uiTo5b*mnKQFDt{U~Ckg{Y`4^aF zUk=f^^1#16qhIlS7QJg%eCL+&%kTA|2PX;J27~hNn$74LHIe?+CP_jth9i?QIb+rs z22i59iSZ7>NlXEQM^p6g?2Um?u6DJWXiS<+aA z?6n+ll0tSTp-O&YMl?o-OoxAE3EXUVrRdp7Yq})Fc@?QfCrkz95*BnF&e`nuzt!E? z`Odp`UKu$vF>zrrD6i-#lK=u_LUh6!LEH30Xu{dWc^yg3V44%yMp{0qBoC3Ra=D5# z3ViVwys6p&Vvg%sVg8b3>@KC`d1-vQqPZtj$r_oJfHTvKOS&= zm|o`MKOD#mqggdkgogcqM=6!f<1}mdKJp*-4<4H62g4~H8a{L4z{e-|?LBhl=*OcM zw|$fX`E7V7wdHB=_6KJL^F8a^^g>|6Ytj2Y_u4zQtVzR*hoYapk>0sI|C1+{oAT5+ z6Tu7caY|VQraCVr{-lAd-E`!my^WRxYMnmPVD32bjRFg9RjT{QgJT3b-(j+qvu6mG zEH!c~Bg*3<@;+tN!+|;=DnKK;$(r5mWLWm-;VP&L{s6T=O22Gn{CS8@>;xd+OcU@I zZm+x-)|?x#Zux%c{nwY8IE>(5Kq09GC`KL3pPBO9rNvLE0LIS08M*(~)P{AbjT^kL zKRz+?;oRKObJOpg_Y9nNO^${xpPqf|qG!K6Ap}M-R;z?qb*vu3>$Cx)=TD@WtMrPp zOPyq8|6A5Aw^WXQqGym%qh(DbYHlmKm>RD&uDz#>tJraKHFY|uM-J$LFrk;gA*9Gp zu3;s_16=f%GtXk;*c7oby;RBl^?GXEswJo}ynVFl-C2H={-Kh>1Ct-A2&0 z_RlOdeA{%RG&3AH24Et;)*3+sqE{hacqUuuRm=tE5snC|Bl{oGzTOCv4}b-rid1Qa z1HiF!)|9sN*29L9HuJvpBWv9)i*G+U8NA_gi1QVh)dcf!h$7&DKh3&})Q4yjwW<)P zAFv8_Uj9XW5aQLxo>mjQ-B?yfaT$qtx|p{_l^?TYE%3VCq%i~jr4v0#+`}aBFBq^1 z6QwtV%um$oIr&Vp@Z&UW?19WjreRXql^dD}pRO3)4uJT3-fV(1AD3;Olz;v-F!Ypy zQ9)XZGQrW5rP8sh?9>#}{H+DS|wv#GTN z7T`Ene4m|~`;gq<@7gyXJ0Hu9#?3pVR? zky67a&lwv(r5Tg$Q4?&?11@h*=g&#`Dy7uXVgF&m5#x&AwGmPGR|cZeb25PM+ai_7 zzmhw+kTb~hMo$XfgfLz05F!Bfta80|@VQ_6i@yf)`!E0I|6|{g*AJiDd%SU@@!EmGoQ}0P*y+nhCO+dHj&Q5LE zo74UIp!IJhwm#+A{-arN-nNJ5wm$7$|4wq7+E!rtx}Tl zFDSXEeb$f=esx}JFn(5V6WEKf5IyMV z_8AE4m(`s>-{|a_^iz*!c5G``LUwdey1JaI4;;_jc^h~%y=Q0j^k+zKxnbVx?rsSo z+nUtD*^PME;}Xt){G(zuRj3N|WC*-V)|0B;N1kiVOsedO=ciNU%hAGcxhCs;?o?m3 z8NiLHxv@x2V#H{(*-GSVF%2$2z0-5=U`FTW-={;wP8>)6L=DmmcyT_~-K|Pdk!@`^ zCki+!Ip8=>J{pv_%rI75J&~VEm*-NY>9Tq2qTUMots&e@?>EH?1pO%XL(nJLSk+M* z;;bh4Aw?01s1wi^a$`iif_zqQn3ZW`JcSBQWib#PQeQTkvJ{E{F-uUR-J3gkiB8DA zI?Z@q765R_uvz(o4X*)tf%FxkEkKQI?M)2?uis>DEO;VYS!7;7rK!l-F}Z7S3WNs; z*0e{wXtu?P=o!k$!|WH}jsA&x-sGewHAAq*4k4YC8Ux&x+W|~MHnM4?wK{A&C~%nxV|Wyr= zPlcKX;d2Q%@5Ia-RQvi-a-TJ*VFyZ><{6HWxzG zA;2Hqf<6m1uRnDi>QV}(1*Ry6zY;1|-HXX{*b=f*X}3GqJ%Nps%mTc8vk~{{jrsBv zhoP181Q`^Bta>=V34t%|4v{}r?fmtRzx(fW+3%0P^Y1=8^B#0+g7f~y=L_i=!^AmcsFIid^;7jC8l!8rt@xu65 zp}NQ%wT(10E1>*@lu$7-S;w;3Sd&1ODyW|GWDWcH(~0vt_sjiUz~B14+4b*P>)(uT zePR)i$G=;i@osyhdxuwU^8RRc^H2N=`?l;$a4o3F?rJqTBSY$)pIRF?x;35cO^*R4y)tK6@>`V{`1zZL{zH_~h)H;JlMFZ=ITb`^?0Ni`jm6d@6P5)6BN5 z)&8UO$+hsTC4yen2~SrJzMp;IUU}Ye=k~%|ue77`35{igu$yKl!g9@ORb$21e`>8? zR~tR|rP)&kQs=ZeLGq1Oy4pzPtFknOJrR)+BL^fHgc-?>6HiSAlPuK<6O){ui=Q9% ze|~KG)pHAbFStJ<$CEF|g0iAOn5#9zga$g{PY%c~#B1V3&r;mT^{-n(G$3JQ&9}4o zQ`3p^2?5SXS2W<5e1KmOEN~kVNv7-%Wv1W?wz(=^9`dBR4@EJB)sd766^DVysdU1` zaXg|AX@gOacA@IC${=q6h$J3-EGVD)9Y#kqbJo^mFXl^E2FJ*qERM-iar2P_>RsRk z2SiC)l3AG@@+3eITwqLj^Q1=8C11AcueM_G!a}(bNtHasYOGwBkIOM%(n+Bjh8e3k zM`XmM@!@o79`R0u&(e4yHLed5KyC9OG8*T~Zj1+>G0S>8nw%`ygkQ$Mv z`T|@5t$-_%vX|*MO8o+q-O(D(u`;DN&fh4ef;-Tz)PtH}vU2 z&rmvI8@9irU$LBcKX9SbF?&}TG+8ze<71p$$VvL74xb619t+CuA*rIQA<+OxK@o`e zQ2~ZCV{}EIi^(x+v%-;Q%ae!6sg$fms>DX9T9@YzZ!i0Hyz0FBP1CS6BFyMXyITLfV<*|Ve{>K0P zuY>%4?Jxe?i*G-n;P2vsyhe$~F$yUX?K2Q(kg&#WY?Y7*8&0K@0zikHG0!(2!zwt* zpsx4@jGriKw{#LytF)rX1Wep$$yUQ80vNV?MhnhSl;{?gZWI%+d6=Pelt(63La6w= ze3nVX)xUV`@so49)CX;RHM;4A;MS)W^;2wHp7q`GzJR>V?`5~X7zPDydD^q-XW@14 z%KcyaRxe__5emo6?T5S>)S5YMZCD?E?aATALj-xGBsZp-Awmr@WI9X`gn+SOs2o>Y zS>4-@pH%f&5sK3edk9a*msKoWTWbb!4Js(|5kk=Ojdrx$q_&r>i}Z~8$eM(R$RGqa z0th)vQM;<(R|fu2DidCd;5aB8~q17pPra`^VsxjCuUy@Wv)Hb>LgAQ78yt*W4jZZ z2p_@PoNa7En&84_PG0-X|M=nMV)wo1PCGf5s!zo8LxEEgYHje>NoMlCY@z#=j(Mv# z8E+(uwQ@b4t8`zOhi=4JqT-#7yYtmVrT>fc=1uvxUZhVgjC!18shwz8uKH|$_DA=_ zTjti?l{1Gs$k43MRU6smC4sq(xht95c4Z&DZ>ef_D+Cspc-LN%^i?%~pb_v&Lq znM!;ncF~zH$$}XmNG+AFhGGT(VrFVAbZR^tOB4g>lxgOw ziDXee;zD{O^r(0zBd4ZiAT2=*mP{`LO(2_SL z3q`d?I92HG-~$mvO0___kuKIP^Z0>z&``>iSZ66-t_7SmIywS~7>RXJ3lO;ns9i_i zL$gO-PHx$h+_^RQ*gc+C9*I73Z+!RG` z%EX=&Nk#bqKl#%`oJ0sT+%$Qec{)I3@w;{t$&Vd3YDzVCwZW3(8sqC+K6yD2%Y zZ4zOEWWs*XjX`_vbwZ>ZJWd*$IA$}(wM-Uwme;4u`*YsZ#R1PjZ?d1Cv<*BXF=oo# z?GD{Z(5IFA@PW$Q$$Cxhuq%N?sRr$4PND}=ER$6Sgz$77;#Wnau=dL8%hw@BM>Rkq zCd;41H#A5%CE(y?)n<@@qr0*p@WS;wHQIzR;7S-RQu3#9PkHvKLDAI=-T%OCy6pF_ zzxgi|`5nL9T|vhNs2%|mjD_{0W!m$vc8I4NwaRmBPKF_DCR3hAgZd`|r;1ZFZxi!E z(RzTuLBmJ}D%N9}vWqaADc|tjYI-JGk~{1#5jcrb2RO~8v20|3}Nr>`^ z=!bAPU{I_&S6PVOxr+d`_|_AxS^zA8@O3WgSu!be3$)b)##vR_{;=yTHX-UYl^e~C z_q0Sl$Xw9*%AT+FW~|h}S;V>c6Pd3_W(~qf$S+iVL|_mk#h6}#Q~Zj-A3Z8VYZEB= z^AD}{>#L_er7V!OPy@?gr7?CkwRuxw&yI<6dL!T?poWe4Y&tvt{z>qM0e^$uLtg;< zW?nzP@V+P6*D#L-tT{UUD|)Cl0+H;{RQL<@=WJjT(HtpbaK(3D0o}J00a_+PAo?Wn4KJeahIY^GLHG!Vy*H%3L+!Mg-`p_x+l6oWDtVe2# zS8|U%WPShp$UnVhOX^2I$Slt0%kpJjTnH#uC`U{61f>i~jxvah!nK4I!U4>XL>J;` z0DtEeK1dd)Da}y8YfX96 zQ-Fh<`5XxHpEIAXf=Ha*1wzM<=et**@1^+S3)p zp!g|M(1)Pl$3$~;SIZBms=y!hSA1L^H zti`|J~^ zg6rN%Zg?XO&fEU*yxh-yXb$`b3e;P=Hf`9O-S%;1`^S~7AC=b2vGv95728#DE1Mr; z8c~ALjfBqn;7daN~(Li_cf^%n#|sLTlNR{G;`i+lRSYeQjM8Q*4E9j+qO)cez^zj z_0ai+4^Pd$qu`H!4~_qHlyq+P8f9W;de=Sp(nIiu=qJNpgfds0s-G6YdOq@%MQWEq}2s1^Sd~TQ_$e=j0&l)7W;u!oyn{qu?ZKev< z0G4uyDYQ++=ShtWvO47kpf<$HTc9Z*rIkA{>x$uHsFX618To(WdOP z+VV&~Et7@1WN1XeprPC%JTL_O%$tvExf2&*k8#NjA+r?=21$EBm?nOJBTnv3jg{(= zVlC{mx_O=4Y_NhXphj}Dl!kKWm-?zHZw30&^Yvz`Sc{}fps^{`1PCCY+fy40oANpPrjp)QaPv4&WV=LQ2feYh5Ot0Jcz;ePdUnHY1`$O_Q9NG8?uz1G+JQarh?( zV6+Bl$=y{51K%&(A~;7_K2U~hb983(b8;WY`)6|K@0s-ZXgT2z4Eu?mcbW_mAAfxbr3x|-34(m2Mb(1qQ=NfI{<4{UfXrf5%gX+G?eU78R39{wWs?AgLg{dMSt z^OYkr*+Na~YV1(0C6=GC`C-cZL_nLw1*-Br0{bTjKCw)J-I0mfiG!5`@8+L+)Y`B< zd*5BnvGZ4(-33wmE-3I9jVG$Q z`KjK{8N-t=Ktc*7?K@FDL{&+jD0KCW*fX>;^@!o1PSBtx{ z_urk|v|)JPL+9t-HwbU<$=NrZm=Ds0z`lij{Ca8ez@YcDLGPgf&!>H^eaEI>Lr(-3 zjR@d_oAZ#X%m>ng7*@}D2>EKjo$#LszWfBxzH#NW{zRYEMrbkR8wt#ekdbThmbH#Z zc7$+%PFogxDO2=M&^SHItaUV)pNtkM)sXiT?Id3Z6U`{KB6ew8~SZnm=3d zL~_AIUba<>7bc~^EldJ54FI}qww_7YA+JY|WSVexAz!hwrIb~6rK=O8q28qt2p38g zX2=S9Ei;lpc6~icC?U(n^Ak8B9Kr*+6AVG%Ysh;NvcWRNmfll_bjfhhl4twSECS3` zqCmjTk~}@hpZHa=>JO$zGnEJqO#j8IFPNRrRsG9L@@#`mjb@_U=&lNf^ZrbEVKF(- z?!>SeARv_=(t;11)Yo~1hVH2?oMd0n2R=nr~%>%Eq zRY9mZdDB^L)DqG3ev^IGLj1B-j+nqS5X#OaiorzDUlm*{lVx^w^J0fn9fU}eBoaUY zayAzd5DBK&o*pxc->tTM^fOD5-I~ptQi(H+&gJ__LIPm@3S^qs z1f5qQ0rFz26-Dn6v(YpOLzZ~!K}-n7P(5et_N&Q$TEHeUE@nI%JzF-nJ`sqB#rQbH z1SvMq5d^DPAgK!>V@~t&^Gr(MsVo7WCQQ*_(yT0wg9sf@bO8_v(+p(mMbnZ^bdFh; z>plP_HG`g{v6?O!noy%v69h&Kn`flZDX5N?Oql|Mlr|%e%r2lB)h7R; zB$3E+V9jR?$y8#pj4CUXkgQFbkJB&<6iQ3LfqwN1$%ObFY??7>VL-1-;K-GA7-@s-Gq zhvfwhd3ED?zr5S=L4KWqeY^HY_KnDsKTHI3!s)PZJFO_ej7iN@`$19<6IXXoGO1R+ z*a0xLPbzUCGEwOXEvJ^t!Ri;EWOi=P?B1Dw;HsYU5NUfXEMJrw3m%V;98K@p2{3I{ z13D>LO=)H>`OaMMj1NU>i9)g7y!PA`L{`9OAdbn|o@Ae%hb8AIEvkWzY*S2oQb^r5 zmIj2q_JXsG5-P7Y1I7fqPp*)~yPHb1qF0;#R&2KT=1cM<<<>3Mx^?Nz8#9|XTbtGc z2Q&BGjhvy(9k*sbcr_cJUT%55Yfh-h1H zh5%=PKiY>fBQw$SBui#N8#?!-t^oCHN6MFzxhi>1bWP15+U&$avafQ&D!Ibh8LQ+E zXD9R%!+5@m9gR1d@k%3|t;i$Hjiw|#t*YsSEKXzx1`*}$RUCeeX2&b_AX%Td!$ACt z&l3$fAY0fIR|0v{rrC_bHfS4B1New#+44fI5z5zmrFt9@bsNi)&lz`WcqY~t%r3$< za1EPOZo52p;#`OkB2`Gaf?GxhU{RrhwgINhlrV%CX_>Fk)hPIbIkuMsL^3EdwVAXD z=7$5v1i{3wy9KtIkW4@pEW7hv_~OJ0Z`T(q}j~3M$gOGgM9J$ZuUnYameo zJzk^TqB#9tg0BC;AtN#`dqgLJ!xRP5Kea(5D_@#X{;!yY-sNTRQ-mDpPRTw^BK+zi z#RG7h3&%nyboCn5#PSnFOG$X<3qYt92S*x!HXREwsu$B3A?pTp&YaEE7+U#(^Z=N} zWb+idorH;0(y{^=T|uG{HiHc9l~lw+978*_N1l@Gjb4~es&w6A9>W1%BiS+XXrrBL zxcaIi2NZlO0ZDt3AHED2g;n)a{@$=4fOI{~f^*HRBgjE1O z#NAdNmxK^wwj%r9+a22U`R98T`TbXa@9!$|JKXodptrYMn~=7BEh@lPyGCVn%D-BO z`m7;JbX%?{Be2+(H@l39@3TZ0Rm_vW|1mDW4Fa(mZ& zs6*fI<@njNQ~ir#y@V9IH^f+J1h9WsQtk=ZPp{g)hBCwEUV*HLqjX|Lvnkd^LR`~+ zbgj304E9}0HRdnpfAVDRNB5^UZ_3{knk32T=PaTj? z%J%6-W3uUF+2o>w$ddpvKcoKz)@o;}2Jr>Q)1=8aro^*Luyd~{#FQq%n!T^Sq zucYi-Fa(ad_?1-AAImSglH+sMjK`YFRRFBrtO;V!1Fo&e>oLhX$gfrcb(I_Pju;YS zzM0Yj2m{NZULoquM9;YsW3jx~mzvI$!?B`&J}%HrpPnZ7kR)&?yo*W>JG_Yj$b#$2 zW&{L5lP$nf1F_tMym8sGYUciCy_KmpWb;h9|CJfblokPhcDD$@V~xn3x0OY33H=am zW}^MR%p$-#TZ_dCzEn}R7=#$2P+4T+3`+KGw4&vD0F6-CQSecmAwx1ZSd-o`LYm>R z7!0Fp|45!TOja&Qk8oz*Y^O)amdZ78VSEJufj?-h;Rcyh>p{_eQ}*Hq765spd6y?O zPFezU%*M_U-vgPsk>CkeawJi7>qC%ATm`Veq`^>p8`C&|d8j<(Jd$S`69{hw% z^bu9gOrLlywPS1Ur%yY<5`bNb;QqH2x*)IU9_J zPDKlrFPol=^=o5oCMsU3$!|^w1f-&OJXaGl!YcHbZaK!f?2}98SyJVVnZnP}=`(kH z7F_>!V#~8W*|+bZIeD4mgY=e3uIV2$#tvay4obfA$%C2O zcIO^_kVIc=Wvk5`8I2HaqHs@$ZM}btBD~qWX zZmWL%HR$kk|8S@TadJGojtIUPQIWb&ocbMN#me0a&TKav~mcYiprc%aYqVV`T?MfWFT z!6TmHMOXZ+dFOX;zAD?C;@+gFoJp>5sAP}6Ce>S^Q0B7zr>ano(PHOMD z=#hKpd}CTFVfqqrnu%H?k*$Qi>D)-PF`cX>OZiMW;?L&%*+pL_7)iU6g*oyr{m5Os z=p}Mnx*SLs6NPG}*>;49<%G3$lfGHp>BMr4$!g18Z+n-Pg&zhrFLPbPZ5-Qsd_WRv zuUfgPd)R--<2_M$`ti(`&5iks)#S{a>x))Zb|qBOI7m3N&y?#{y_M{=V-4Ts><{ir zZ{L>dKQtFTb#~!>q&*Ti5iR=jwPdYDF(jYpDb^*jBPd3U7u@M;1SX9@V&R;;#YTR@ z+JF(+DuF3J7CJo~I6fq|hmH}p7_rupP4!?y84zY<$IC#m6>JJzmQ}z)EnR8I>yz{h z`XLEXv7r>dHH3R$wWKI2`(iDcD#XgQ03e$Vn=3Cy%tp^)gkQ&2m1qMXAV=b#W@#iO zx4)M#1CmFo-A*NnkxI?noo^Xx@;Q5ongR+t+lPS#;0mnioBe{uEJ!zFAR>7Mt z#^QMiC3Kaqc$8smtlkKd;IUgs*8`N$GKv5wbAZsmnm|uj4V$lZL3ZOY!y8jJw{kL| zOg(QC*&2)`LBEL{qM&E+1d{1#1`*JKv*0{X6wQYGN2kubncTH4_uLaicI2SVU;~Z7 z0RIvV2!ZZd0lT+c-i?W@sBDqt{ z2p?%z!-d1o6i>XkWTGDi6VFc~6U1voJvkkr_7mX{F_b036bI-Xax(KZiEGjI*O?te z&}f)PyShW`LvJ$rbq~Wq$jvT|AT&#%V*k0C0AAA1ata?u_{29VRm7eu&0=6!CVdVK zo&JsA_;rxqU;pd>#hEjoPfT1G9lsdKdJ_eCTo|#SUoJ;h7yuy!4}yT*pl~dl{t2-5 z%O6VfiQ(~hbtGC2rYF}->tBbK%)1Wu&0m|C6xz2jB~)q1$NfS7dPfzOuo=zcnR4i* zzVTZ=NN@aEc-zBsJAOE`^~WwyAjog)N9Ef-ZQu53=j41D+{P5BaG0-Hk$iY_wBC}Z zpR0|4b7dW`(b5PQZ9=Ggdy@l*X2$;KO%{L$t6c5s)Nqxqn8y#4L;l6Ih}iX3gosU| zN5ai|sJ!=eS=*}0ep|FbS>}x>d2eYkHGr2*%C`V!i1Ub@%Q4`5)!i)`n_)W9;hdz_ zMH#?|_QhdNd{s`BE3Xl8WSs z5Ix`ak7xGmvTpf)=FVGNbC>E_P|lnuIWXusaB1-pHZVCHhId2R6)bWa01XEZ5^{7K6jEvFaWc+pzF z&VA}VR7+#1tw?{R+e$M%m#R%C8}sR;FXNkyPs~L7J=T;zGapD#QiB$1kwALXpYhMe zM@a)dtNRAA(6Xh^?bS~lptowh?C@#$BiIuV64%Uk8KocR;CiqR=n}TOej0C}h&WovW`nPj1+|noJ5zdSf5KRKUmZ*jTU5rKGrgG)LK&#`L z#TiU@qM%${`|iA#%_)lBR5mltR=%A}5M6t4*@E2q}S}95Yq8nx&>6 zClODGD*0N_yRxe=7s3y!%)&|F7={WKAwvf;L#{+W5RI{5$wqkI)PPeC3>wOgpaqT< z7VxWT%}D@Od+`jhCyLWnX&wkpx}q^E7zrHJ#EELK!*bn6Gt9v5fmDZWAZmM|j%Ki@ z&mc~OPa!3Kl{)15y95|BzY;eV;(e%F1*La0@dC6)KPsFX5yr1?1l!C&P8Gldu7QdH zC3pmuqrU?B3l(pp9xC>|ojdg8)t0=2g56f?L3pq)*B($bsJgQ9nAD$>P&CwY@+Jf( zSX#~yZIGde1v}|nx9*6ju>k;FG&}Be7KCpfuO>TRP~>RYN&loO1Vy0J&iCxuqRW2Y z{qCRW$9&_l?zSKZlah~1^iL-tD1sFh4wDoNumpGlogjHsyqFp()-#idnpL^(*8ggP zhc)|Gl6A6N+2xRY=vGk1Jyt$R1MfQW&VEy}YpLgdcHDKQ}XPU8s+;*pbl8du+WC(&!spcn5=o!GJ)9ThFt|AKACS7S> zyQklfH!TGDF@-|S10(=Q5o#!I(GHwr*kiHi!M5yxca`yO>SG5POs6E zoRO$*;65bz%f?HcY`vAm8F3{%!dXA`5W16?u&Mz$1!I6i?GXA};7@p3K_084VGngy zp7>TG`ZMrY@JJv%c)`6lo*&0hsttdA`a*iw_Vkub*}HE~Z`zoD_VL`I_o6c=6UBvv z_!+n_)3Zmd&ZL_?b$y7=+$@+Mlf4#o+JT`|l zT-9S0=a|KEEz%j40UZ#;ZyE_RN{l`Xq4dMs@? zaEvK)Ewbvey`odbwG$P;B4@H4xdcIJT}X0Dm*yD)e}*4p7~S^Fi^@#A-E7^bgaGyB z0EWh?m=678pE|E>C6ujr=#X4K7wc2}0Y4;HeFmR|3adIaL>mGMA=rLrg-d`ky0oKh zYyvJQZ|2_=qs!`GT|RQftfLN)r=-!R=gtn`V0F(B_Jir>WGkErx>dpQFVbGKy*B6p zb`Zc$@8ZdAzIw3QkPU=6*7guT!75XL;2fl)(6)y(I}VvQijZfq>OodheQzapZp}RL zFl7J((SU#H9Am(cPz2IOUv$V-4I}&|^Ma1gyn(Ad+tXnPW{SY=Rew>jxlPZ75GT>B z*ncw_&ABJ!Zm;YtP5)#Rcj6-GjUG@R9MTW=$z(AhhI2}WV}+_t!Ug~?OmH@Oj^4y( zu5W`z7{Y4}QV%GkBT2v#u_$DABWE~(X54JNObLNJt&&vvM0^zvq9!QuE0V#yO%#<| zZx|u@o=B@_AWRP9*MLvBOBd(e$%|%QvQHRY0W@(3(v|LP!dQrx;GmbUNwlF8!VUn4 z%ZW~4HKG&qB1!xx(djRDi0Rj}}XS)Ei01hHpHS*OIF<8M0EYzw>wgp9=o=?R!(fU%mEq*Xm%Hc!j!=IozUIWavs>B;29m zLOqwST_=Ga5(8Me;mz^oWjs#qpJGvsc7!2t4TezuJ;_U`9w4ZQN9T)$=(Y7$=Fn7m z&w=KS{nahc3G&xWpAdn=DKbPYLeV4<{sf+C-~tW!7h1 zXvLuDr1UKP3TM5WJckQ^m^Rbiw(=3^fc!E(7KF2f@GOztt z>Y-?EE|?AZ(lZ!6=>Z0?-9UPbB8kGN)lOCGQZ3*ZOkdJ};OJ2D{5k7vU-FDAeYtHO z=0I6CY5&X}I{}pfaKV2@&fT8~B7s~P5s{f7MntxN>G@QETAvI@5Fw-jS*XAel!~Q? z@Gh)h-`$}ZF_h@(bbeSxK163y9S}_d_x1Kb4|Hy`y#l5$=_6C{OalbSPs}A*T(nA| zm3(;$8)hPig=T~UGtg1o7@s66(PkoiLIVo%vDN9`P1BV>n?sujkt9Nz(LZUDW5fkN ziQ+U_HeXq^F{P4%Khmx9|6;?L6vG+N;sG8Ur@w+6t32eFT}45tvs^@$|TM*3e4*noC_<8nePYU zWy~&Dc7x=oxKzt%+!epDI@6B?7YpC9g@UQbHW;Y}EG!J781VBcl+b)y(tuXUJ zHr!cLh2jt3(L&+^kS>%Rm4|-v6Dkv~B?{>p5(O|^;ipbJXB0%C;S`I)(%^xzMCM{D zdH4)xMmVo)Y#1$Kw^@SZ2G;dhkp2mS#hM4^(WZ8?n352L_Qj{JUotSB5~pAgC|sV; zeQ~6nlPR zro<@h1l8NxM+j&~C9s(6-s!f9Cfo^lj6@qkt?>%lxc(S zP==u(&J*@aH6K4=1J%Gn_V(K{x8K_KjB*ueOYcfS*t6{^bV6^+f2%F;KM|?aH!1UA z291NJ=vnYdBTMHv1v%H|e>EXVT^xZc@CI&T|HSm+kUkj^GseNc_HADiP@K{5M#RAF zj%-uM0Q^hPUre5#jh;9?_x73jcluo)1T&YX{GUf&dCXdOOUu(;gshbll_MWz@4P*; zb9?sf*OwajLwX@0H&%d*N2gxtbM4EP7l0$C5k{7WXI4Fwf#ACTh zWAtKjPJSo`@-?F}(^&YwY9$J3T_Xvmhe3X%XIp)$P(8*I$~8X;2BDD-xg0Ut^|!_# zL<&OEGrEuy%S|mCwW_Yc_sSAtH`KlJt_l)&GH*4}xq6+?8cLS^L2FJP)3L53-hn@OAq3yx>ZYx!i34qWvqEAZH3Hq(>)MxK)}5 z8G~6Fl){P9LIuby;Bz6-Ppxh`6qiIG#3)oo>hh*9GZ(vONE;w7<^qh1=43|BmAma%s$p+vF24uz@4kogX5`g zL&!5#n4xYV$0KBF2_yhaL5vilG(dNFiYIl6W*W_yi&Hg{3ydDI4Xg$5!I^S7_>cba zKUDDd(u+?|Ok5luJ)6$Dsg{XX_O+`Ce(1#cCa+D5o2$B+qeeEJzD*43{L@KXQcW&4 zEqNA27ftJ}tgL{p^iXeQKA*0?ngm>^CcTpM()u2<6i6Xc=!YX$`(s!DN|}#`A^?VZ`zpIv8{IaKru2p zvM4t$;Eg!u6d=(fUv-NW5+i2zY+2MEEoR;tZVBsX%=y}!@3ci4Y$ zCVF~o^u4s%6vw`*-pt}!&Cqn=Cr<#6YUd7jYo;-X#SOG#B)m~1s=7Z^-XV+#K&V;s;DVezjdZ-ckQ+gE^*bVvkj#>&y@ z%%cyccWtkHv7hrQKK||YV<0*1#GgyDkd~cH)Lm9JoG+zwf#hfVGe5XDy=7B+&#wHV z57kb6+KfysF$!>g-&^S|o0n?cFS>Sz>tYK57U*7&Nx%@vzGgl_GnbTS`H7?&4wkBs z?A>=n@7y`)J%pyc>HgW+sWJ2YA3`}$Adnfx)iFMTGANMYxG-P!V9?+;dal$$)jGZ; zFS;uyv`H0asihD&jrExZSi%iFsgZgsP;K}DKxQxBFhL}o8J&+^aK%SMX?HL^m9Mx9 z)kSaWGSRmI&)R#b^oF=bzB5PsB$8_h^8H-R%S78j~VA**0| zL@^nn3#5l(Pa~HaNk_g`DIePfC4k8g8bjcpa0{%VbKF%&2a3t^dtxYGiIbHH_w%tn zM#Q&a2HqH#Q6Rzx)hFl>cn2rAC@_oB$@j!2ui4rP+yD-sfvOT=PDf>5XmTfx4WD35 zxbyKYb4wkx%5OZwhBsz*L5#wLJ<)PcI5q;HdO5HAE2f!PGN$QCI9gJ>X?ce(rQ z2iy{Zu>k;?+>x(%vX$6WL_Yt+Ox5bRmXeGK+8r`$#0$@e&S+=I-r|HzkFFWfo+IaJ zgIYO5htvSflnGMZaR9WE`^d3tA7$rH{1JYTC)!6K#5WWQdIqxs{h0{7;VDE0ECdnZ zSqQnh@;MER7Bq~tC|09b!fZItuSys*IFBBb6T}Y40F?Mwww=SC$*i!gTtQ5qq)1E# zM(C<7?7^pvD(DKoV-x}il7VyB#&Jl!4B;GIi8DsaxOpO0EQW_p=J!8bYNSVl_M6K# z{=Rkq+dW;a?%7HFigyzth}h2a_`3#nz1%*~V+kqOx9=fxzrGN#Ch1Gi*cHA>h?t6; z2IL_hPToiqJ!c>ym<sgeKRkS+U_6i#}VwlvAj=*`?PpZ_t z!)Oyj!xG`$dAS5bk=RPMGGBsr{@ScXn)UAYR}gP~<&#%XtdKK{d7a${n(OywZgG5m z!zSIRZ_~S(-LI#2KJDNBqq!Xq&g^``yZv?fAls&Wg|{!)L69<*N%T634gvqz0FVgd zC(@E1)izcWxR9)eDdN}07rOjIl2(kyZMN&putu<+H^ZES->G*%VD5zMbTOSiu`m7L zJ=VH)$sJpLKYeKW#A~!9^r`f;fAn5$1aPrM^Ug0(8o!_`*g!j)j*)7q9-A?*Gir3j z+Q~RH6O5aI zE;auipLu;Wc;qYJJYwd|4K|Re-?~WLN8Cu0llqf36U#OLZiV4!wlYt|7y zg-hD42tte9zGG-XKIU`9z!xGoHsLlK%!15-XoO}U;Bew>qUyyOh{A*+7^VlEh?7KX zg&9l-P+M<=NhAO=@-CTxPO5E}d5J`@5toyJ_?O&CwjK|ik;dln5uzImfN2nHq2>#e zr`_eri<$n3nA}i~XFc>xnaf<@4Vxx6%N^39d_GH~Ou6nO@kDcDvc+ya=uHQLxpcN% z%~h(ovb;d5{y=7hRhUuz!ZWF5KHg_)=qY#xv0(!wA;bs*9uJ?ytLYyZ!X7<{+#G8{ zFswEpYBkdo<5^DOX#j;}afUof(Z&Q}49-c1k=z(lrZFamTcyk1Y(>7*B(NJuCyTZ6 z6(iUqH7X!5gB~FU>H3yEx^ZTCJB)6L7X$^uG;-h!#|-MT2Eoc?4n`z?A@I7{F0p8K z;XgJZU^h~7@1bRAWdUK+s&1w&!GL+>!W7xKTJ>gm@zUc&3nK-$mSc}GTRD<)( zg7(tCd@Z+oAs7ffB2rg;(36ziWSAz3gYW{>foz#Ce^Qw+(~-%K-S0jbeC+PXy?YXm z-JjX9ooE|-;LeHR55n0I{pKdw9W$d8tk$C={_AdGBimw4UeHnd*MD&hP9ia}sAY?a zi~7D$lh@KQBzVTyfOL$GZIeRihhwY)0-1q0$%wYl#)9%_0fs#uIwj8Nc>a&B5CS^F zRq-{-q*7h>=qc2^s2ij>8SYx95=o2bN8*PKtXE!c{n1a5z13-j- z%pQxyBM|RM@E9JU#raC8=@zjNV3A){4sG*R83q>0j`FWI0Adn16y!OGQs;v4R==!a z%X`FKPlV_kIpct+!9|A-e5DGs$#tvQLvqj|m2&Qu!d^uCA6V}~luY`F%Il`V*` z`Hnd-3zO&Q-|oSKSqf4)I2LSH6K$AOPn$+P`mcYlyRq|w58kcdFPFRa$RlBpX<{Dsnbnji zPNP1Up}g#ADM9c0bw1UXEgYnwIp|sgeOT5ILpN5o`n!hwKCbP2DYos2#jQ_zHvh!G z{w?!aUZwY~&9B9`J>}j0$ij|?fPJ$&e-hgHUSZ1zIq>411M%at*S7A1;K9i-*#|$u z9XN)uOlclBp*&kL(JpZYbt6w~6?fyn?m5xrVxrS6-THwL@_(BZ(r zvEb*F_?q=Q0?}g4hACwlvJHK0@p9$?u>38B=bx;HCKVRYRjCqen8igg_fE9E6mMCs z+SvKbeRrkSt+SqaYN;4p>ZF#IuWfqCg~ajd;0f99`ne~R8O|$Xjb=1g@sP{wt%zA3 zBSJ+p6?dlMnoL}ACkNe`AzyBUNKFMp9wHOu9)Ae)nmhF-$cD5*ULkSf(lhb%b7^^y z4n;4-`p#KrN792$lkG}%fq)FkF{B5|o)Utpm=|El91v&7h}b$q5O&F16f5<1P|W74 z^uQ?m3RmQKrh_RjCNBa9QI-sWQ!OV;t#G8eKpG<*x?^LFro2c&GMEg@Qe~<#maNFL z&xCkp4Fd!he3;yWgTbvne})6E_G;2zyB%W)s@TbEPxK!Sq=(3YHF=Oxp4bazMv)Jm z0JnG!V$oF`C&7RvFMP?WA+v^gB#a`k0hLU>X{AfD@jdK;Cc$1>6p{i#gkU@33p^L= zDWZd!tlSEueB>m(@vn1Z1%85uVRJ_wBtZ{f^{ zK6;{!XQF3FD)#dwN-$t{Q?oMA+eIyoCnku3dEdk7C$RH`_GCn}7{l;^bv2(9S> z8po>b^U%t*rvXeD5}iy%<>Q2vhAigcTxd6fbcKivfLtAN>N8)0E$x)sTNm6IgLCv$w^UDw_rAHuHD9w2A!moPa)Yg z5VO>|PzI#S-EWUVbWZ(dLnS6M8#})mIf+RaHhNBS2HX}al%lgkxex9y)g?hPE+H4! zkZK_)59T7^9}~mv9wd6p-ZX2hrP)Lq!j7&42QtGp%1Jk7QZ)%R`lm(! z{zXS1d*Us}_%DBIY0*Phmu1!Ms?iZd-X$XSvZ7GYv*6OLIp?_ zk0Yt+$4k+ov$Q;bUPlL5p4JHyd3{>lc^T)C0+XXfLDnS4bSAf@v69Gd&=#pqqTs7o_<-QIEyUF~#*%s?v1H3^%< zj9VScD*2pI-Dh3lJQv!m5_TBK=0xn@QPDv()(q~XZ{R-!aV}n7PGVTA{qq+h1o}vk%blJZOg>4!K@WG775M$a)~_QThj4f*r}p%ybGxL|*! zb~sjFYj(n;81kkDNumtLKm^&eymR0p%OV_| zJJEzZ&D3-yW5n#Ei(okkt4uR!UW^yKBKr|~S6emBFbw)p8~_`L2#2DdNOr<1FD@oW z7E`jx1*nBMVxEJP#Yj+vJp~+_pEyvi7zp{0+d$G2;S)efa6HF=6=Y5WBm*&MFfHHd z*X^B&aSS?d?hf=2qk|er{L$Pv>a&+^MuW#etGTjE?KYT^}{+A53}eLR4I9h!M7Hk=o_c#h0GX+<9Ai=Z^GkyYo*xQr`Dw>D^b;dv+#v zYzF_WT+-d?6aCt84+~MW$`Al?#FZ$_m+OhScz1t02s{m8PWXi~4>BWoV*mAK2n0qw z1BPR2!}?&m+1?Kc^ays+eC>?`MvP>~AhXIVA2ua85Ui=SI5QCf`N=2aV2_@OdlJMt zNf-cvsIy=&wAY{yVU`>NR)F;w9u|&S!Y#JPtnmoiP}gzLZpECyjsrRuBdq%PHC>)# zMiQ?K^3a}XQ#RLffaSnHGtHD|oqKPgXbcI9!tq5Z9r>sX)+P7i+va04=DhUKk?&}6 zU|*|LZzk*YRAp#?aq=L}g$q!tpeZ_W#V^SEVmlVgO(NBcixln0nLZh@r<0oyBO(x0 z1Rf!aujX0OY;`7D9MSJT5p#$J1Qy&DW5cA8BqIXTDf|$HvqPKAp3m|W6XJ5p)+XkT zBf~%1)Y~uJpEziHzFgH_iGEN77a}hG^FRFQw-o&S*)9KZVCcle#Kp9=#+M7Qgw;Ga ziBb@EMh?UrxU$dR!5$(c;`YQ$$mPmBCWMu0 zp(58_-zRMpEILm@-=OrNUm`evP^R<<;uj^oTuk8xJ0vw1u4HcAoqPPjGwP8c5;a=y_iE-hEDHj6FyZ2jz+>gW55@4uFR z`)AeQ4%<|%#y6c1yh(-S^?|H zA7%FJYWpvLxnvgMRthzsB$Ykko9IA=?Me;KTLV{u$51>3a#G_X3DJfQuXd8D-P<$w z-POq~w%XCT*g3KSL77R>ZLt{y_MNlN#wxNU9zuozof?4{_Yh0EDvtz_?R36Q!Z0G) zaS|kn2eT#(x6Pd$phLPmU24s@m*nkKfEqXzh)-xHSCP8rVtsH(3ItBUWUCcJW#lS6 zY9t^l5L`w5O=2Kbpjkp2aaJKC6XaSvR%t3HvZ96DGccn(NH z$RBV|16U%;11TV6?oADlw!;~DH?V3xwpOW$E|4wQZaQ)n+>G7{b{GuON{iMgn^Z@Cn_3TkP@n(m>@?R%2DwvEhu!nH^b2#%J0)*x0VHnx;3Ref;6 zuZ&o&hp>=ziM%44MRU?z)qQ6WX)q{)#as!~WOV+;RdZ&?C@drKP3M!P(=VsO zBcvyDe}euS3oPOyz^jk=tbCWTPFSbM*qw!?3d@ zG#)xhy+IE>eL`24nN+sX${?j1n(KiGF;_ZuvEdxXLt{Ahud-g%E5{gReuHwwzRLg7~dKDy4UOZ~dsY;}O@+ zM_spmR5!p*PRjWMZO+{KVHMi5ueRrt7BEqNf{x7Okg%o(2y-&K%8S7-Cb|#LLD&O< zh-wf`VYD_^kl2ab(v&Y5LR{jUAj0PiiOCM^P^u{35K?Gi9K3hAK?!%JGRM1#KcHv& z!E;k(F+WVyW3Ba0uIJF?`M1D-*2WE$kKVo76s&f=0f;*EfMl93&oi$@YYwmJ=?Wn* zDf=oW1p~G~dWhNejH2`n6i-AZ==A*XOH;18n99rIS`xE32@oa*2{57%uSd!szhiCQls)xnr(>1ssd7E!ocyK5gJ|NQL>D%}V4oJyD!|8+wvaxR5pk3)}}C`Q+mVvdt1vrcw*K z6PJ(-4lGNUmBmykG;FpAxnh{48TbYva7;jt<)-LR`6t+c3qd3>OyVaSm1gxJ3-@#|#d6lqxDY!9JUe!?V>Aw%eNl4Z|W_-ruis>^qu!$4ak zgPehMNEPsbF*}vcTy(n-PBK=hE;}rsH6;;+s85h(rvsFcCjrF!NXhL~@#H~k`C=yIYbsHUl$MXmjyCq=aznA#5T?x{|X04#%V}jE&BThs~DUu)`QI zHW+45#=}UL>LA#S5(U7 zrWjbDD8&~Dun1qfy$K}>lf(){;e-@Q@~*=TruOF{%m6&Z#BaZIhc5g5Z{PY?`Z3=r zcOPLvo1qSs11+fu`B%@|zuL!y3yc#4Lup~3WKzyHHz($Z1k{(6n)3NjYbI8>_w%N_ zxBF>(*K?sAkGl4}Us6x%Eb}1pFnNjac1s z<)3)O+P1kmE#E96ofBvEZPv@)LwyVTPR+herkRV&o08-bGD^O(zyTd*%H555AbJLm z#?0p~Rz^(u(*r}k&uD2Cr`(A%R%v=Xcx2drFq#{I2hQ6QXCke3YH2CkYS*57{^{TQ zz2E!8Km69WzV&Z^|M!3YJKy>CGe3Sf?VoR4xtP8CcKKS#1NYR&FJ4{BSCWBB(kCvo zlq%Hnv#ENuSz2DA7No<%@{%kLYw{}}{wV*N3l8WhuJNqTSo)#>};GFepJpJ zW9#GzdcgF#yuB2zw|v+i2_75L_BL@L$(|rCw?s{mL3$ufVvb}Q;tM=r9uUs3m>eJt z5T_6${a~yFXy5{lN~)li5}YAlZHm$-NsF-Svo2Q}vP5Tpqt+(U1{1-}$Xm7xtx2R7 zOo9vzFoHKy8Z*U*3)MxqN)~3+2H;Ap#k`-3tmG;C>LM^sr_8U29e786qW%Nl%$kkm z=$yzB%8rs?0B6qpZDw>Fq{6?G;get&q=5=ZoMs_&gwcz&fGasZ8ti_~6?-P>npLZT zW;0rA1PL_SCnu2u5S%{|6o0}e6QNHfzzq$UDVN0aQw#zBsw1*BC+U+(0eNi>bwtQ{ z24OOatodlH(BQj+oyC>Pr$~KXh5j7m@dDOu)34dy$t#;C?cvBT`r4g^S zQjMl1+l;mIEqP7bsx_14dc2tN7Z1HJ`-$H2eR(c$*N*h7&!*0N?EdU$;WwVi{rKVH zYcG~g@68VFD~9?p1JH1;;>}m(JKexyq@)X?2+C_+W)@5b*u>~GhQz1p0l-OsX{j7qavKzzp~^CArSd{C($M8n^vm2O?wQwSvC>p= z7D1tL^TMXQ4x%0epKC5!zy_BndRC(42)Q$IhDwr9pi=<-U{qK;5SA#xNpcdf1H%&s zF;B&)*wt(BZd@CWvq3-R4Fjj=-dRla(WYn39{K3y5FJ9aA@XxzpI@#83x}Q@ncO?D z^1u&Q+3Kbx_>zeu94(@d?ah;4Pyb2)ZZ#+J3sNPc4+rFiwT^gmLTeg4kxx&zE%U+O zo|9jPy3&xF?`z~xrF`D^_kR1oQt z)oY2wO_h!S0RQw!L_t(|F?osV+KLJGN%$po>Yt1*>Tah1F?O4q5REklDNTkm?_93j zbx2^}o&&90KWXlM&D!zs{LbgYyZ6ho-)N`^57-ilBRzpA6sf5 zHe<^cviVp1M-0cmfGEy*I6CrS_yGXJErElta|8F9tF9Ms*Uao{hjmu#~y({UF-cTk=A<1{74nxcqr_DODdlncli3`@?%1@tHt++?|j|eY+C$ z9vTZDSEmJP1k&<-v-1n@yW(e~xv_HX+D6c5*J}+BChUn6s;-6jSzX6U6(<+sr{V>< z=bNv(DB1015XXiY0^Bw5H|L&>#=;)o+>=i}`fvWtzuEukhgTb=@`vx2KYX`2H+8jB z{qoD^)lO}xRk^yHZ?{v+SL>x_r`GO#`DNWu^UI&Ne*W{eV8NwaJLPF!9;k<0SHEoh z{68%T{k-$#)rzy0A|n!WgYvwNydN#`UGDdFze3Yx@~U;U885#53MSRc$?a6!3CIX= zBwQ}7Dt%~xtu&eu6pC>0{7TDRZn$%G`CcSNJYLk(KAxYbHbQtTX@C^fy{Y6oJR3cy z4|gxbFSrvI;ghsP=XznlyrYWca3Mk_!{G@ijx%^QmQ6-St&6DvIwyTnt3~q@Jx`2% zr3Whc(wA{XgcHt;P(lGNkxaTQUsZtQW%QbdYycAS*Ypd@Vhz-v1}%}VZPg1}sW4t8i2JTr-5`r(r4$Z3Y~TSJVCuFVVo za<80dg*wRMz+%OM42SkfdsqV9D)S&qU3}8An7n1Kiji@dwYmA8NSCg?b^sw{c(ecH za_k3GTBvz3l6vD>+Sa@06QPrw0T94RvFZbiG77j2^bpC8Hrw(ELA$q`6WN7-;nutz zEYoLF0K~Aozv6g8ycJ)O>Kd;Y&qmJ^0nJ*V;8CQfi(yLnT4FvvI1)UWm3>mg9gqNF zba`2J-)x%q<;ndZ!d5+!kGQkm;f2flvQIo@ZCnoov^H)43#PVgN^Rd_?c8iVyCw7H zZH2?nSo5bcfzevV-EPI2%~&uk`?f&jR78hz$(pDe|59Ts*5#E$5(zEB% zL}&2#buaMZXvmZDhV$MOUCELs&c#)fI-o#ImwGIc8$;%lb4ZdwNtycG1&twDMl}hH zGvql2rRTBW7f9GSmJ$tM2JZ$<_WXq20jXS$kl_a&R13H{DVBM02A?Hu>$s3De+*Jn zthx-$r_1w149aQU3mOhJvyug8qUJloD`|pEhUg?rIahF(lby0RxBro`DOvVYQlr%d zcm$&0Bw>d-1oMV@#Sk|l@(Tm?oTNkbYnw1IbUJ+fu0U%N-bZ11qd@_GUK5LfkO+;;lk)ACvXmaH-vzrs9UNl?bD%Dy!8@%Q# zZYD?@=4khSY}Ou-U)7Zh^I zbKv~KUT9Xnj&;Tux0WyFq1ybYE~P2~@CivAU=|bMFV4=tdvWpOM1GP=SMT6JaHS!s z`=G7qd+SRM2 zR;Tjn8?W!*zkh6E^ob`QyYtT5Uw-w)NYp1N@XMxWdh(@*ADK9J{*%u>y8GTcA9&#Y zQ>TwNTeWIa?r2nM0RS8dCPNUpRL#tbK!D*YZ%(QmKVYp}S3UZ%{z>JBC^+CMoZoo~ zI#qMQRT72CdOJidSZ??;wF!bd)fkXk?iZLljASEV8JCkYl0{h-0xJ-{fpNA?>l1A5 zq}*)9nx&W%`-$Oxv>|zL6`V7dREc_ha5iSLi}~C&RH({J)~Y6&QL1XUe;y($%$R5F z$izBXSi->g*J)!t#OO?oz%*wb$s(-iO*CiEFzf_>7$ozhPe>nALufh$+?Dizkj0{w zl96=xD@G70Kc1fgc$I4bd2rKUJLLht*%7Y^Xc@V0)T)_b0-psCx zqRg$&sNM+RSCuo+L6H;8ljFg2FqyA-h3v4VfZeKW;%tcJgtOQUbv&r&9Uo`gYZ|?c9y8G4Cj>lZ) zrCk8uJeY6CBMUp9@ZP#l_Geb)hgD#EFlG~(9cw{5{7TOlyxt(988O`1@4OAkynT;<{H=fwj=W4<`#AVD4lb)Y&dF{W{$N`#F+OULq z^t6Q3Zs!iYM6!-NcHh|iA%d#lIdc{KFbfFif+^AxNA_pty4U&+^spgm>QxBWl{gMiSyd~wKLUl z@#W{N_3Ns~KX$&#L^B+|(*df>#!gbNuex@*9?d`bSZ4Rm=IFVAH6G5&?LTw>P8MvV z=Iip~!4qFhzt*?#;d$5lh}ECI0*)c(5^V{TcncCFD%pKzs;;~|Yg$`B+Iz z-k==Ml;llVCIvq-#L8^~C-{pdg5^pkm5P3}|HD80!$0i1aQe$HI}P9B%a1?)Z~yHd z+;i`pFZ}c;yLa#SKmX4^xpb-T%P(8?R%QK$b^reV_&@gS+4IaZPd)Y26Myta|8eWq z&9zz{@ORH^2YwZ~x%_`(OIm3%hphNFXM_P|Zd zg=-1)rG~5A@L=E64X^>AY_;W4Gpjf|ZLpo%C9x)vmwk-kmI_rXj7(_(2j(ZE7vY?Y zc-g!nfh>se!enlkfG}*EX1fcN+aglrY7e&JlwgK1`85(>>#3A6q z0M3J@EiWgL457iv5*h(i*?%Hr?HQ^!Ls%U`;9qnX%8aJuF5B5kBi?MM-HGle#>Jm4 zxdBIBr#HkE&7$INR)8xQ))Db`P(`{ZJ8V~*0eLN>E$d9wJT?eJfcy&cDf5jAVxKxD z&6o}~5-oM1jucMnC5!0#D`#L*J24A;f@o*WXO74>f?)EKSe?d7h(t~Vu{C}p8uH7{ z4i20M6;k-(B(e@>h7jl+Q(3Kd&fo<)Q@QJBB0DohL`GJ!84$T`Oul$4``{o_?8j?e zrZ<%&lBqW_eiQUpz%ezIRq`f_?ourlFUXdV%CL+$|EcHb8~%@8%zyZLdfV3Q-FLL3 z6Se3lJ(Ow*uO)9-BL|d%;>hca!sRMVB!h(0rFm={#*|Oh1^E~kz#3_(jR`wgrVh&J z7!3ALx0n+)iR2UcX^cE;>rB84PBIovOjbCc{nHYkBOpnq7>RL7tiB>9(P^JfD2qcUZciRk+=_8KidjzN;Wm<49M+zDOn zL|e^RvvJ)m7l=Qt@zbv3PdeGK$ymj;g&AxN7a&>MpyWnGx2g`CR)aqX$0yfN{Pdh( zP0S9MqOlG|IC};>)!R8x6v2TQ!jx%Kt_KJmJv`iqQl;53bCV~W8>2Q;_j&r2A1U(t zd%ykv)~EfB4}5HI2}v7RGGMX$Eg6)H{a{*ceG~Sosee{NgjJe##rrYZ9_H61#0wH2 z0t7Ru&!;Po9B6_Gx#` zPdmX#0I9G?7=%MQ#99`U1H>-#IQ}5+LpahIeI?;Lgb@lJRB5vcVGp_vY7;|C05R_s zK>3OrAH+|wZD*LWoyd*}N<=dTf{>?jZj-Fem9%9Hufc|7s&V0 zBdPW47LLEcG5)Alq}YRh7-70I&;UZncX`Q{=Q&(JW=-KYU1SiipQH8n2nt!>dnQ@%tlX_YKyb+b0kQ- zi|9bKrPxAP#2`B;6dI9BnG56DD_%=(BBNa_hV&q5xM4m_;<(?+1obK>`1{`Xzq@YT zE#Lj_cmL#1{`kOWA2(XnpZ|Pmc4**F{=BMt{Od31PXrz8kIaf`5_%84!$5RD0rdRGhLCy<{VK?qymbz&KDnfOAsfK_FN07P^{DKypu&%EsCT5O^Lozq4z zkpBqsSxm}T<2W#Dlg>M{vU@Po>FHq=t*t?LQyDtX%*W32FJW5Ysgq!a$_>srSddL< zr+X} zg+40@oSS|eI-Mu1<$V&q1%W-DeMp_6M-BC2e*BS?wp ztfiW)LtK?j_`H^UvPGu`AzlT$Tt%uw1?VwRl-+!=I_eYV1@fDU$f71~^chEHA@_Mr zC4)NP3bBwU6v^40j|3$5-^i8py#C8o3_>bKVg1Il|SJM2E=j9GgTsCqY+uR zhRheq>}yy0KT1nANGBOfj*)tpi|sy6${v5ued<~5!S3@$=}qe;r#x>&)O7?*5yNR!}Czvw? zhDzYoGdCxHI{wLc?t!Bf-MVGxQ@)*#x^_HdcI56fj5$qr(JC!e@$YtlJ6P;e4p^kD3tC@ zS#@m>t!(TqCPEt;aKKNfhS{kHIcaow zZ(_%maC+O8{L_!M zDnSV}?PRl)4yLaVE-BhdRiEyIKqtY>5HV5jddSWGm762!TA)9DexWpRA>B6^xpXml z{>=Ob{jQG?qE@lwO9DFllSCy?bQ8=quE1?iKm7zi?Z;0(_S92PJow-P-~RTW-Lmd` z({rOByu*h-{ewUF{m+01CNU`0nzWCDfG){(n^>%UnhIN1TXW#aRLd(l}8Xr8k z|C`_Z=EVzVuYTD)*MEv;?>+rwYwU^#bQ^Jh_q*Q#HO8&rOr#H7Pej8-1#+#t zGJoP)v_T*=CgJHBnYF2s`H8X&9}Ziv*PE2bl(P+m@HQ5_wC~y>p#|-{PM2Ld8ud6#8gw01gW}@fl zQ!Y18g6Cg--rBq=c4i+EVBBgW(P+l?ZY(`0lUN0?Opoak7oZ112XZ3`5m=BI9MbvX z^{=qln1+*dhL6qx2b!r}LC8~kw)gsR zSl1c^&^MEfkvn^Sf}}UcR24wjum((E9JA=LE{H&FH?~QqiH=m-7@PCg z<>hqlz+=&gPcRrH(9_|XB+sLpkj1~^wl{v#4xwqway@_>!Z1OM0(kY?W?xC@g=?Li zD>1sNhKV%V*;eP;W+>{ykT$pxEiI+M4GZxLh}Lvt0NM@2fS~J_cjDOmVZ$!A9^Uvi{0N9t_x}`C4Rv)Xhsnw2BA6H}_e<0D#d;nUmMT#%~ z#M-!_`o%|`rra;6x02!P1i^GHc#H_B&EODjQ7W+p>_YLapcq@9vjzr|7tUH|p#JdD zGp-L$&%Jwo;X~{OjEK;y@?8q!mL`zN?F@5M+ZJN8S$^&(PXW}*jWhrb@_6RI_r33K z-?5G3L!W-~```TLkq_P#@V8`jmTIrQ{xcdcdS)xl{JIUdeD}NGOD0K3mJ|FfU#*|( zKl#mX{+o|qd$Bn&5P$ReP-x*A_>1L7WuawBHosNvaFt$;e1y!?GjhAvO6DtWE}>6?BLKxLs0gqi7fOfS4*|(bCv;AUh9!_xZ16|6wsYz)K>$bC z05MSE!8V*gGH54Osr!klVY8cBq2?i0(tbK}CXyYeF@Z_*D59_(2?8Dg6!d9&n+TnZ zLeE?U#=`0d!FAbeZ(=bu5X_7$rpCQ#&{8B*@dY!}q0Fec5pa^>5R~7#%q6(nN{3SW zGJ3o)J)e-dbIiD40?sGR7lh@WyGbFXy4t`X4UHhy-20~Nlh(E~_OoR~38EOUqG(7VYtP&#V3hkhD`r)LbtFI9AHl>J|U;51#QkysA&K}e?Hjp3q56G?-ViTzs#E&S(gC{a2+0qhL zG3-ov9(0Sq8O2QJq!UOfnVUf}QwXy`+Dwq)Fefw^&rcz3a)u{GtkWklkD?Txbp;hL zaZD5&zz1Q#(V-k@ra|ERWS?A3`~+-T6Zx%4%mT^aJE{VS2}aadBVfWdGYAO>%&W?H znKpKkUWmTXAQeucaBca#)yY)T?#x?vv`StiV0U;E0w79+T*)$o6!b;scAq`Od1z@l zLx@A6FptguqQ-1f&jWLI|9af+ShZHR+3Mb+LBAXzK#XL0t%n6|k~Wl)dGBxh#;^ay zzxWq{eShn3{VlWVCn)fL`CtA&`;NYTe&QfCm2qmb$mctZDzO%nuD-(=YHxnhd!SZv z7QMucbpaN+in-e(!t)dV>f~Sh&z5^=^Y5Mq`EA~t+x(n=JFxGOh25_vcfFgx?Le!G z`Bn(b_uScJzb8|yrE$Zhm9JSSF(Y7^xSm-#GrV=5305+E%03l(OiTNxHHkS+M^2Ak z?~in7gTG?cOJE1v$N<(rDZkzJ6{JB(B>ZyiXi%2WehCN&^Y~ymJ5JctJ|R*1)pVgA zp9o*Knn<+4ojs|`vHZ+p;<_6zvqyfG+_EwF#JwCls|fh#PdjQEDV+*u5nZ=I`*1qX2?&Ja9>&CLdK}M1q=j;_MCc zqTJE1Cg=na@|j!@XAMuPvSzv4qOX>#WDVjhv>>NfVI|;j|ylH&h;}T zt^zU8#(-BL=G&o!xN3RK2TP{HXFS$)BscF*&*Hbf%-p2N)`N(2@dnXV>Oll$ZmUV8 zrcabU5juqyX5;6H7hyiJ@3#hSReM%n$9#O0Lx;5lcB zti<#+uFb@*JzNNr0E;@g#N3)^)`-q4A2^=Gc@ZF%gRL6aBrlF=rPS_ZeA&4ndr8df ze!`^Ug-HZHW;XE=Ole;9=A=Fw%D)I4+aR{2=T2K2)@2`hAQh1>h=AvcwKxN5hc<;W z!?}{1(mYj)#PajGGL^s#l3y}~=xV@clNug1o_R)j0yPEFRN5n$2d2mwDkUx_Pdit? z3``uy*U%}bof=pa(Y^27%@)plMvf=h(;HK^Puhe)@CAD4Ilm^M5#-|xxfn3EieNFz zaCU6QAYDz0BG|P;kWKuGzqpcv;jDb~Ll+3HF3T&EwYihoj~+zVIBX9O5C%`7$n=5T z42^jZe|o|r*WPG!TDGM~kOzCT4R(b|*!{0I%bOGCikoCA3#(C}5}3f;|LwkK%5aP; zqu+G#4`LSo@?ZW>zxHdt2H*qv{iVP3mlXW{&hPxrKmX_d<9FBn=_R-9gM-YmSVW<> zeTkft<`ph|x0Ewj8tfrV4z#@*3r3j9SudWOb~&Jfzz)Lm;p%n9>UV$VsN$PPH5#(eD- zGUk*nHY~q&-O43Q(%zpQUXu0+xASGbsr|7#cg617HMDS$;S_X{UeTZ}9Oi|KA(nW4 zCR2$nB*r--8uTBgG_prWyqL5a7&%(bT$NYN2#@L-3jWAV1XuvxH<*B?ZIB=qPlVMk zJ;R^&2vr*Xczy(?={;4TL|fyzz}2*z^X7hdpS5MvQfZCXn9;;yawu0>mBNy^>2b(?B-(^M@BKD;kf7K0kc$5B}f}?z!hK zFkCbmxaF4b-}2pW&!0Y$4Y;SL2fzL8KfCqTJ^a)#w|xct#Vt>^-dQRhJh&IYr{Ir& zIR*}LTzvnH)Zn@A{pp|B;181}J(CaQ$(WT}^-cogqiGZ7;cEHp8iy7jYjPVAjKB8w>u$Hg-HY@uqs}wk$h-JBe!I^h#FYCGyg$=lCt@JG!aA>&mc;6iY}?7%k#2AR+u*HM&}5)j%c-pMw}F| zh9a49dh0nq7CbT4{pi`X9%zP4oT{XvAd4toK@{H90RO^9(;#ELXH7G!OseZ9KN`%( z`eXwU*#bt)n|a9u>waP)jk!csiJ&-7@WoV^m;bG&QXAF>UV8$2OXkr+0#r9`p2yXm z$3iDl#rae*5Xz1dTa{<58iXxx<+r1tuGIoDsaoE;NR{TonNfK|+$^-i*h1nWs`sWY z;}mce%TLV4*0}Ep;=xTE%f{D;o};<3i4gczwvR@$OpVT|?iQ21dwpYF7*h9r4ukmN zmY!*bK_Vq<~>-8zl~9_Osy#3$LDuokI%FRedF$9{-xx3D@|h&1$Om z9kJHkQu(60?TC{ogAfzuQmDG3xsgO+B2$ttjP*3@p{vb!>7%!-_3Mjo{p@N>B6y)1 zXtZQ6rE6`>^8_=IGv^oH9|?Ru89JtQJQ7501D*rtWJj0}PtU%6aq*Ku@2BWyA#s5q zODnO*%&bawFK>%h0*o;7@PM{_!9G(eMBMH}Aabc9(1B%P*T(uhvhWJNcdO zeEU!T_>XpP-o&q4w{DrApR&OpmsnYA&T1B#%O8L8$(rD=onA~&T?YK!^8N3n4ERIq z+44fR?9yQ2B)Eb!gu!Q}>257Wnj`1ZTesw&dA!*U6`Qj-gB?={({g*IG)po7MwAZ4NO*!dIZXQStcDG=(TlEV$0ZAfN4 zKCsjwDs^9gHFwhl7T|vPBv47V;xo$t${uMFzyZpkTk;=F5wPP9)%y>hoY0c0dxQk7}XoVOzp z{!f%4j&M9CG4$xA#RG%BLm)HhkSM$Y{^(qX%Tx>bdfs*!nrQ>EBKc;Wygm=gA@f~a z+<(P)hxu58s*EywUF& z$d?1fy1pL2<@}WE~Xq zHcM`@9f|4lGDc3GMwRr>pZL+JQ4^!nenMU_?4t+5NWS8BF3f;dF*&i}8?0uTz~UlX zgNzvqA?wgK$=%*&wotS3wS1$U&AxwcCnNEy$M;c9xqjWo1v<4J0#>3ay#=oGY@l&HnO`YV2?f(2ly0KfB_g9`Fqd+F!@KgWMhKi0*6fB4r1H++x<_HEdkd-R0& zk~dwhUBlKmrtv=6WWHFBv^zN_g{6_jkdhP70IKk7ggF_K*ODMul6Nm6XK+%=3Cx3L zoYY4hRui%ACO8C^&?9-1$bb-VG~f>PGf`BJiI6=#_t=4lgC zv#T~U3-JMD6-W;;mYy$EWxH%=h_eZp$3RFGP7pq-2UlFX?F(Uizy;7HVAgrwNsMGG z`{tD1wIg%)?MvzIt#>C;1K|k*0p%v30F-2YEN>n{>}jb~Zih?ezV&h?n7#jQYxAbs zrQ`Y&T_FfboaXK5bb0Qw=aYWdzP^Qh7hE4-bbo@5W#QL2EqPJ?^?o+s{nVDMtR96= zk{&n?q-7UnBuK!;Kj~10Fo9!fx$at=Jl}sp>Egh7k8iG6B*Zj39pXra29eO>@sHkl z^O>iPy#HouVRX4uy}F#cdbKe$a`Ey|f3sDxDw%v^dEOH|b?SUP8v*d~Z{PV7p(_K; zu}j5Qf7+NB9y<8J@Mn9=k;SQqeAHyk`v^nGxq+NDl%^suxH(23AwZ!Y=+JJg+<_p@bt8YTi~m zN?0WQ&U-|j>Wm`MRj5D`Ds%?C&n-(a7Nj%5;9Z6P2NLoyNa^mOFxSny=B zI1Nr!uISk;>0NuYyxPn|xSswAF|Mv3Lm*(3Sd?#mxX-&jI6C#pW#6api6LPOM5W8# z&(K9g_E8ToM<*u;AH)V42v|deHu9hStCR3GG6ea?j<)EF%TWZ1=1*PDgkdB=d}mO~ z(Mlr--deGCbRmy&!j-U!xg7pzEEa~%$Oqr~JE&z5!V=@*eF+5J78?cR-F#S54U(09-6Hz z08NmaGN98zPzqw4uC2sLuy4vddrF^7hsmN)bfiz(I2!}_inU-RIKfCbykZr49gBVWLiY=)*;gWhE|9Ag#R6$;)Y(U@2 zf3fI)()0iQUkd;DRB-R`$OX?A3yFRNNO;j`h82+`OwSUOLfNrWBb~2!Mgw19Ka8S- zB18TKg}??e97EEo37g0GQ8b8(fP-wc<&B76$xSFrC2Y)FAifgDmMPB@ju=I5n3$Kh zkY{McgD~dVX#c2r_v;rVvovnD52Hw+GU+ie=O)kT(wq)Q9w*D#1v~`jk_wkCjBV8Y zxwZZl-!l&kEgZaltS&K@4e4a29b7e&t#~N#m?J0gGNLiZNyokukUBC}L;%5gDd&*0 zZvTXLUkCnvh13{2ZQXK9<+Bf*8~fP=VryUj=^OH8z`B&k%k$38uSqJQy!^^`g{{~~ zdh3?l{r7Z|-8%*KR#sD2s~$ldeeQi1+#jD`_>jDnEKW0jtO1Wg-%f$9NthH#Vlr|H z)6tAbR?zjZFR#|GI!OOqUM|Wq07I7o&B%29%*p0J|57ozT+eih;Z7^jk+qzXwEwcc zv|NtYr;Bxqsy0*Wq^e8VT8&KH_Rco?&z9bQz4-i7&B@El)l9=bY%TVW_$8mASDmI! z1|`T_a;j$Wz;?XQm}xIXm+R5&J$GjBy(^KMz_rLdL|fWqOADA9280pd7(}9C%~NW4 zTT9nfEs#l>@{ORRxlxNe`4g)p@er7L8Y@QOfIfjl_LD$lP`m=IaUP>Y^5Y>&J^A(q zZZCJl3UYtBZl0*qS>XA;)F2^Gms_0cD60wI3uQ*_LK%T@fTDp-9N_Itv-^{I>yrZr zLFrh?0XI;$B#3Kce&t`AU<{i90+Q938hNxYR!19nW5!EVuCOYLK1A9o6zJZS#!lrC{Hm$pLv>%YYC174p;@XXoFa;_whSM zA@R&cPt8WpL~}Etj6B1qjUl_|n-k5{;5Eur>b?Qb{!5FW%*6!sqroe_L&s-c2N9}4 z(w@+ULYb*7-K}66#DyH_hpN=(5dLv1WKISp95Z*C>3Jqg7~)rTPyQ5iVm?2OxQyE# zW$v5=E)d#;!*-(Hj1;RLG{W5NQQ!gN0lJ|zIBd6*vHSwVfwAZWr7$RIbuw~#KGuh2 z(k4}$AwTKM9AqyP%6VONaMH-^{_w+hS{v4TK6rLiKIl1EYg)}#qSlCclHE_XFtpQX zNra502~Uaa4sWnwFFC+GNC=C9VSp?-GLWInkcTTcz=`U0`92{6pO>dU|miVJ}y8tMT*@Cn;d;_Lw>Y z5g|E`;;^*o==pHgovkcV0eVs+l}fN$kIcs8=>^IX4MzkG904_9PMlXq{*B-G^}qVp z|K{KMSGWDp`^1LK3APMn86o9O>+ zqK^Zc6DOg~@z6!daq{5*7r;JFB3r;T+$zF@6!SU%vwuRNU?$2K!YmP3^9zKP+SY}I zQ&donlI*A!q-b1WV8ut|ZZ8&&f(Uf}ba%f@rDTx+J2D;ZT>x_uY{YWi@7qGyjD{~c z=p?9}77`aQV5fo6m=SH4qzBKcO|QNtnNV{ATxEA|Q?8b`k4dt6a|2@_up6`QGK|H- zkFZpBAI*I&vEH|1Lo9O-3N%~qt z;pLxj%*5)gRHH>KmYp3M&9KiJ0Q~j2fPf$Qt;+~KU|o*n#;`W@jn156b<&tIHS~(j z$+DlU5}Dm147R|w2rlxki85FiM3vlZM4Ph%6?}EiHFD$9V`< zxT4$*pg~ghWR7bT0 zpyXEqI&ndVKu`#u02I$pt**IO6AB_^s6cv%q2XMaTsb2Tc-hXTZEDS+J8==Nh!J*C zrGx}%P^fyDHS;1@F%UtV9u#E~=9nyJ2z)?24rtF+=mlcRus0o%ho!*HAR(}eJ29Fn zO3nyn=CMHXH@?c~^pALH$pO7}WW%;8k~E#**o+AF!fs)bDJXkzMG~?_0dj&LV4~jX zLl^n#f-~fOePR|mK?pb!&rOU455o!ZC7c~wh@U?*|K7QU_aoU+^$4h3mz78x`AKRC z%YG}Rn!Hj&pqIrV<8&~_6c7bn0pnOm&YtgOxq~LZV++ zm+g~EoS{!WU#SOIOANo0omOw~5FsZ?_H?ew;&O}`k>U<$M?ruR1qt(tWX7$cD_4t^ z8-aQ=1W@L@-G;IBB`3V^jdx!CZ@>NS-&=Pa`uiJC{gc}+L;u6>OZ@roADvzQW@5t! znROqeZ}}j-?t{#>kINhP<~Z)5E&CD=91T2h#DD)`FU0ZVC+7f;(3=DEZx6b@n92Xa zUz<>bH$VHI6!YnSCyxDG&;P++mx@l@Jahu};n5V&I(@`KHK-7oDMQ2lBk4+@vy@4d zVo`78u2$si00B2#pn%?(TWXw>xvR8@rS(Ut0pT377UH`^?H;?@vy;+Kd(7emS#adwr}AeGBC8 zq-u>MI0=>z@%e?l{jQH7P~fG-0~cH$4SGH^CqLGOr5?gAsl7%5Uo6DIACtQDB@>jp ztKIEnTg_Ob9s$NNq71sSwN>r%sm#tD@(tpbo@s@~(y94ILpJclIB<+&)vL`QQYKe% zEqylIv2<<5UzrcQ{(NfPdiO`4&nByddaf&?rDXZazQj9slKaiQE%^*CS(Z?O-C$Mp z&q1}}tv20_j;tHO^U_kh*qq5c{}?bdf8lfa#&H9EU$arBQ>=Je&2HhV4kHH?aBZ(0 zPlM@U>;tI++Q{^HIDU@X5Q#u?1UQ<3(WfF5reUxVxf%GvPneqCLV_Q906>#_;8T{$ zG9y?j=c#}>#`I+hX0o7}pgblrXr3-w`w5R8a;-e1vYMEYK<#z{V*umAD&zXBD~xh| zGqDy~ZZt17JAa~Q)CA95?)*uW4%<+-rQ?kaxk|uaJStE3AEEXI7a|h{6Ovi$fna8G zIyxH7dn0*owjz6rkXcE+bePCbGa}dpEi))xscNPpr|AI%!=E(cUkpj_SrZg+cx0|W zp+3}vBCwV~X4q!(Ym%6yk(>U>bOPz21+%3b#}HaOGym?O=Rl$A#sWE`Ex~z2bCd!< zL~W+bytr0!L(PZrPy_H2{w4ePWXI&IFy_N(%$M+u7Scrl#I&Ikq9m3;L}S*(ccSxL z{5&mH?*LrmM+t=1gR2k-5sgde3OB*PGPMxGA>?_i0ct~bB8i@w>(x@>h7Tf4E3Zg>1&lv(oNU&*tz)OBxcR!NKAQy z0l*EiQrpAn5Fmc1cw#no4w#5WoX`1TAzW_%2_ZTZ0X}2;t0C!X!tc-;<_bP0`l(4{ z+cv49A+fYh5*xGEcp!#=$sT(H2s#le?a`eE2PH;H6sMgTG*gjJ`v5wZD!%N;54A$F z&nS#x5_Uf{U}`uQARd+Jpfp3>>Mu7Z7$6iN5bO#Q<#MiNM0Imm!hh)s1H;AaL2V)k zBYbCvHZi)S2D4ovp?K0{8IU^R&e?;~Z0tOt6}f>77E_mt^;Dys1vHdu*S*&aUPNw_ z;ejVlRsYFtg9`qBXM3N5zkjgh?7!Z1ar=X_+a8(U_UOXaCl@zA=iBcg`!w`#Q8YsYC?k)686wevO|*+{Tq-p9nVh)=#)jfua#xiB>2aE(&g@Jb3G(c zv_ruuw|%dgl@S~CBLOF4X4Vq7u{1CDfs9kR*xQ7#M!ny8uTJ*0}Ubf(!!%K1RYtEAbSpeo& z)8$42m%zcCzuHu)c?0Q7dc(p=PTywS#_T}$_FMB0J+N$+TSy6oS~y*n-RCF6$G~}) z+y?~wxjw$+{#b$F>DhP8z2IwNwFz~SjgSa~CGWm7anEh8`N8p6 zaU|M^6tWc7%yFq5%YFQi`^@uLIgBZvAOjq%%Zd2}t$dcFIg1;ZJ7Tiya%22FHe`M9 zQl;u^FGV}DQ&bpi$0dpUWU^$mU=&9WwU$)g#Kc- zC3%0-Ss&ko07+a(hdL3PIHRJ5id7HHFUt4*j@gxyvnA@|fJy^p(c873%vMRwX4G%K zscMUhEU3m{x3o#~CB(e!e6K{TA<|)%bTth1<%vxC*Vhho z&tx=CVAVd!-=qqVt4bA~;T)F8n&rAr6ElBeV^|b^&b2x&p%V+#Y5}eYLki=R&(*}# z&{wBru)8TRurz`uJ*!D5E~g(Ao$^2iwC7tJ#d9DP_BdNT2kEPwAh`4uLe9Q4Z!}=W#AhUhxBrMCLHyO32D$tDT7D zWT0}xk5mzb69Wy&(-iUsJvBFmlr6hRHk!0J&^D86EkBPBzGr>^`R@fewpdDsG0K`KPGGat`O8922!M_rDFbq1! zs^#+FF(9>b^^W)eT!RN)+=WT%5IV#dC}P3=Oo3+d#)El^kq*U?jj88ra?C*|H)nnF zNUgB4KZShULN-C9mY}6sA(IUn@f~dd-N>+Mz(D94U%#xL4Loz;p9KLb?~3ve&t`>Gx{H%c5iwqwB;G^_Qza1 z9&zn>Xs-L2jYnNOA6wk{m|MQR@yNoChv&CHG$%Xr{cr{#xbfxi`nM8J;>@O>1~>jJ zyzRZ*?Jvat`@a-XoTm`*-~C<}_Cde!-f0P`Y(F=81gai6qNL;`Zxyp9f9vTkFSAU{;*%t|cli;)y z2=k!AByDl5CLwxh$FTujf&23i?o8Z(bF&U|-Nw#Jj4t(a$Eq~t^S;=URvLOa*4xt_ zf`1C9ka?*;61frV7Hnvqmt>VjL)9(2*YUk{)@mu&2Jaq$z#77c__HN2WQdmPmYnlU9HOd?9m9n)l7 zMu$+a!VB7zzW5})Wpnx9`O|5}ML>)pH4;fus#oJs>O(F)^^WF=0Ky%=$6Nj~=klLh(A z37{>Jx%ZCD?R%Cik$u0dD*9I9>%io*)h9DD+srRiYHkzNY3$E95ELY(VIT} zTW$JEt+{M@9=#Zx(O0T@XsmCr5)J8=dC@pqbk%CI5wWo-+0caE6indxBEU}Ec6&}T z3&hJra0BA9trsT|i?MYaPkk6GS2J)jOeb_JLN@3e5KmT?9J%tX4kzj59KaZ zIjQI2ht$ijdR_@t0?RmHPkS z$_+_=^gzh-lTgh~KrWe%$md)MkzAE2&oc#5DN?F7LR#!{o(s8(VuL~D_Oy8!f()mF z(iKL6*4*+@xN+hIb3rvs=jw81*>M+4C#$s7?ivOvlfY^+Wufjh-*=7?lriQ^X`X@9 zk}*pfaIlz?S9xSy^MP8<04^93x?LP3I(jrU@p1?M5fCv@BjmLe*U8B+eif ziFYeE{uo783QKduJEjK2grXmNaB8#B zilQ%P57?f4O!`E67>{k?_z3;TPvO(_OnokLHoGAb6@BKlUr-dYMzH*eTEWelvz3TK zIGrbXi2?xJIcy&El*nm{G%kcgyRo!4hLkDI<;-26#gsho06(qBmBqu4kD7hQls%Zi z^=!O_S|K`g&UZC2G(BJ{I%S_V1Y?AEgby-f7R<;gB1Fnbj32SAwnis0cTKd;;cR9& zpwgR-4HO&l8gI|F5OT(wh8(M>STBYe&UsV?XbLTW{O_xjxALeiUsJ7?r{O;G&yWh;-y0>!Mf%a_&+qdp-?D?>~`~A}Px6_+n z3U7JVx9#D1ARriV`;X?f|7cbY3@9`wXSP2q@bR|)aQgrCpA~GtXVc&LzZIrG8bYLi zExZO($8iuQLc{OWwJ|D~SKG$ODPZtiW<+9Yb+VnM3@XEN=40~3aPo_aOC^Re=&_i0 z&0{-A4{@HX!Y~PxW2|ms`e68_M^YQtM;^Ls`q(Ra zA@KyDHWfLAck~pclVRCSj3i4yz*_;n1XV)4Q+kwYwtSRuB?cuRU$^oH_jW41IWbiO zBd$x0N=rF!_6PT*c5k=OP!iGD6h`S$^yljt2 zv+}t&YEwrzn2nt$A`p_8rpZZ%bLL@B+x}piaf9ihY;7t#e$rZZOW|kFalX|FrAjl^ z<|1|pi6Yukp<2jY<;p=pSMcW^>(1yl>5Ti z9Jv{d=;CX!D%%&+r}*}&`y)t|A@EOz)?<80*Oo*$#`efzwo;rV)lYF2^aCV9O`uXc z^4cPm2N^4FU0&tSidk$RLeZXqw2cy@%R=c&^ubyLRhalivQgxXh}8USqCF6S+3^#W z58Dhx8xkZ#(1QkUC42KTI9I_=hR-Zov-62jcWNe(ootxhn3y$!Qg4J+wHf*$6EH_I z1efEctdcjIMyo5OUT>DWu584p+PnXo%hF zu}w@$g~J?c&2Y07Lp74ToAQE={Awy6c#!vGJ94KRjq9V_h$4{}pb5{!EGz`UdQz8Y zCOw;-sG6+^Kp%!%ooJysL-oS1;9X_jCbP&FAy3=4X{Z}f5WSIg2wtnI`NP00z+W&k zLsp>F0T{Uw{Uiw@uihrciRcjIM`3`3aeUI4f;I?|2GUos4bZ&L8bl+`$FTg*|1iCC zdpkLAORv>R%*ABg4#klVNQ&SIREe$PJ6wx2=rC7uXG#mhj@LmnI-?!@dgT##S>^;r zPe)`A6yxLF#!4=8`v#LkbU+q(CK?dv0b7U~)hJ6!$eFo2a{x&idq4;bhY+x2gR5jB zEJET!JdWE+8%ZLa${YBL{iQRow)8V?>F8jue2d;ff$2pZQ5&o{gS0WplUe zx0~6-T%bzBFOT}PLY~y5H#wXxEz~AHcO8FNdtAyNhR1TnT>pHm*fEE zQHRO|Awo}yhQ{)Nn}}=3|Ao)or0%&8Vq8K~ zkBVV0oV~UQpCUi7-FMzf{_ghk3jY4+G53bI^BdkN?ATvhzc;gfZx-6}QPJLJc}?2& zNqzIa;^q(Yo8QfBd^NJ=8SmC7+*_Vr-26gd<7=_?Z_4`LrniziUXE{m*0|GF<9kk4}J9JQiD0?dvOByuw=VLBr+lsyZ6A|;uCFRyrZmf{j{>fJ|6 zZ$z}m2-n2lqrqeDL?6f)QdLr5VB6TUc~(Rohky;PMa8NeGP1GxUWfXH2#>=@By}2t zBm!tIvw3z>ttCho`$RZ)4=8)ab>SsO& z;?$1q=a}T-iVw_0P7V7$uT?{tf_o}_;?(S0{jPnA{4Ti<^eyZ=H~+!;g%3D+a`vtB z3$nvAhH}YsaL_B8q(cZA9out+!+3s*{QCc=?N4JQySDv4kZ3&gL<{2!gCHMymxI zLfd#~L2bxZx6}>8ZP_hLPi{Z=6J+_aSo6f0yd>}Ca5-MydEgy5lT{>(^Hg(HR#xRa zj}bXUWX$tC$B7}c*g*f*UXeRbMP?Ow~P@D-GXN@GHU@L696kK9H-NjQ|l)gP@T{s_n!I zPyZl)-^td(^?G|F+?WbBCd!Unn^@0P!GF2B?8o6OU#X9t{>D5Kr5svPfQ2OKP`O12 zFBk%8D!^1Hf>u-F34aCwhJC1^oXiugz z@Lg_sAp@->C(=cKP+r?`C6t?_(#6d740hm~sh}WB&I11hvJ)CX=o4r~NCGaSN|2Do zT>7Vg(P=VA)Wl>%`QE)CklKJYAdwR{X=Z;_;#X`y=Psh&zVHnplR$PnR-D83fEVZs zK@pXZ7Aq|bTd*A^mI7R?3+IHO8c zUxkOW>`n=)BmE2*0%am$^Nj7e@UxF*?mH1$y$mNC>Cti{;7Q3_?-&<9VlJ2&Lc{WF zP6(YcQ^d&Z@Cb}El$%mk83K?R&QCL6ohe6%Fknq8Ob`zUQW-#}j0+ivZ_KqLccUU$ zEh^|gQkX#zR+z{ZV1e1gJbsP2;;?7|HKCDIN$$5HXmGAgMRcgcDFL;qF$gbcc}?ym zzfA72zq%JNtW_v6Q*07-(?8Rp{s9GI34N|A8aKE6G8gqYRL{X+c6KE(94k(@g5&FT49^hZMRC|lJ)gacFL_;6e_FuUAf)J9^8`sw{*Ij=s8&yHVn8)L`?0v7`wWXyiT&m5~60~Otef_=uyu?cXmC}O-r#+Z(?FP zbn%A&{KKDx_n*%1e>?O4d}=|F-+yu6FtG2SO?>m*f_hWfc@0YL4 zEq~Yx9mre*0ug|Sp?4H8eI|ma(FLJNXMz22oP*f2Ei4=DLbIJmO8WHg4T`2ZYS6-NJw#RMJWeiWe3_*~#y8&maDoudet~H{!(^O__SoHgHqp>gT|Y zwy&2_sK7YI-Pq~m`3m}hV|(yh3D@sA!<@uvA)(0&gLI^P%cS-ea30X4P^AJJRp4dWR9iA zTBRwsa5WrRE5*3Ukr>u;e82(`ayjSH9^(V7lICvQE$S42U(|)=zNhrwJT;#;9&GXMi4)$ zAh;7!Xhj1WbBY99fv~;N{pk@ZJW2oC6)LF|r^5y?Ir(ZX%Tn#wUpbDT_>7Jif)DDs z90b0gWe_l_i?JxUnFSGFhA=k*0>$8#;ZPYOB`oUOhdEMk-I@*a`a$w~OKm1vYp*pr z8<-Gjo(v5fM^*r@QU50-R4Ug*aTeR7TVoRPf)-{cn2l7?f^0Sj$&VBrRDYpQ( zFb|;IHt(-+7Fj8g=QhTe)Yh))D8g2qG6io!UfYwYEMr>yN(tvSgFOjNF%SaeGg=1t zVqoU;1@}^-C43V@jhDdOy|)Q4YdYavEC*2l+))a!6%$n(Lx%V}|535+M`v|9?IGilRe?aH6*|Nt2<-f?%?{)rdLViH@buJs zGIZ<;9<6+8?M<{%1FJex6Iwr_D?+;7Dr3Q)aloEcwA*q6I!^SRz#onpFV6bYH>j%n ze%ej>A3m17@5E-N2hqSH_9y5jvgj1V^Lv};?fi5HB3RHEp~MPPdGmH^Lz&F}drH52 zS>N`CEO3LGBlE;1sCq-$vAOVt5&tKv$${bZGlMIqhPEI6P`bGE#;4Y|0W^w-zou`FQTp2cm12)|1!Jx{38v z(x1qqdChRM8qTgv%m)QJDE6u~W4V$%yb0Ugx?DP;9|Qv1+JFRHY?P*AviP@E-6(zj zSZ(bjyEz@}nDH%pE_PJ$AHwN?!HLPh_K8ON2n7w$f~G zzyL9t^x!kE$+AO0cr^hX6DNLo6IaM9-OYHj8_3q@)CV9M=$eP1v5o*T(170P%~&Qy zd7N8sNV*-tk{udgRBmi=?s|Fz|8X~ipSpqITjl{VwR<8vkpiH@aSlR!fEnBy4?%!5 zQ+z|@C14S%fK9MnY09948=IdZxoOflIhaVt=r}EAtlb*ZO)^1Q7RpVbYhnj+YB4IS zBRfwZngvlvXAK)71WLVz)l< z%N%pnRp!g-j7YjA_F*1Tb6dCavzoX;u%-dk4qr8ritfS}YRwSt0D@#Xe9%526$sRB zB^vcevk^gM{>(_B-iuS1G}&}9dT}{+S#Hnue_E)mGD@bhgh`C}de0j&78BIPJiS$) zs9LH=eHnS$y6=iGRSoBIa4~j;&fyjUJAyUwDdq*pGf(?UQlS|iP!`>SpXeF>kz4r8 zFEji0tuII$K{hFsWCDPKUr=VC3!TE|mf3=!EkD(pAK(2EV>D0 zAsjknM8@@{c}xAwh&3nFY(=pjPQ;@*$bZH~IH}U2 z`|fy4`rM40a19Db1{Hp~358Jl6AHza`g(wvG9m@4YQ3R=gDD^r0tM4C+F3`r#&qTB zCCC~B)ZHYRNio)~_=+Dt*C}`~QRCD*K@ZZ>0>^is3rR%XOuMD3`*FCrr2%YA1oz1F zST9D4TJ2Zn%t%?KhZXZOVyZG^i(qj; z92TL`t&Vto{p`b^g%7=7KKZ_L;zi&8@c5h}zkhh&@RZXti6tu3*Tic?@{jfcvT5*pbPHX%}K8~*E8+F*EAXl`O61YV?M`!P$ry@#35 z6j4zEk+}(##>5SbffLnYD-JvpneT)mP&y|fcKFw*;z?Z7A=Xoa{`7TUy8r!zwqGGn+`=99nl!Vz|bS0km*b1u<<22EjMqO z6d{hEv?UgNWN9XzpPCJQW!DexKwIUF z%=f-mdG*&fom*~(wM2me0@cq9580pkh^kIEHbfl2RaEHyRVnlE{rMk!f3vW|nA6c0 zhseGEfy`)i`<@I?&K1ua=9;fu0#@*cVazT-|PLeXUJ-xL% znN~;CtfOdGnk|%?t&}HI_vNbJY^CcHXBrcq>!2`zUt!Z2P_j5*s(Z;L*aVsuZVk2r zxDcf14bC@ntNCYskU6-&^2Pf%%@JlqOWhGrqVV?RR82Wp5)Ht4tI5G=VSp%M~#L{_L-o zBKav4G!q(}3|?H04^^76d_4v%V7@?>33IDTvb;!bSEV@X%5KJ}i3qDQ(cnT%C;y=} zCc%$D;iI$v80szN=KN?P$;z3VAt&K)lb~2JD)8z#ZPAj=Z z72fa>H^JWsic=`JFk1K_sly2f11ageb|*!GqZ%{wrEH@Ol1E~sf2@Te0GD7gg4%ra zvNw4>l$(Sl?G05Do(9)WUt5(uo3KFH8Mv}M;`?OIJnTmQ;9WXV(a{6siC_1p<$f1b zrm0j3!7_`LgydZlL&vddP#}m6laRW_%)-oTgnWa1h_G<3PQ)kxUvaw0)9J$p3qN}? zk(i(68%EAoeclsR>AC08rA5wV zP&!e=-j;^E#3))=+sMo@k!mAM65Ytx=912QvbmbA`vHXJr2-m57@ZM;^=VUhQyY*w z;TFPYO@})^1@+Z?Mq*!L8>oq2VZ&)f;0;%*nU@}^McLEotzd3`u%`nYDXSD}pa{Kq ztv^Ky@?e=tM!T~8fL+KAe7M<7R<6F${o5KifF+jOYLI(71xXqffuKurM+?J?sh1-P{sgx8%{u zMHrqp#Vr9Dqa}`k8|p3DI0l$&#jb=SOouGG?M;*UuBC=?x4wzH*|S6-A{qefY)eF~ zqaYA(0x!6Liy1_C83s5`E@0xSXgCM0sz|XwMA2tU(nfYv-GR$wH}V1#RQ6z-AuQbd zRzeq;1U=YT*GE`2e4@v`;}D9bEL@6R(FIz6dJNAc6nIT3j^vRxc5W6XcSHw~8j_Xd z<~GiOm??A7U%{I8xSJ4&dOd*=&rOx)^7)1A(~l?bJ-R&jwkgr^-#t(eRB4j?WZ_?u z&aKPgcrlLOXU0l*wOf0DP^A_ncy=mTk_#@y`s$u=wU4TAypq{}Pvc4ttXL8qOX7!> z9f@>Wao|yR`x(PN%2$^QH9(l0sHWg1Cdt9l?|+#+d}uSdQ>JWg<=WjmQc%NU=6Wvw zXG3SNdf!plXK8Tdy-Uk)4R}x8Sk*=1St-~3niVQd1Nck`hSf?f zoGHp0gFIO&3kJzRp}d%CGLRD<%f0pRW*sO1u98X-Ctpck2bWizm6`B4qC7d3nbLrB zGbIl|MC?FJA=Qe^<(_;jd*rY)b(P*^JC9DX+Ft2w#wp^lX3h;|r!Zo82Eb7zbY=I> zRruF+a{4bfe9_X}Vr*z3dSN3o3cLe$5Roxxlj;&U2Kfe)r5`xt1F;W}rGX%r?fM%@ zLVeb$gpKJc5yPpI;O(#{r9fZb$@nt-aH$tC&EdzAbAvS39{?y5q`po^p;s! zfHawmv|*#$LR=ntRYQ_k0G==r0W3}+)};~hA4td|BtRHk;fz=gSb;#YGJ+%Iz_Rqv&TR$@?gfkxnQcD6x6n1TZ zR6&@AJtAPW5nyx-6`;unxhmwymWmp7RXczKM4?MlNQ|>A@}BU19Qf%E(+Bt0hR^a7 zCl(sncyTRJTFF*}jdrTlA-hu^$P%4dr9;=rh9hsvM*avbke$HfjCSJ4BwhAo%>FW% zD3WZpF-bx|1L zZVOR)(X(PBC2S^9TEKeYN*Sr~d%v-CmTDo89k=^5F*QO22eCk+7I1L)j$jaS zCIq2e{v&D(&%JDc;+T%*=MIED>nZ@Gw!sH1GhLC}5~vUW7Rllw8pJqhZ-ijV5?R<2 z-MJ%xn|A-ij4F*lthjdY{Sx5s!0)5SpIZJmFRUx_`+NW8zaAOAGCe!8usniB^c1WV zbb@U&9RnPDuYSg`Vbv`DNvH{$oq%*kQ=tosv3?B1iQqZpsi!O9r+YF_Z@5D^KW+P5 zG`psA?sSlPV;HNZ0ixrG>K(gP(J8sFhf3}+G0Hs_aR4o&Yho!s<*F+%^Bq;To8SZy zF*}9qyNL#RL1uReq=a`6U1`8{;7xAMHdxS`xUQ&oH!=6+_-MXf6tfY3k$dr1x9{@A zq3mS$B<5Z>?+C>K*FXGq=I*=KPyGzZBaOb65dF*Ii!AxeqAw6jg=uY!(d81{tq5D` zPAh+F$*bX9f9Z1v+DxzJAATVB@B>}fQki=ZG`>q@ODS`YZ17D5$J{w$p zFHxNDZeL81MMqPiB6=)-)oia%;L|wRZbYi`z{fq+Pu?M>1TsSt8($FD_^I9uj`=?x z+xQ&&h^~*Og5%f_4r60ztCb)z(7C*77KkP|IL2qK-Jw*aFco*YoB5lYsq*<>mj_;z zZl#F79L>*?J^@BJ2CmK!q-Tr(fyn7C@>cJv3Lk3i)$G~@q*QqBsjX6Avm;oo=qxlk z>rN*KlGBnMdo}l;UB-Kf%OqoaaRkp{EPr}@J+(kg2c;ofA}k?;mWYTcb6jo=j}LGn z3Q86ih?_KHYP!JrT?qbx9d0LFF|XfH`v#TTr8RoqZ8O-$o+eI$PnH)ApR&cEraE$i zfiiNny4{IU_;!r&=~nAh{&yRZ($L$HGf$STy;iyYW_9#*x8UhBNLs?4epZts+3>+O zP?9Makiln62qj`pd@eUOlEvjhePcB}AIQq1A=&E2ROmdV0!B`r;|TUf?SZ2CYK(`1 zq?fsY>GWnJBN57zkVoO9)H5rl{C9K6XYv6pQ8$hCEG04}NEcKT%uNE4rbCq1S9J$C zJ&}lvYKWmkJ+d9DCusUoBf+dZ(u;V3qzr94M9x^ISqZqpXUq&f?Vt=7FV4X{AM|RV z@M-Q$MNrtehJFI~i0_k8-=~q>^q3#_d|zMB?IvQeSy7XXuWsEwLx_~D*R?^4xw03| z*HXjeT90|x2%Ix6q;mwv08QWu^G3+zEoB(~Q5hc=2415OFFyZNN2=CjvJ#$^E8Uk= zn>WpMx6RE=xxP_t1S9#`xyY4VjrvE*HYw;U%UB(_nF&hWyJ=qKT%}BkSDjq5Rj4*Y ziP91fkT~9K<;_LjB#J;^`q-IHim!$%xpNUgHCq{fuC@>rwpCwl!jg$j^1)n9!#?@E zV-h!I`)=*Fj}ViSAwBaTk?g9&xJZ@89M4sE_G3q?lo|3e=x!n;VC5P% zua1CY0vRpCYjP7+zrk1{?%CXjD_N&TV#r) zESyoD7Z=;UQ72c&oSb~ClLl?rDXZo55jw>$+zYe_&<xBo&So5romYSF-i?U;5#=T{fnDA7dDRS)4vcEl14BH{=QcbMYo*zbD&_$^pA| zPkB!wN)U6#S3f0pZ~XL!(`#SomGr)5lJQNhZ?&ix)6GsnudIs9&007g5UJLIeYE#I zf7qha4kt@<8Y#XLZKms=zn9s!ukudsIp5v1wUu*&KYYV!?rc`lM}^vI--TwTLH@=p z^ed-#6Q0b0{pGjio;FJg{+Mt$J3k#buTP;vOsdt1E=Mm7t;zm>_TsOLWFwf_(AkF5 ziV}+d zAX|}V9jsl#CpZI*P;8O2;e0(cL~m5ssp?F#E%8+Dp6+~qhwzkuhQ5c&{H-M z3K>yuSu^c1V@)dhnVtdA$`WuYQ})2Kh+Qv#H$s~QkK?~yz43Nw;{A=>Y`x{bxtVCJ zUdmngRc-XWOnDjkc;bVggqmv;8B)TE**T0TkSZ;>r_9ud_%MJ=gE?j+@+2U~VGn$R z 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 z zkaQ$`uEl|6n^Pj9_FBeS1;Y@%JLKFEzWIU_U>-N`Y|$NZhBy2Ox2?5gQyy>+k8>K8 zlcqzLjlQmU5^~oOeNhrm$FJ3$sjm49ox*_fu$J?de>#+Ycz1f=qs8yPs1-u>7C}vx zd$h2U;yjHkL^@xQK{B`x3WYI&osz%s?jKSQJv2T1gOe*wX_TlE$uHqAwpk@wklVgM z0Lp_)dtsyG->8Mi7lt;@r8JPey&Rrii(dS*pdr zJ%oc{Sa6IGX_nTo9-4~ergP;Ly{)cZn+RN3O%JZhrhRwJ*HJ3G!8{2Eb+H%{9c&ScAtfbUAfo51vO``lLn0_|Y%xYO zr=8MxG(U~d2 z7M71*>+{HjWDF&1j1pT>x#2v_?CG78_zX ztwjs+F?d9wNdO5tNia|Xp8y0nf`wow1W3Gs3AYn~$VW**U*f>MwtWhah$l?`==ew;9r`8thM6V&`tm8H%Hy_ zNCrH2&Vw3_2!sGBldlGB6wFs$sFhSn+f<@!^;sqWRoVBX^LV8thKZ|^%~;FS1e(7_ zzp_N_EN>}YS}E4U`IF9DO}&!T6SKz=@KePr&;x!DDb?wV z^Vp|dEx_IM4POLEMaqB`wnry%Nq#_$Ww17=^oushHWRpD(G$n-q89WPJ5M1@D z&HSD^-q`on>fYZjKXIZ-=J)Z98X8x@qOvtvLe8|-IybQ73BPu_a`{y1{`*T`eY{Z< zL&7zP#M%*rpQ43eW*ntst6g_I??JP(L;vDm{I4|mJ96af*_ok4yffuMAT@LM$w|0p z9gP5k9Uw~LhKa&fD&{n4dj=_qZ#wXtia05wKu4GgxCGAFtJP+X5RL{X{6D+meHd`5 z?$al6v0-8*VD2;tx}ZT+sp%TW$_BY(q9`RX3A-c#d6Gk5vere{s&~sdS~id<&%`5D zr;S1Ug%h9^X9ViOLn`_+V@zmqJ^I38@dAZq^g_VZ_oFRId9xoJg$a=uA(jm05MtVE z$>!#BBT&hFPh6`Q%iLm8&LGvz{o^d*V&2p(TZ=BJ$N<4}wQ9<9bO3SiNf@>Jg?fv_<<4=Sv{zb!T2+ym^GqN6k{+5dNFoGEJ>be=qG2wM!m_Q zAtw);)SVbyG`oyaiy_m#Di3&Vo1_OjAS$368nMVo?bJh%4SD{+v(WA$yr|_Sr%qg1=y}DK7`WY7Wt5U(j8HjXa^RcTuwTf-z0Ix zx@;esAoJ6eKYTKG_@%n5$A;A|V!S$VJW9{#xFpkRg_mRc?skXg?Sy&gO`{s0w4cj>s=1F;vYmQTK@F%i(4o}sU5UpYPWK&^5t%_DQhYmBaDzC=5a@(JZ9*o-2HtTsl#yK|8})EK zIv(ix7;S={I;V#*T0nFg>yk@hnbn5O0aR9Mz5ME5NDR`5lv)T-t;MbsY5_(eIBv#E zF$993XqilxPzRcGU<<>cQ7bdrP$09AsRjT+Dw+bRje4*h8LNyQFI@bnGJbMBCpQqd zMB^5YwPf|y;dW%C!<)l+=pFtU9rCZ#eGHt6^s9!4R8s|cB?SrVCWVAXB#(B8KrkjP zm>7_+c&y@}QU9fdSZ5bWsv}-&{P-rhV5#nJwqv0ju(mW29GDFC6C0FgS|iJ+Ypf_* zaQV{ndP5w1Ksa~@(N4QY_}V6}moCSqLUNmixPoT&{C1*upaT#<=F-=;by-Wy>-71D zPDL|nezO(V`bH;nVrXjKoG1HCmzEF_swDL0%~!wZC~3B6r7*+6_PWv(ON0quy0e9( zC6%q^&^fN<_<#yQX)E(Py|(|;xO~#>)8vz<+AsXv%vEH2AOjk*OIf9vYj0+LN&*74 zQ1^jNC_xR5`r9Bji_#W34AHlD_HDrQx82@{pp~-u9Pk>0y3H&a6tZm|AMrZ zE98Lir|5Mxwb!Zq)fAFg5_PkhwB0%ef`wjHNN1A}s@3t-c`U z8@RV!m{Fnt!IDv6A+lxHW}B!UQOJ!0*#c8`=hyS3^2AXq=Xx{DbeZ#`%cmwLj<^oJ z6M5$GWi7*{5t!>v(Z2O&U@g!;Ef~o@XSWO z`;L{95c_sfD`87GPNFDJ=xe?UsmB38!OYhF1xnaFgkPWtgzQdEF+Q}G9m2ui84>+5X8`TZ3gwijxG+bK3xIk|Mq8(&nduM2X6;`T$Em1&ii9y-PEktX!%vR=iqP73aG@0MNw>(cB zZ@h4}6->*dWn&{P`_?wI)uwC}X)7wBL98MZ97#O!7}0bs-r3=thz_1Or>qd}X_vL` zO|F&kfAuf_N|V1o{pp?Q>A_%dUN@1!*z#46eSr0EM2HT-B5IBq8WIB%VO6qu$2826 zri?9F_`#&*oy*0@m7AWEi_xnXBrRY?R>fcx5TOEBQX`=S2ps{2=obl~Pyk>sp0#Rv%Y=JyRE8=$;Aw;~ktugsQ3o>7o&$`O@QRxwx zxXhg*P?z9>e<2OcSs{}CS`)yzLp~HRE3A^bQF1kPlSry*91L$^%O>fit-qUhigqL{ z2Y`ZYn-)6>qe>PQEPE1C^+9~IM9PRbCS)fI^LP*iIH}AL6pMaG=aeA6U8|s%QO*QNs=@Rq!^h2T+#*Sjl|_mpZ=9& z11rY{-6ugw@<>L4+|dfy1X|5T20$Dv1{|0Bl_7yn1YI*Xo(yjRT7$~+O|#B!rTj|% z)CiEXTLD2D>|qA7ClM?8Xr{E(HP`VZhvr6qX`gu{Up^%VMt~X&4dMVK)u78?THqJ;;p7qw>f!Y6 zU3QNi%!M|~vQQ!0M$k1;f&73LO!^3*$b%s03;yAa^o6F-4m=PlIM5)SEOy@4R^pO7 zF)SO`)q=&oZ`@apjz=5uQoh-gcgoNd-Pr*`mAVh>Bu#I&qM9+RlO49bk^(x4$x38y zHd~1TtU9!2U@-f`bB*XkGA*lUdeV|X#!hqr2yVB@Yt7?&;N1o>*b~Xh*4CIM)@7N8 zuz_ff%s}28*Q-vY??_C=5FG}LiWg&p0F*#$zhi-Gw|tUzOv*NLs|eF5C90xB-H4Pk zq7;&(_+shG$>5Pct$g>E@4c7ed-tRsxIgmj{*?o7PmUh4UEK1X@t*n=_2vKc$91!@ zA1Zb_W-LFAGBeje)0*4#I1OBX(oet;AJfiiQE>)!MvjJf2V@~Ag6SE)xu zXq(zZAWWpGMHxH42N)S3@&~e9lr3ZT|>BV#HNIu_clkUhawQK8lJiO&3+7~-) zMxwn(lY4gMUU^|X-FX5M_U!N>5?OK%cr(z~9q*h}Ec!qH?0wDr{_3y(%h}oCnd!kq zR<=0J)#MYy?X^sy{x?hh;GZlOnPa!0x(***;81PzwK3cQt8i9ug0Oa9A;fbSfoLFGwSF%6TF(W~>#-Z%{P7Tib9F5TQ9V zK@cO+Do(;Ii4H^%wI!@h1020zIrygD+^2B}Kc#Dxzqy~A#H1%pbqm6@gA)-J$$pR+ zCDF3Ab4J8`38dAz3P~+sVwa^LY#7JXV~9?j8mB>siZr4ItQbZ6UBl-uLjZ5PrVtQk z@CXoZD?>G-qZiUUx}#akFvMT{g-a3?N`dTqZ>4uV)J{kSwH)u4Tj36WM-B^->&x=E zyex$2y%Yi#SjU77-$W5sR&s|^UWl218Q0L!_~Q>ppL}fU)9aLyMRQ)<$5%WC`R959usK zxJt}kW*7*C&L~rB5GfZp5GicN1BQzGF)))4T_*V>i=wG&J+P7(R7XYeI2H6Z~j!J-31_F%w(lhl|oZL>!0BsmnC?lWW zkoGre+%(=r)AG$a0ZquB#8R{66?~O|M}m(hYx1{QMN&Z2wz)#v*&j=ZV)nk6l?k>O zGAS~bXqJ4Dl!D=7UbrRU1e3CsgfIcSy55!B5YqE#kg!*~_H*j~`>Q`6{WE{%lbvI7 z^KmVPY#A^1fmj+1S%cJCO0YER@Y6SQUwlyb;=}w~Z)AS`B=bDydY^2uG}DhXXx3sD?c)Nm{H(oi%b9vD3^kBUBb++^YQ=k_c=}N0@x8fM zU#u_PszzoO7JjCqiOHiA6GwteSKGmv^2zTqPd=W0cz5ZGkD7&5WM$nGBJ)7$z@pPi zg$;wAu!K1QK+LmoE*1FZ%Bz$l4O>dhdN*a`nd z{8ap_vumAs0M6Y10*cIzUmrmGQ3KCp5-&X^Flyl0XbPjAIUF2Jx{_DT~?=|^*<&|ei z{=D9)QX@YaZhA9CGEtc_ZL0+#jUAiiB%X_@5WGmjjC{6=@fT}E1(dNTmB<&HYgxKe z2P8jRTi;qZfY7NsF-WYT@z&;=uBB{g0qf#Goxab|kuhH!Wt?$mJy= zTM@Nl?V|ck7r+@2yVm7^SU~R_B#U$4tz|$7uHyMQXLyC^f)p7S!zG>8uEZI=R|e59 zHe9LunSPKdl5&s~5}=pO%a>Z-EVfBPMqh}Ul!F3rOESb6iYd1=t688Wl^Daf-8qRC z7`VoI;sTzl;>ENy21$&&vo*S)08>}OLH>(BAsOb7#%u0C4`{+Hgw4p;apl9CR435j zi3rLRJ{!yrdz12sGBO-~X(U#dDU@BIlbT?N8p7q6 zpexq!s|R`<%#2~Fq&rL#HLnMx)c8m)N#u#sAPA`>5R7mUJrS3Dk*>%5mnMT(lKB-f z)@F;0L>jC$!xW%*aFc{=CM=&^#0aRu6ujJwlSHe%avmW9^f;kP#2)NOxCc{n#LWQt zbwWG_3P0$tSoh9^u94B|c}x(20&Qzz?(>YrtPYBsp&^uq{T0m@jjXAGx#XrA$q0(+ z^3qaF(s_8(WkMv6?P_7f&Ln_1M2ID0Ms#{!F16$N*I!QWeY7#hG)T7jz!^9Xlf*f= z0y~(3mny5#ygYliSy8q&g-;M!=6{ko1z-U8V~R#241{8^?euvilrBoFg<{8F_MiTA z(vuA2i}mIm2*@zoBnq2pnGz$yH{`&$CBL<5C@*hDk2YH3A>t~ytGpSoR6P6MdM(hX zh1*SmY-i(6awdPKi>;MHJRB`(xK%PMvJ&J(t=oKWM;iCb=c<`PVHE_(@tGg}SC3UL zov1J0DuL7gMp|d#}#j_-bP2*mfCq(c+m;(vR#( zJ^onn!#_4Audl@x*VFEeauDT;K-%$*YG|Y2TTiZVz7b!lMi*+)h2q68a>w5;Ui>k= z=i$t=PuD!-NFZUhI!8w+7Z19Y8TNg^F7c&A)b;z3Z_m%X3M}ieh2hX5@HmQ zLQHpj6wb{Pt7g~VDANfBwG`{q9nid$j-)V#dsn-xv^HukvY>(gDff^G&!dbJwfxMk6yIC2< zB?(E07s+>;GTM}t!gkKy>6T%d8^p*T`Cue?w;GQQpV&u7#2Sn3l5Ck{=4}4-D3|m+ zC#@nNy2hxgjR1D81(b*v#3twTSfi3wnF?NVCiIp_i3;Y6AhNW-xe9>4Pz7_fjXQ}r zMM|L6F%oPK&aDQO;2DBR=V~s7mnknHJ^kxUXGtM8%+v^Vpf7%_^#CoSlxSXd>7tBG z`8K~Jr@xl?i~AF#5H(PP-|2e-c9q9Tv?jNDHW3EZL)e(JL8W#jD9@)pyt@&eqdZyT zjv0uV49GW}^d35G;!r-vmUGL=9@0MgB}X#pjb!AMkp+T}-%34jzwg6WM^{eU@=62( z`-+vN`>Zv468QP4YQ2{lN@%3uY1qD5kB$3O3&FP z*K(qqyM24>=^Qx3gg}4t^+pqWNYz_+Bx+E-7ETma62+hZC| zMqOT9Z8f*w95M4+la5eb8^mw51&AToZzEbl&e#m|0cTRUBe~4IyhL==H+bCFe=IZK z8@_NL^1>6$u~NGp#M2UcA4xv+K=R>TzV}~QIq>%Kj~_0a`bcU1!sp|&JG_B)5At37 zHvZ;|q;axR_|SuyXPzqj@%N=;-D;A8*3%yYlazWAHW%g<9F^YjzR zM;<2c%)an!eX36-z^FZmn`j4*Lln)mjA+3~W}^})9s5o)#iyQVuE_p7;C?JWn<~ov zJ8T=*165n(=$r3$SZQx3B%d~4Zgh?UPa*ZmRwZZ=49HQ6^?0)xVVaHxF$RfD+g3`N z{=w?_$=ez}vkST7uUBp!x!t;B4vkabadfd5?ZeK4*?FB!?MQU3@QOpx7hZ--0;9Ff zce*J8v!VI|u zD8c*(7?(xp%8Dw2@oE7jW>biQ0m2n+itRNbI4`;|P078K6H_sgzbB8@_WpKx@0%-6 ze4l^v)Y@-;UUMa77Zs8Q*n?-2Vs4G-FH-ryH_2TOxu@hi1puH8?Onu4umam&YfI*5 zmh|%aEL1o&fB*geZ%zIldE~*Vss81aQ8Y6P0g$m_$v(27u8E&yj)L~Cj-kZGD z^^lyopK})f(wn^K8WDwa@|Ydd3FNFTphV*x=JBk}%#Taxom!N{PMq^q{&F6bEyp_f z6V|1*lyVi~qio|RtKH@aP9#GMHV$IjR41uo6o3YjC+)*ejXU(>FV+C4g~lmQQ+I<+ zK-G$!v0!!N3@}e4ngi@eI2RnszI|qMa-^pVLzdu>nF%=4iRMO<#7$BQMuY`oa)7ym z4cRkQMXCfF`j>d87E24(kx2xdJ*tK93)>8ql=R+_0_M?zR+RbGPFA;`^^^{NDQ~8K z{YkqV#2FEkxu3A}3KZu_JmfZ`dHOa{kez6h^O?|P2$j(nghJsHO)=y~B~<+U!{mbx zES-Aa*&0NH$f}F0`w&VjKkZH499}rr>UdTKVrtuyCq9?E9_N4L zDs`&k<5STM|zr-z5t)Y{>Uybu3OYSa1zd z5MaWITg$UQ`p&!&{rZ`OiShYlEmSCFD&Ug(vl z{ck@%F@AV-SteVf{&VgmQv#V5cg4kDLL;P`-mBHnbaQp0diH4c%~#XAccEFbOn`&5 zFZ2e&C1MzC=!l3Jn6ydbE(fyXFo2O@Yz&PA4jfpF$sJYBhcXl4te-ZCl$;@f zTaZ`KE|Tj|m;(5q&dLC~naxdMNQ{_p;>9G;E3pAwOdZEbRF4(BU=+?vmBq*n&=SWa zQ(R5SCZ^g{@6v$*_i;VmPUNPl8stDP;LJ*VkdtT}*y-w#k_Z9UrfYf`3-=GC`})&; zgkf9*Y53BT*(g@5%UoKX5+PIrS?SV}ZdKjI0H}`dpk_{|DAeWg2#@3V<9%auX zSrqWW(&eS{Q>WMVf0o$$%KQ@tie!Gzo>>cJv&zZef)I!-jQMAnFL{3c6b1~!U-UU1 z3FsmiLoA76b~0Ko*5nMqrN95;fBK*P&&d4#-rxIs=g%GGr#5Ew7B%U47Y*eKV0nkYkS>zPs=N|5~N z8AD>FT4hIa<|TAwV>|~kuLxZ!)qEH>0%4xRFTydgMqCxF!;hduac(AjmEjPtX@ty! z6rU`xTwBF!bjcjOtApQ-;Dm}A2O&ns&_G&%i1T`KJ5h!#2e)D#LgH&Z8bd{`xvIRg zZ$MjiN+M?A`=o>Pf`wxVqIf*!aHNsDmx=v&dnS?^VlQl-@dwDkmVbUhmOd07%V=8d!pj5_7S*h zRxH_kGeTBsLRZ|W>*jUi&81@ISFH#}#ax0m*AmNwhWOKaQKfE7L;A?vgTIy^2$_?X z+!rs*T$uf=ckzb_{~6t21u>Bk;v7iHE(MV-Fu zy(c^ex1j}KSF0-#4smID&&#|8X3yjN$-+DlrQVd?`#6JY@HYw*CJ`O|A~Z6pF0kfr zbm2_mtNo#Telb}wRP|&kfqXe$DkRGVpf*=cMT$l8zxhNRn5#Dvjb^-34=pDrYBhOd z18U@5g$p0%4!xN9?6J(b_p;MJ7cPF3JN5hgx%cV|7dI;YyX_B5upz%e)I>5Y8$iLt zo9!qgf^!52+iIx%Rqa67fDWqj*Kv$+YO$HjOV6br*^__w_xbnV%KrYf!sqYRBeU6x zFJ4$;f@BLTjWeT&%A`es-g)UBgpt@|I4o5=FAH}fI(c~`{AV+##0Ja&6B}!Z^>(aT z_F^75juiq`FfF_QIIs>+MTSpFoQvuj9x_M2Nx)A$r;7zl|h=dI-zYhE0UtF%By#rc@oIFs0;1(c951%jEWx_S7Iki)d3 zQR{qFnPcYO%Hfdv1(eE-*dftvmU}ZGvb!G7-Ky6udB< zA8l^t8HvI?aBYi0qA&Akls@4DSD=%E@LwdwRm>Q1;X$wmVyLpPt9mWmZfqgULaadY zx9?s5-q)9&JX(A5RQrSL&30QP3c8W0ocaN#Fx#GZ*Qb4&8(yajsybBK@pkq|Bto*fU)dK z^E@#EgM}7aEws=|yTV{bBP|9R%wnLGv?FLGV5JeJdwVcF)2-?0p4v7=?~=BPEEdTs zdQ)Vv=xx!HX_%JD^e!SZG9ttKi1#Am#q-|#cb|)-0R6u6y*PQ}MPwGMB;Z5ljr-0$ z=R2SMf9KwN?lNh}&g=5p!LzdY+72tkj7TwNdXq(dk=Akz(?KWp>KYB1D8yKx) zw1`WYN9o`U3JhfogZFKF)fE0UYAtSkXpd_#Z!VNK49xae@W6Qn!ke%z=4)O)=(kl2 z7(T%s`X|j86u&@pq&d2E<61W{ir!gvvq4@aaOto73qME$#>`FgULL1pC4i8`!N=rl zPkfNbN!F+}diT3*5(nR7*c6le3nzV5y;NV@p1D-I+D^$M<2JKxfPe1fuQ5x{Tx* z6cBaO*!q#POP`)u{P^O^-jnkm0V+|9g7;$08!yaQ1kI3yP6R#fKkEL-F9dL*8JfdT znr*pvz!_X(K5{mY9m7hHGTA7ap9$s0V)+?-6)+2PL`+1CdsJlG?!2rY1;P{B`V0b^4C0*f0H3vh z-$`)3ni>ujE_oAMtQcTT?1*SOY)wnRMO@JB^sMlA@X4qe4`Sb$vk*}_UXs-l~v3)nxDp# z5h>NoYVtB-r%He^RU)Ju@+)soBU+DxJmuOzBYI$e$hvJ1tUJbH5N z)et9A8UH4`_nG4G?#k@Z+UoiG(#g`LFN)v3)>s>GuSi)U95dX;MyA*()LZhEPwlGi zgkwe7b&`pIfxy8CZ9=d;b#fFjXaSe!Iamu`6o$_o2`%wmh zqrt3vrHcH7@6cW1JDU zyj)`XVJ;?Y%2z-%yOY;R>TqH?zcDG>5TSg#M?j#BrQF0o`od&(q_TPIjd4*i(E}!J zc;|A?V;%q|^ovf3X@r^|5-R5+r>Eul?_sP(S60H=N%cP5u<6LXer1n;*E0pc-~De! zJJ`hy?LRoyEi+{P@*txKM+-Eto4*Uq8gwL_;CerrCp)jQ)R z>=0KC%UegXS_Y1H|7vjOCi)2+Cjr&)Vkf{X07DSW1Kdf?s2;`;ELI)KO<@N7s(=r| z0f`Ti0k?fRi*Q7QA(7E7bF{FPo;j)M8`skb+R0*j3JC~ADlU@~=V^~^W2>@$v~4pQ zC2W}3g`j4`rBZ-?$cJy5e9Y_h}=Uh6Qx&OZG!}nJ%op5S9BR>fRrb1>G< zbZ9yr_zuSd`7s~#?N47Os3AV>J)9lQSG`D9S+Rstb)BXx8}K*YjlXRJ171Y$1rH_#mQLh@R6p&Q(lIAEARVCaipU z^I;m2oQ3Uf(rb;Q{_cpTgt!3*NXFXzj%12&S*B+C054|EN%9A&g@OYa+IXQP(aMB= zdxnU>B}5JE7_h~RXd_uc_WT><7{i51HJ=)#$ix(O-S~3mt~;s+zQklJj(l7kcO__& zgz#-d83))A{#hMQx z5G65AEl;7@aBq93$(gnY9ooJn4o$Svjd_5akOV_ znEH)~Ogs$+E@q#3GJV&bSPPQDw1E4TdGTETccgHzKJad113^tu`_e6)KpYSX@G>LG zRm~H^XE(tRSg+!ER8Xq-Kati)-HvP-Bik-c9LT(P??!3oJGl_fMY5!>Lq|+aLZ?|{ zunh?G=oIX={ekqk$Qf*mYzo+wq}z~}m-Pe3oWv2RBz-yGO!zF`M}@%bXrL>g5K~hF zfcmB*MNxj1Oe5RDB>7d(!#NY-&$4-5kOO9c95~Ro z*7^)Pm>FA1Uc?es66cfEabHRjp;{d$3)NLCE+u5HC5?hVdE4W8?}NK*4;^g3damKL zEveQ&1kyxqJ1Rpk)iu^d$e&7oUl;BKpqK?@|q$&(JUYsR6 z;Cux0*`x%EipCd$SKe z*pAFKTPXM1PY^7@A?`qVW;e!Sjzn*L8%)WY)|Y&Hf5JRwqnFFIn-BY{RznmM@QC=T(dv3T`&j48k!+TEg&|nZTqeC9x|JY zjsC9bsuJ3=7po3HC5GdFVgk`8FK%A5%2U85e?P_XxE6$MG zi1r*OisIWycqSz8al@YNWIJJk-Da#Z_?Z(N6O3YD3jbnijk>G?I!>%!?;$?`0Sv@T z`SEBoR$Fsg(OlUBB5B%XzgDc-j5&F4{=f^>#GD0xTqwO|mvZ}`&+mP@zHp+GT@=bK z7n3WshmXt-+B!wp%6jDhL^c~}St|w z7MY-Q#v;~Zw911Lz)>v(_(BMl3V74JElry{NA!T*Qm$aDm=@tiS)~}QIXg#fCHNPE zsRl~l{koHoujO8kn(g>{YJ{;Gn_p|-+PeADCCtMBfs0?kTbon9M$DRcP4FRPGYjNE zmIChd`jKzG#RA#DSl|S}(VLK`LiG-s9SHkJ6yf|7a!_AjT%cztJ7MuRJjg@kncB6`6&u!xw9kTbPL-zCYVHDsxl^p{M9y;$PLPsCG3aDNqdzK zQ47CDSzMSbE=&bZU_yXbej*9M4_O?SNfhR|M58x9jjbP_3Z4ZG)SBys`eGzEMKd?5 z07Ep*=WQ%$G_WFiV1M(0&kMVrUVP~58bA=@JbA0!K*Ih^Dd34y$;)j%8e8W3s9?6Y zC1;^@vNhw*pZ*|u_wA8i{*+@>Kq1t3$@OT(I|1fX@b~H~&w~7df!RhgTBt|$Hre$E zJrac72?E=@9?z0nO>d#>IH=A%X=+lkEM_Mu473@S>oyDWc#q2&$*RL^hpwz2IWhmi zfOq%xUJSY(p>fdLwLlj*P7P^HPTv1e{$qtjeNWcu$hO|310aHOg?D)5wOqN|i-nMP zmvCDXV(x-`c)@1 zkA!uzeXQN4evObM0wM!q!Qk;G+?fohH^H?TE*zIPg;%hDuH{$Bo5{!jpfZj+6xFwd+=_CPsdK-mlTB}vUU702(UW-gq@5bJL1shGu_LZ{164z>{5#@ZNm6}gBeA!H`>4#f&14&&ptA&NC!Ti~e>Y;IjrkR6Z zrSoR2Sqn5gr)#5o%I7~WefN6)&`bG)FXi_?2bE5~mAF<(1c_4k~9sb>KjIJC)p>vUerT9doxRkB}k;1pH;#M?6 zzonXQ)BHBSC2c<5&jFr7&5GYqU0}@fk@E<=KJcCF{QU7-tvVr0)QTdo)!wzn-nay- z;3p-F+~zq;w8V=sez$F45{L+(Q*1=*t>2x7ySb&};a4_lI|oyxLM=WO9Kax9-kxMo zTn1oA)r6?+Vpty$VN@4VVujD()b5AgkRcHxnqLa#eVCc;**1W{f+`cD2YHl463C1O zGvj1XB9ADgEjMm7Z4kb3Ui*ll5*=d6H7D(~dK=E^5O|zfTKJC0d2-<+y$|yPNM4?G zZ&OMv(j_h5M0^1=(zCj>(hq?)bUCF;@p#rV|e-D0L-SyPs10Uxs_*3d`WQ$HT zl%K|Vxdbb+KPeI1P!^$*Ob_OR^qp459rGNBJ#t^{!F!jMWlwDPReh>-Q@I@c?9+D@ z`Tf`b^*@oP{bq-%)ljsUo*`gw{ho)rAC3ubl|~>{TJohwNEw6_O;y;ZDwl~v#&czv zhcl>SEj5B*t!)@|lCk)J>EMI#kHfkJi&X&o2EDt_E`4@-@smp{zsF7jXpIbx&|s23 z$teVX)Wk7LC))VZ(-YzOOf?5HoldmcTq_b|UEmweK~!)>M!;OLG(8U?d<*sHpPxJl zdFWry>`2%xJ&Sy{-oQa_$A;3RGfK)PixILg5&}NcC;DOS zh*$3L7}@Fy{bcYs?Qv?Xi%7B*8zh=(+~!a1pSk-|BiJ6}GFGLr4kEPjaZ@+%%Rlu* z=AOHq(eup~fUIXi?x>|iJhwgIUwGeq^jx$cYwAn^tjrW(5>`6kDpOON?!s!cT~ z+ZCN-QA{B{c_MZ1U0MP`fP_qC8TjF5RgZ7Fw6bT=vwJ>rM$a-gVm&-j-2xBG^|f5p zGZQ*Cyms)y@)wL+uCJb7{(NNZF!n_8Ckfl^fH3YqG~oI2qIb_l?_NR)Qd@|gBdr3Y zI7Y;{2mLccjGNG~Y6{A#`8Fu^cO*Zhfd-n549&(yXTs+_30YAm;G#SrInyH|5M%)^ zMoEkDqP*;lg3$`mlX+?n5*o}$;grxK(32RwEIYPriBpy|;XyD={$NnrGk3c3#0UN6 zW3T2}>@8Pe;wzgU>B5&ZH`t;<$v|(pJC-Re*K48e;Y2(9g(jCo*P-BYP3E@H#r-PtI?&;#Zvrh@o5YHFL|& z>|!gkP(J;B@%ZcH9^w=xVLB8BFgC!kFLh-#IZPVEa5&X7@)VqoxkLlgMR^2i4Qk9!y~>!3cS>9?TFinumc|se9!F8un{epi9v&0j`&Yu(&bCGidABKZ@NQ+($h-~^w zpS+;s;;`0~?-z4`d^TO|ns|YImsa)-tsOWq|KWh=>yz^z{a()oKxA_m1HNDYh>pOn zPZ=q#XU1ZsLb_Vq*uZUL?M@U$#|m?V(Crdyc5+u`hmdQ}3$3R|z=Z-bWGCGPqJ&u^ zyf*rdq-$o|`$sHp$?T{yh&E=ipr=!WPwr!yK+m~rpQo3HL(m0&1l%OI!lxQD@W2z7 z_ejX~T6aN#%y_CKUl1YRk+TRXC=re5hzJnwP97SpCeQ%*+)=bwUIXNIwKjkVzI7P-5?njj1S@ zsba0wZ{AAZdaLi9XZe%Rjb#eYu4f-D-88WB*|E9zfp`3@rz8$my_l(RMs90`=~rL! zApC)c#{EYCq0#(gBrmTM=Bvy8^w3iD%w^x6ORM{aR`vp}w}-8z_#pj&sJNDcT*Zr? z5WN9LXD}CC{F@A(&ey^6oCxPQeM^pTSp8$`5N(3@~3S}oJ0w;h48p`{O znBk<8;!6JD3(fpeDdtVjP87n+8oMEDcC@rt5onxNZa&$F7E7F$PE4S`c9jz;oqD^I zmE{?Ap-xvGNFdy657@Na1(tO|v1}|vF9ZVSKL1(XKUk>xYBgB`>{2JSvF=Pkh-eMWLq zE6JHwXUk%Y5>6B`-=24Kh0KwF^-X5oYuuJMuI#mtNsZI8(LqJ_#l<6-g%!Ti+UBwu z@pm>dxEvn>Pg_+ID+nFfQY_z#$nI-5DIGVD)}X{{GY7sg=s`AzvH|n*>H+=*og*$h zjAdnrClx*G- zqe|b=0JalZR&7|;{x=IS`e`fPAlDtn&7 z7~7_Emj`X3#q*y~xm6E->8>K^K}_8hh#;l|)oYQXNB926|MC9>hikQ9Br6|<*T(eF zaKd_T8e>q1K+tx74NnR1cYgVcLGPY(OJDT8YKa`M9PxCQ85nChHR9`?!E)#pb5a{a zAb&Sfz*(3o$!bF+s{Fawt)P395-QU-L#wklNThmwXMP z)tbTSuq^CR>VQL*u)_n7K^XTMmFxztr+PFV;~mYG~oT}0}Ybv? zC<;e_Vp=pa6Y>+9<4?|`jC9pcydwjF;dDKjUv)Vh8>I(Q5k|v>=orl{#4aQRm10a& z;7)j^h_`pIAnN0_6S+>MR0kGRBL?)OfbB^-WQjP}09u@F6{Aqj#Xdkg_yXCkL) zLq)!p7;0wc+wrN5%6f01Wg{*8N6!O=5u=*EC5#m-#7q&d`^jG>i2lSVH`UpkydaxA zzw%tGAyA z!sz=lA_N)<%-jb$n>wbmGzB6bxTgxm(FB%|Dsa% zwH#S6?zF;f^FU#(5yY+*qvw$!2NZb}3E+U*$f^9ZzewMFbN0ojJ%gW5toPoDL%(Bz z-cuLIjpRpY(;?_qRj{%(eQqbr9#M0k8O!{snSO`0K($YNq}jUmj--;z4vd?e&s_MR z>bq#qOm3!POm1 zmFkNp^LwBE-fVlJ0k^M#63*DzwrWW9Y__6AO!qPv>citG+(E1GL%4|Kde1FDT#ha|1+J(*36pEZu^!Bx;$5<@*pkGS?D|tKf}^bBsVLvfrT( zh^f6XP5F3hC0s}^xR>9CeTRu`>N5OGvwBlDza^CS;Xl=>nwAn38vFp$nJI>fxQNp9 z21_JYa2uhLKkX&x8b#a7Igfb|LhYH&^T*IW(U^YFFM?GAfFIEB6dPV~B z>d)r3-l!fo?18@*yt`gl*%ACvFf>{@?6ceMi#D>aB)UeY+xb*V-F-*ysVBOHYtJe` zeMTkFp)EU%27_~V-F1sD``vu=UxWPCR(qfgo-N4hT?LG5MT40!aw0!*2IwYH%fu^w zHF;1r0YKWSK_!minc@LS0=Cqx#2w0BM8t8e+54UcKTU7lp=@OR$i1hc#4O-egD})+MlzMv z=5=1Pg|IZ)1EIIHJV?61!2y5T|Mdtf^_czO$TdbdQ}Aivf#jpQ`J4$31-GA5(sD{ z-&kQrzIkJIT*tJ?S((lK9Mq8L2R;MYaeiH#+?TxT_V9B*L!LM$uF6mDK_LJxISW6! zX)bblGH`Tw?GSzW(<3wCV|6E(lTE|Vd6So-=H{a>H9Y9~dc=1ajV?ydOa+ci1p#Eo z{OKVgn)X<#uZ{bUUi9uA^z6Rq-E(aAU5XXAz9HNd7(o;xMd=yTPtqct&@;G%tU~}= z&&*B)WyuYx>FP8FjjB}KW-UsV{oFwZ{mK11^FBNiCU4oF3~6EHUUB(B6wXc}slJnR zqLz)_Xc+ax2T3i=h2V%^5ni<=-bm5BUK$Q$M=PUyGDlx2eD_-Q(&yEo&$|T=VFhCa zq|y>iV__;u(5)U=qMA`G0x^0lKhwh>rZl0!)mB_S?{@z#XW=q`5)LHwZlp+QNR_ML z&6BvYo*s8UoI7n^!N#PB4&Z4H3*}~DnTb)HMx@n@c5hI}VEVyfS#sO| zTyfxIXI+XC_{2Hshnd1KXR29mA-vdbB^!XhR-)>pmQon|O8(%B`2){8nfXd36icpk z+R5t0Pbf}vtdBzP)3rpcM;sjo73-<7)i&f3MptG+XoC00bEfpeoKh8m5_1FTpV zjz=v)jNtM@RUQPk?fZyuHYZ;x91O}nrSkcQz6RGL^pY$t;Gayh+m5v&W0gyvl`nl- z{O+~fzUQmH;qQ&!$*h$|z}&Z4XOUM>YL4*;$}QNNw~2mj#jEBHHj;0wTCF1zJ1O*chy zlXK?1vBl^GWsFb&vPU>TC_*IyC(^=pXXX!8>j>sM_>3TETn`BsYfHoBO%_FoIElR*D@v-8h&JmdIA__<%{6 zM7hPnAgnvg%48kbK6WhYBGBv>&KtjG@6NBpEwy{}E9C0hnE1igW|Q4pbn zQ0Z<1nM^I;tpR$%A+b(%!8AEQ4tP312=nI5j&=yOTZyK51rQWiDaG<{zLviE=F+F{ zUfui{75!|FW=fn_{)u=h+e~GNIF_q=7B9@c=b9(XP;Z@mR3Tqo&*}a;) zw3ZxLjt@{Z(i(3ERE_!xG{-StBHBvg{Mp4%=OV|E3k{Uw#hJ^i`v8BNv&N&{@X`_mkt*uj$}W2usXWWNzKEv7GOP|*#4?3$C+G$yoWoV)RmQ$#%`O{-Kf`$eN_hAaS0}U`p zn<|JGL~5NfN(AAdU;K!~&`x=>4?U27@foD#w4&6Y9HciNTZA!ua3v|XiqNn5BmllS zxDdO5-2#Gj|0Y^8Q{t?EKl5a#40JVJZ2}g1cOmWQeOA;?Oy@p(RDUAz;2>1P+5((TV8bZwuU*wT+pD#diuA{MGt}8nm*{W znj9jV>L?J<4eet;IOB5SB0iNWE*J=Mem)`#$ruJbpa>)n!UKyVnX1_^))E52X6&Dg z5-+WUt1Ey-E<{GP-&#bzj-6iVro65AQefuN<3GJ$k>8*G>7Ri7mY2u6rdHXJNUp#d zpe>WtGxCsVVHP1+p`kbexSAG(#!EFHYUL`b0;H!FDB!HVuFFN$&F^{O*VrEE!xO*6 zh5U4R?VGbppWB(zk6Sy~Ll2smch&8nZh|*{)nm#+h9I7E?Rel!Fgu0flpjm zXv#twu1BB<<|c%tP4s{|xT@PpR5y3QbDaO`YZ&t$zN15zVwJ@WPWuEM<>GEIT^@|fgC7@ z3N`tJBmWXYaXl^}GEf(307P`IvbjgJQCXqKMln))|Bdu5Hy2)fuAABUZRNg~hwSAX z;9vAlO$Fd1I%z6#mv-jQYv1LAkP;IC)#17E;vB$iZv8}R*WJZeUf3uHnLb*8c{GlA zu^gJA0yO1I4QmfKonQX)%;Kk0p%eT|*qRHUnht@NrwDe`dHl-&q=aBT>Ced4k)hl~ zI6F47_RV^FC{yn35e4O|OLO6qAV`oOeIA{8`@7k9&nr1^+dnO$OyHefmT-HcfuNk;?w`q1@w-wzIu^RW!hV zV3jg-I$j%%G?m7p&6#+tZ~GrY%0$%Rr&uvpbK;Hs zO7Ya&rQ@$RQnCRiBbMv(EWENRD6pHVeYZD#`)$=z`|T769AkkqV*z=+8t11{N4cKl zSSTmk5X^?p;!C6-hzL%yR0F`|i0p2WDv`@cpT5+HCm}Bd6T4BLJAx~5MvV%hL;l3V zr`L}ckNw7pj$L&{E(XQsX<)v`C4rArq)`>!5r5IU#Ov(1eS?Z|N%m&S(gU1R*kBt> zha{ShP34|?BKO!MYMfG0II&XIr~ajkfx5Vg*fbT~thhF(Km%X|4k!-W2nL?6S*#|@ja0T8OqSLH+4)F*4i&f; z$RQcXY+YYDpLy$E>JB5RAl3#Nb5B|lk8gq~;=D|q=C!V zoDj31Y@Usr0pF`N0_MOdiNZWMm>h|eIB8;FZ*>s#Q>e*OI(U}^Z+XK+nKhjE5mo^S z_&eBs;GOucUoLFrP6`bvGdER!BlZESM?xFL3QS)ik+9m1lHL2m25&k z?zInu?|!p;LT(Ps(*R2o2z4EhL|6QJ&E2kMz~yq6FN4J7);2~ClPWzJ!v^3=F&VsZ zo&ZQ9);n*IfhkgTj!|bShnSy=0s})V%m^O=qhoCL!d{=QPvYtuil*uq zz)5Y(8<2Kl|721)HJ%QzvnMSf3b#3x8$Lnd=2ows;aCv!hI}T9$ggwJo8vZ)K^!0i ziI#2I!n1tfbMi>(x36Ch`9b!3%}VrukWml^?M{N6zHTdAV_3LOy)o>2aS-V@E5)OrsdecvAGXGY?r)W&xDR$ zUfp+L`Abj>VTb@hj0UCA@FoFNkFP;oB?~{4r045XhqCA1^-g`oxaf}rV;%^- zgx%m*NQwN1YU~GY<KgP$(zLMUN~1W?S+;pe#ASq^W&z#bmKj zT+dghV$NKmmMmwh`Bgw?Zr`(=>_X%6$-?qrs}&_c!w2Pf@cv(}Vm9p`A==*+K^ZBEg-gA;!PC#ONkYA{JTa-i(Y`CXtbU zi}g^x62P3U{iIIV`rw`iZy`&5I;F)8;MH=$Dm zMI_-uY+xaJ!I!>*%~0(S{8v+#$q?|5<&a(AM?1GBVTn;78n{m)qHuQ7YTQk#{rRZb z=UG4R`$dW4cP~2bX2?gPM?2SO%0VCagKADdA83K$z9kuqAFJpV{fkH6jsEO`^zFBj z5i@t*k^b?I)3@E4ec-s!h*cg)MK;fE=27RP)*eyNc2?0l+U_rUq5;hRdkfz09Yn2 zAI;12a2N*V&}N775FQO|hj5F96H+Xz-lTlZ%RX#JpU8*)u{WxVK2_2)K+P(#EMFU% z#iQv525d8YkmzTx)fZ*l1WRrNOt(ZW`==6ZkOs7c|Lcej=!t~QjE<6Uk#k=IIx&L^ zC)xXV6@T@7H^0L(1Ijbg@0+-i>Y8MPk0UgFp9Trj9`s3m-{e8a?f4M>hyiHN^G%TZ`Y@f)C((!U7r_0$Os>oz%;Rsc6qsU?gP)z$I;9<$pdFYsdy|dYRe|`sgFBr z$M$lJL1;b*WT$<(LLc~pmXd+KNzoYl14%@3Q<;hfTy=w(@;eEZl>d%-(yrdbY|>Yq zaOLa=xi5a+42{>O4i>(BMUw$ks^?cSwP>k4n`lIeg=it~%Vp*hp0K>^5zbW8{(N~n z+MG|ym&F>*-e+DL^)QtU10frt;f)WKwJphpo%5?!DOglzc9wb~LW z6!59W#k5T5Y$c{~fsICpl<7-di52BMGbNYcfVt`_{=OI+%-3c6Ul0{NkRCkAOJEcX zl{4^Pse>=$vEr=OTFi7cIfOCySTcJw=rM$fd&_>Cbv)cM1;R@pC+G1u+=E4~y zR;;gK7`lxB>@f@aM@MznH_1uY|{vb&~|wD1BrpSd^U0hj7zMu(sq-m z+pH?BrSby)-cQMHFCS*MgFj1+R<6`YCyKKKc`O7KXy8Ti=oblF(6F7dm1WY0x_~O$ zO)K7sKl-D8q2TZ7hwi=d;&TfRJt%KJo&EM|V+VM*oy4{=jM^%^*{A3bH8qJHjsq++ z*Ysu@GZI(L{x6(|e?fi?@deVToAudOf956>X zcOykhw83);K5p#jo|MjANpGhpfuH(7KP{!qaDrUh@=vAjxV?Vt8+QXGnq|#bDA&`Y z{`3`sj5jf)n|QkkAuHVKJ5R7m7Un6f(div^zkj7ThEdkfw z+So=%u~$teOdq);eHha-glP=~;N3uG+!`pp3Wt>b%-xq731-KQAEv(FNOr6Kt7g*& z1gJh%s`)^8#BQ=U6HHf@)>6aS%v5&x^TgS=)3K4D>`1iOXDj+?^Zbj?a7@ZH_Hkl4 z6&{N^eaH{m3H-^{9t?+zI?di^*4%40zZY?p#5L@)m1uX8g?d=JZAHHCCY$RQi-%sy zef^~4A6EO3fm-o;GnFV8g89l~sx}#O=95*W#Z-McU0chR;^jiIo|P3oQm>(=6Ky!M z(W8!t3>neH_fz{%eyIW=7C-L zH(#+l$BJ{~!ER~@Z3|mr=QF|@-QdUx8Ih&ybCE%RM!ujB&M%u)Kr)lum!~CjrzL)h#p-&An~*@#y!6U3BSQ8kPC_aQ z{-l$fL6EdhmLpC(jngqAQYG4&rwJz@Kn4SmRImz;wa-Q~Of0hU2esqWx+KG&@DHf6 zVT2i>8kITa9}!v4ucRhZC5dtx61Nk14tRk_GZx2vzbbJpQ3WvMeyCtU-r~AA6*|Yk zcGRe(jlmhpvn9B7|Ea`WY)Nd186hz+F+o^Xwyqy8MD=FfsP~1pkFvX-S-RhB_4nHO zW?y3^ddpOT*@|rGs>v8*BhsQZ!v0+3EU-gY+AOJB_27EYuv7}{-SdeezyIpL`rl4X zU7VY~l)HF5_p_f;A67p5V57R_Va-0G=WN*nghF~atggFTLg{^xxz&v&O4l~$f_bNv zu-nDs3&bL3ii)`$RTj*52(>p9XP)H{|H5-811HEnFrbf_lIgCuaHWLh0OQaL$6VED z$+KlzcvwQDk=!IP0o;jaZPy?Ywq@jY0;s`^yTjDxZd{hcRU7N7DF73SQy0db;Yvp& zK%rT#jc;xj&rfGPJ_$o47e?U#uLR4kB!+sg>zdeNiJto=XwR56czJ9_ z&#xpdPnf5n)JOE?SDgZUDkhQ2v*E9wIZQ~bp4hKlx%=l5a=j!z1CaQWIvKdt#~Au0 z{(y<)*UB=@>`$~Lq%f|)Vp*_1KN~%>oRByC1RI#H5M6ETZ07E}3a`FMrceep{}rgc z<4u5@M%NFYUHXiW0YlT_3xnRhfIk2@!eu0`!Dwi;rT>-MORhFA2(mJM;!Uu3RCsV2SO;md(mnwIgDX(fMVzbU*cfLSZ0X^XegYU zM3I;#83k#YHI*#^(GtC3@hV>xF_^DVTVXnGzhY>Z7XWTvQXx76XBmR91?OCakSPZl zh)&3e<=Xmkd?1{aj|adE=7n(JhaNCxGNLDP-gEK8!m;1@L+4c*kmMm_uN#$6@z*b< z@46F3kY-?DHgevZ*Y9@-_IcJn%`UCS%c((!wByWVIeI*OR42qS8n~PAgMy#A~%ks!|M@=lrbO z2)5XEOGpXM={A=NBp!Syb;oVq;n8TolRflC>L>RAUnr6qqi0H=ypz89=D>x|ZCsv< z4orq*mlN%ie~D9lQi2HgbCH2sEl8M_`{OM^252Aj%&*&xjS2@_+9?6+jbMS@2*2+_ z&STz4k~x|oJnoW_32JnkbiJMo%|*@-AMsocv?YJ0OA9UeLY<$Cg^B7-QajvSe9ICIgf`Utjld1)eW-Q7vu1pn^k2PK9^CMwSxlSHb`U;^NK@Y8~T zzt@5sL$;ZlS{tccBSQa}1YIAbrr9{Ja2{^oD~O2Oa# z_ur)(JAY4slwHleDBGmvp7>dF#=V=;7NYjH_UR@>5z0)YOT9HG3Q;|vwy~ScVYFCs zqt&~20cng)$tJau1W{b6wyv*oQxY&!Yp$9==}M81Ss&T5UFCMdZZXJZ^SMa*&Y1bM zj6Tt%5sAb{iqSP`Y*O>u4=3CZ%eUJRE9pArj>KH>BgO)QBAk`PC4DegiIYS^n4Y+agF-!9aFs!39T*RuuKG&P=~pl zcmat;@>BGKBFa_&QuG2rK-BT!+vz)QuM8X|5Ru0<9V@{M*#xuXB$la9s+fn_2Iv#v zuV+S4A_f4TI4_tA6%Yfraw}*D!&pgPj1|V?l`&6zU^#J-NtuOk0U^~>2hz9RTK?wq z?Fo_E7zE{3kkUGScxcT_W1e20(EeE?6?3QN&5;%Nrh@oz9Qe8s;nmY>L! z7grJ&!nsj@dMKKoPz=u85XA7>fqmmI9hrXpz~rk(XWr2<5ScuhV1lMuu)PSZWKhmC zC2X z&IN!}b8|sVGn5^t0X}BaBtB2cPPqw;W7aAhxI$d;iS@W|_G!w;HxN;=zJ_>dZ&jki zbTC{JJW&AQa1|yV%TL1qztS@U(K80bPxQ7F8(bRuEco?fD-*k$r4>);{G#vp^1^}g z;<3`X_p`4(k^b?Iy-PiA7h{)vxx!fV8tj{i*FEXAso)l&^$~EVxcQJiT-kWNBQgEH zGfE_Ql_AvaX4{=C4q*LCsgqbL9DFhN*`t;7AGWd!-SS$u7PxBKNQi7ibzN;$H| zDQ_3BSXgi8)*K*XZnc?N>EwMIMSnTvO($orHey}#f#$loU0%BKH3pzcMB2p7TuqdV z{B^@Z%j9Bwtlg1YHV6TRJ@G-}do=Hh6~m=^zm=lOd?o11tWAf9GZjJ4tu{F?U224; z!{>7q$xJd_C)sGl3Bk;cGsqJmz)YbQoeZ9)Tth|2Ydhj0A_0F%qR9WofufH< zdk=k8+4a2F?(^K&0K)K!wcvW{@@jGjM^hoIwV*XO8__~<107=N_L$H|wOaJ-*(3ki zfA&8I`TeK=>HqBX=|j4)v;KOu7Ab%Je&*i0(|6vUeenLm8^5Z2`d;O;531jM?o1Cj z;hDAdEsrNz0!X?qh}-Ne$-Ya4u>g>{eX6BWMh(j^^dVF#JhNR73Ewmm^y) zv40W=sNe7rDS_mp3@fAwxu|Jyn(lbpH7@;fb|k^s7%OWh3aZVb};Cv zm1K$)ag|=~Ca#4gI(MHWK4AQMEoAIXo*bYPcQZE;V*yxH8gvC1qA|z1z=7#9N>p}1 zzm_Iw#vJvSDZqpMY4cjarq*?}EoE z|L{I|#`W+Z6h~U;CvXd_A_Q0k7ts$x2pNr#*Mfy%i?i|Qa$O#!(^0BN_oi>Txj82< zWg`>h%tZ9Ut0tAp=$qSLE8R4_wjUbw?g9Tz`j1{--FtZI&56Kwi_x=lVF70i^Hn%5 zc3R;?VLF((vKT$-iJx0f59KP$1V>dBrY=lJ2Bq@V($U+%H79=n|R)XDy$oWWa+B{k(JJVJg0eWyZ1L0w~z$Q=p5-P-= zI0kWI77P?G%<`vg>?STGO+wUID1&$nhl*O7P5IItqYF!$5pcnL>Hx6FPnbAUMgo)< zez{9KK)L2#gH$4>s|-~FeMHJJAwW>SH!%b!OYs3rP}?&Q&Po3m2iO$$#1Ipgrf0rf zJNat%{71=)pC-@0SH1LUb8VoVUoM>3o4WOuwGUs^p+S?iX2zeFSAES+DAiIUi$L4~ z9qRj&^lw3iVD9U{J4o{7br#;Resu$8S9bCnTVHgtgk82`6ZP@^IUe_fsuZf>TJfS`SdK2eT8Q+`?LVf&+qD zqBKuL9t&Let1!4R>OfY4{95s*6T{xF*BI*iiNHq`?$?EBqd@@-fd-4UHEbR?sWt)` z^XvrE$FY$x2iOTY1KZPnFjq1GfrC&O$c$mk3fFJ}ES3yGvbVlKW15))thcB}fMD(n zLDWkW=hl+L0eQxBTtmE;C3Y5EJ{LK?G<_iX?#t=B?gRp6AGk03#Lwj2VHXu&ey;e^ zv$jn_I~hC)j40LQKCikt0<`jX z6AciBWHOhZKJi`qp}md!UR=HJWuJmS_ZQxj%60!r;&L!MhJxT00n(4k6Ju7fz?D|- zeb+)VsO#PZY^afYeTxr0)O*$AM?d-t_r}gjS6c~Zda(TM*YaxcqYvjE`AO!EJ2JQ5 zmc93$)NQwhpZe+Y!8gY|@*$Q!0!G+Qh<*r!;p`dMZnqNDJk@3vLxM17+He)Kvk(V@ zbN8RZxrwE=H?)QxF(IrJOG6aslyHQI5QT10L?;+9*#!BJfJmSuM4F*!)Qv9aEnbih z_Naa#PkhMi-Xa?a@T(3-KZF#sWYc?}Oo<+_TZX1q(VGvlj+MSb8r3x;D|UMcL~l%d zHZ1GnOhLy*i7*d){6yq&w`W8=&V2@=PYoJM%#LQr#Gd(`grFdFxN+* z(08j71^KO|E*ERwVCJ$fbunEMq(axe)X+EMFCUqH^XTk5?$3KLC9SQ6%XW0dyhN!2 zqQi3CN9?vi7Up&gLo;D{Y7mth2{=cHx_-bnOYH>OzuSg+lJcnZ{gN4|&g+t`dG37hqo3b7$6ZbI)G}jj#EfGD@==R5w zl#qj(iy9f~p|@yWat~)P8vKE(g|U`ngQ!z8J>8D`kA)&bo$~62T`lV-V+$vf_un1) z`GYiI*35$Q?M^;ctW}%&Za2$7^w1~0KEhlqdp9Ph5pC4Moz@Oh(_4Ecn+o{5dUa>; zXQ@*UbxNz<+>*TbxqP;C_JiyfKhJ&kXzuf$W%fN+IR0ks%AQJY9WYAcW+PgxCabk* zu#kuBr(+?tE2!}1D}ww!eebFh?QUd3h0;vCmZ}g^;;cCCHPw$Z!~m+*~lb;JQs$qUv=_0-}HX;(ChU zS4@{42s$Vo|5qd704-z2RL|Haj>(_=WS=vGsAmAO>*-O>aI7b1!}3rUZo<^Cc0H-< z@yLoE5P}?-cO%RY^4yy?gDjsoKEVrTwCiE~G`VslxO}=ka5VqI)7hW>R4M)N{n{E~De)bbdoDbhG4-4LMbNcSPa!))~*!Na$&o8?sz%exGO@dt~k+1hY_7KdB z<5sv2qs+&~TALfN(Wcf+$4V4wlFK{YG$jq#j+#vyNSkhIEj=5^EqN1^c9(Oqv?=?o z6rANyAw)7um4dYaBPGu=*oMxs~;lXIU`!VE|-HpKNk z51@o4kgb^rD%SV_F^gt1N~r0(e`g6xwlNSQa+1JcUN48lk9G=i#%QHn3fNY;|Xl!|gxLke25P(o9!IA!#X30+az}nvLYmc7A%u`ATpQD3Z%Ay zkW8k$Oywrb&|o9oxO{@JmcH#a*I>BI>Xswqo&F=jyKYBuA={a>Vi{A2kx+vZE+pm5O3Qgi_3>7U+o zYJf2f5jUX&v`#6x96P-bIq8?(`@n{S7d&4LuO3{C5|u8K(bOcyV$udRD$U?cIC9^W~NGBQ^%XB4)wBloV(MaE22S0V(VhY~^cl8{jZC zR6^L|D#?!KT}bAD*&(A?VaA^xrBu?!eZ+_~z=kA7r$;as_YF0=B5D)6*VE7_aM0#U zh#-PcxDcYyL|Dn**wwY9olY&=aAYaoxeOk1%l(m8f}}Wk9MD zOBf;p!3O3l3>0S9l9v&n0$e;?Z;_K=`uv38OQ0;g^jz|e+ZGSMwH&)h&4gvE=(G*a ztWWuD$AO-~%1w1E3z__+*|goJ z!0NB*`$+8@a-Y1qA$z;D;!Cx$eWi0BCp+w1S0UcW?ef&;#*S+aS zZpps?h}<1+3WO5NF?j;;$G;dY!HYsgkrqI3HN6lm#`5)4x}1vT{dLE+&r~~+DkT#X z53ZCD%`c=XQB0AZt@JwGSgJgqtpeFss?9YDT7Pz_(aN?uxvG=P)e@YiN<^o~jiJeH zNDpVUlZAjyh}s0`-dJuTPs0zXLJJj3gf*m!IVH^V?8ckqjXaH$4B-w(H=yX|H$n(O z?wbtsLtxx)rF}#LV%=hNfT>yDI-Mi{i{xq-AZZ7H zGp0)Oq1<%2fse>1708}wmX^`{T%$#ClBhb_PA3hRSWR8#U&VGSW+Qjvzu0_i5Oc-F za0Dz?Gax2`fx$K+H8Ec_i!U%D5ySGvNg=aNNn@LO`pCY^Y@LgNb__=l9TKdVf@kx+ z;~hyy{joULvPR~++`UWld1e%c9_mw|>rxV-qYBQtj0aqmo^TaU#s4jNm{$|G#O4glaVz2EZfvw#nu%z#% zq7nimq?8YQ2KWQq_l0g0+UsO9!xD4IQ>3<=mZBFZVb_uavBFfzJQNAwKuq$jww1jT zfp1SOel)cD^=fj^ZIJ+!i{9PgjOI8w#AVCKqH;M)t!Uz}U|LcdK;FtQnLHhdZr zq$Q}9A{)$vEC`_C{1i$}l)QngZ0*A|$T6YZB)}X>78h_Q@+&@%Edu)}GRQG>qTTip zn2f0sp76Aa?CeV8o$vPc5rg8Nn7%#3po{`QB;LWN-pqw(pxCN>)!|r{{1Uthh z`<$?kbZ21XMvz5|9FTPkVz{=7uEbB^JamIJ2*lys6q5qWBTR_%L=9c}Bl}X>=v!cJ zYI{b(J&|W0E2if`x-iD*u&t}&AbayD@zIIE36Zv0^B)VGTu983d+1-Dll6?&PaUl6 z`?Rw6liIhts~3(o3T=wTr&m(y9E#uZo9X&K-Cmd-~nd(3j=WeT}749rNjn zMk`lYnkfAGML~Y={HB{UH%SevxHlj#SIsS^>fTJX>gf4&rkYPx^C$ur1t^s3>xiB7 zPfQGC$Eo~e!J81=j$pLNlY*FdiVRT!0>nHJCWSAyDo?O9SkxQo@}k_btgkUa{gsITRT&)@Ks)@2A;GqSzj@alp@ewO zZ{KtPBE-X?1+N-SaNz=luWa2M!7Q0FbMG|>9FOFtWm&~_%SMdB=oB*`-(<^zs~WAI z+0>^lWS@I1eaG#Ew_bI!a$^D^Lujzt%+n83R>#Ndkvvy1&3ZFfar{i*jskHNic6N3 zqeZ_yxd`EyYpL;MSvD@lw5(mxxYAtCRn{wxui25UTtR8EqBm1nuVb+tSe5-m4B|hJ zquIjGO`IfCW;Y)&cN6_%^9oitcK^f~goa%a3e;b)Kw~XEF}h<23Dy3I!DxC`q7u*! zu>`FHAsTZDamf~SHz3+DyI^(#O}!~Ni9f|pH??oXxC2&z4Gc`;i9Ud}x$;+U#^)2Y z6T`Fr*Z=PSqTuiK*I%BR8M*Ps&X9Cy-Yd7F7+>5Udj2tT?aJ;~?MWz<>FqA$re-S= z$xRmO;Z{e&AhTc!c#!7P?Lu>(AxEHP`==%I2**k!KShDG9q!LZFBWR@Atls=*49%K zn2Qn^c~#iqT>-gc>-9JqQDa zG3HVXks0uCJ%9))V^{@Km=4R+WreB~ zgq)`~Ci)=|nlTHQBtml1eK{?$9Encykwba1Ru`=xxRQQaacA^Q;g#n>e);Er*;oZBU&9Urlf=@SaDJpIuZ>9N^JOawOVKkxy_jtBITp!J46W=rKKJfQ;zFYt zqKjN*8GMkhdQQ#1A4rWjt#Bke>Q7&u3V!>|_{%5fe|voH0|kGOiASbrFkj%oP#6NE z0n%Yfpm-__Syc|6$W|l7deEqm_#%uFh;={7b|)6djF}}6SFWN^K|kd$ zKg5B7s$7WNuz+Y`W<5PptjWj0utn0Ub_ zJ^Ry#@^8Ib@Q&zv&`PL=;jmYZnF3^L8o4#ubmSR0ll6g3*WSnB+sS%4?6x)ek z#WSm+T4uQ#pQ%PC^9$eQPrsY{`pNv>r>d8~EPVaj^nLebZo92^X#YmF7c@!dz*B{- z{2MJ5W2MqUvYseQRo84L{P{|@k|PenL$evnRlG~F3%=Aa`Hwh4+&AFqM35 z#X=tlqs0s`1`w4l4{%1SG%Ro~BHsh$3~*}uav(N_UG<$*!g9Er1h0`=$t=td5cFYy z1{k>&8hH-nfzrW+T;L3kQ~*W_U$bhA!B>GqF1Uh5vME zQP8|GNLa!btbftDWkb=ngiDiyD^8|R&v&|VE4J3mH`->AuNiCQJcU=ag4blqtA%QB`N#4GQ7`c)Oonn3 zral~CI(0{$!r@mgCuAFCQ55a$+RWNG@3l?HEYUMI2LIc+#o6&V;4JK6lgbiOGVZ*k ze~hG351<{6F+u_+UeB?t*txb50k~6_Vm|~-&Kr~4($5WuA+S|)HWzASbK3@S5)fd| za6q*Knd~c@{dSSz^&bWPAtWF9IMliSt>~_2Jr8`G<9MepyaiX1muk&W#mPw}=>qZB zBc$4^BsamIRedbKJg}H};q~_v`TaNl%|Dx)8-|=l&%xa!7GmvLVwya9gBhIeA|{Iz#q2nfL}g{yZlb`kxqr>=OD!>j2jiCUcmC?8d7L?XdqR|GVR{4fc^ zn$)^RvxGZ*0VAa7f@p)kD}qrTILR@Qjh{e`ZYFi7;v18@tip83N_qw#>1zog!$4*n zw6G)Gcatd2y!C?U1iG2IfU~vkC1dJa)o_jq)R>h}0iCPfxt!!1%#K$bKRw`I=5aD# z>9hATciox3?Uve!{ToI9_r^k0eb!nKTF&eVH4{FC2DzM{r047Si(W_%8mVZx-N-qk z{fNMKx@E*bTOD-~h;}OAGvpMo|FOd?-7gDf_TpC|-~a^xgh|MQVIUZDeH* zXl93i$W_F_S|en$5u}E0|KwN)wF#IrYWf6FBECXBOXPAa8w+5L@Uxy7oe7-=s^S&Y z>*?~6=4|&6*P)~EjC#zSAW1x^x!MR2OaZBC&8k`s^5zrQYpF5ZmC`|iPAl%ujNur# ztL+o$4ETcwy{eBkN`6`Wy8X8DS0BaWV>mWG%z3nqDFicPsDM9_Dgc+%&P6JLsuG^Sg8;xmS^Hlz9!5g5QUU+MH_8=$mSTxALB-*}9sIB|X z^bzWtkDP}Gz%l%zHE-ggwSQ~?wzHK*smeBi4ji^S2@-=^m&mOXU)p@93LYp2)p`kq zG~*H)5G&0>f;`ohun6{F;Sb+tL8|$MX{ z3jUsa@)3|-Vd(kjIeFe-Q?NH61Y4-B zfMxYh7{;xrmI-U5PDF%cY-1(56}L71i;kRjgz6Un&A51Os}TnIrEj@8|J0M6eq>shedHPYQqA5Jo-O>`G0~%SkqG$)U5{^XI9SMEm+=MrNacy%iRV)G9 zz^{$; z@f{dmJ9KGf_p#Y`PcMEv=>6)u*|%rICrN}rz|r-C6d&XM!-uC|KfU%^fj+VdpApguSGWXq^x&5}x9k&B6vyc6>apq7fA80!A-laUkq6Ie) z0Ovp$zoZkr+6lKh{Usn1B;2^qFp6B&j$x_9R)yLC9Xf%Sj*xlq0%C&TzgAOTt!*^I z^6j{mM8nFVuhMti7X9tx`Mpm!Vw0SqXD(ORr@P8Qy0LIsUKCBI${1h0SQobs7D~mM z?5Bf}8%~(HTOu6;hQ#sg8n@R2tczJXnsd#0r5} zA?TRz%4ly8qUKtNo|(I~nLc7TuoMR!*zOL+cnA7wwx!f5 zm`!^1yxSD@Pn97`)Vnm6uo)l-$sW*SVWslJ0jUA2(2PKy4daKF?6x;e#6q`dfi@V4-fh@UG^;w- zHYI^zo>0%Vhy}AZ6%^y9h_uR;smGSf=B-D2p+p;52mKw3e-Ht%&oXgRG%_DK2eK?~ z`#Lj(-t8s09tZ@DF%{_anYDUfxh z1~T{D9eMgu)vOYAEHcz?A-4*koA_-tdC?O)>(2~VHuvC$Xcx+kU0U4}H0L9^$=UGn zA>Y?$mp(c+`{wBS;koF^Z)e|(7bd5J$4)JLe9^l{!5;^gR`#Jks@QTvc3p~5)0dY~ zHen94BaB++62--GBbl!y!ui$d&^2U(-Ooql3$|)!{7b09aG4A+Jhtrv9va}lVQI5f z9^@Y726W?QWJHw)8batu94BNHpgJlC0aLPIQg{XKM|);Ra8zikM9@TY_D^WcFS(PG zC=bhku>N3X98Vx0fclwxr6D^)W2S0Yj7~EQi(eU$P8h<126=nPq&I?shAq|cM#*3K z^gXEt9^93A>8a-2(ABNaHFuJp^4A~b9)DDj+^x4%zxsG1@6)Ah!n%CBtRXMi392*k zwBtlNd7r%d7GJ8ZkNJ1Mk$7lV=B_)-Uw+i7$+!LpcBT4yytv@YEfgB5Ml;vgde0YA zrZ&a%IToHxfELcp#~<-b=7QaWV-yWGrBhn1L?R*fS88 z+;;{di_?RsKq||yo|IZVHw}}JNI;&)h*3SSr$+!WgdPpYNEN-{K^$kwOZ=(MqGpM) zVbZy(N0ymUp~0`gNt#YqGXX2MlTs|-iaL@jf}^f>diu~hjd zmtZRVOG@ykM_~-5aGt10f=7}7J2D5l=76hU8zFEl%?LOeD`+Mcszq%sZnfG`(f|ki ztJN?6!r_eIcfm?e`FnKk{*()brbUfYyD}x83%)y6kty9X|&71q1Q~SRY9gHK9f( zXsTaoZw!9BBS5LU?}$A1;Kb}c1WtYK76?jdcT#{qn8cMxUT6pVr>lHzh2Rg_Eg(3+ zoZQKX;m9cnoC+b5mz{)d&&&=x1hLu1_^(G2InYOF$A463xuFDL;_eW=7H(1B!{RdDw|ae)~+^B8>WU+Xa&+owPv8y z@cGmIPbf88y${E`l?9(#*=mYJsc-5jD`E8%8P}ac6)|&;(Cn55=hDK zI&>$ymizgmsR!=uq@FfQ?@!!WgpFR|Q^nTT>5>|xmshr)!hzRy3 zU+Q8oO9^{!C2_$UKew8=kSI57e70<^!cD?H^^@xdKx@r@3tUxj1@7_+g#)i4^GIhH77ugg(l2%8@(@bP6UqWyG!~ixcz>KEM>_)!2M~4SrGjJ#5SO4O-V~K z2i*dI^ma4S6J>W3%mvZWemo${jYJTARemaPQnuPM1q4n`sDc3%yU<43nYxhw<>Q&V z?*iVX9^3`g%RTv6_Gdp8z^7k2fB1poJFj&!Tb_ERH`&GooaFQtb?VIon8|<`v7`<2 z&BsCEa8cmXD0>T9Cp+sZ_ zGaaC+pumJbFI(wkt08|bS#HQ)qxd{3P_D3H|!WU{tw7y4{heD0H$N!J|F+h{5NpUStSk{EA0-%=a#F z79bt*y%$E;kD7=t7y?=C_745Kh9SmIv@ z!yw3_2s4W<4E#>2v{s^pQGL`wiE;}O*$MtmLIUCJWY}!Sg=6YTB8>T#zwAr87`q@q zWFx6JV(e861d>ClL_bn29?dK$FuaM2itWO05mI)E8y;-vh5F)9RA2f2q!hz5*> zzod!_`kka+JqFV1L0<5#0C5IV14H$F%T!7jDhzW#GyC+5peCnHou5 z4QV=jYBqcpP8yqWNrh<%mAUh@63s%{D|j?KyU#25g8+Z`zZHG>VEeW6P1W`Go}pGJ zi*+F-ut=W;{t#-^qeDZd{>%UJe+BaUkN%_o=)0qP0e^O5XG`^FuFXK3k8HvT$7qmQ zZwhJ)f&Ak4-#sz4hxn{MZb@ym(U#8<0kCWi;sAvrUII8iI~A0hyffib=v{SZi9gAh zNINAT*}67mrY|qQC*_+@G$SwguGODMXTpQiA=Gq+WQ4QREr?SBQ7488F(YJXH}oNa zN~GP8?~4$fNYe^@r93uO6S+H@p8*4yWofypB)gxO6kxEv>cXWmIiM@jG*|I!C^s>e zSiy|Rp2%Ud+0MjOeL`S%?&5(dsHgm1gd!N4o_(odl_XPU;>zugL<5{1)pzTW!iR6A zZ@;Z^>6kT6=7sPHYXD;Y)lA*H(5w^LKetjEbQsM~0cqUl<&sUu!G(!1@J1-0ctif2 z0p6e*+ulvrB)^f$Kk>8J!@I^8ukEr2VQ=6fSwwW?VG_)sD4)!gQsJi6EMCbE)Wpn0Gf-)o);SOh-G^4!wE-i zwj-oHM5Ztl$jo{C$Ne!62qS=Drxi_?mhfi+D3eN*=5=KVKWAug8|Min#M8~&a6O{B zBCdfv{OK|EQWaXJyc{pgdE%FhR~+SlSz~QnLVU*|0fIDuHw=jOD(!1FK_`uaZ*6S`28fji0i*>3#tkGuZ~%Lt3e-f;Is`s!+)s{ahN1(Raq=R< z0nKwPLzr7j8jsLyzTz#_d{~P=GX^nnjD)JU_|=E$+iq)|KdQ5qp+T;mGo_Pn6_37J zpZ&I7Ty2|=gGs)W$|(u7J3)MVN~GGRCjTgBlU8uo zo%Ego-Fz(C5)5Fpi_r^!8yefS0hKdER85s5l?L^F4$9SH%{ISg>aCpnj(?*O%@hJo zQ=Z@APdMZNIg=PlrIp+#Z>Mj$*_pr8aDr&uUgajHfCD0S@S-WPc5b#KW$Kf`+~sm( z%k2+~;SeKmXZtNPd<{&tH5DBl_oK2cl_bdtTdg}Gof;yt5e8kOL?kTu$$WB`-Z&tF zt)*o5Y$QNX2Gk-%X z8B!#?@bjNPtjm6X{^$Q1cv!zZ)LZ5qdK}*;90F?!QvyrpzOBfxk5zQ)264;6a zRKkc6hoy0!Ug$q3drvMYz~WbQLCPbiU;sK_lx~O6MR#>@%`Zxm!823A-j1^~W_=pB z#m4kPREYrT)3)bV04~GEY2*84YOL34xnf zeZo6)xbW%QnY-^Qee&)`O`fk%v4BT$B2^Gc?ROgFCYe>FZh~lBajq2}oD`4l#E~|} z76Wa|&U|s)AGVibgTx2Tl?-IZ!benDoKYF(pME0#z&(?b*WN&K6Y7BN<@iNYa!BcW z6Rdk;XR_r*Z~UA$K5%Je?||pak+p9ImcP^|(#((ve`a_#{2eyO_2d=QoG8vx_#T^k z|C0BcE9=yeM?s2Ld&c}%z zTR%a4W1=`i86+Dt4dg;+P&_}o9jZb&Atr^1qZO0~hT|l$734~k$FJ}QE=2V1t1Mw^ zOpOu2H2RbnHi5Zd0TY1}jH^yd=D-AzCui_v8gqsyLz#lmz!|C1LZToKa?!?3-I~90 zd5>&cn)7vYYa5l2*~V{68%r{UrXWAUu@Pya*-ntI3e^=-g7Io;hQP0OQ?)aPD2#GX zK34Z!kv-csABI&?&XYYNCrz3>j@3#3=5{t$F<;661WOiV z;*s3+Y*^w;dGeQ-QhWc5XmLh_g^gzm2+gSENKUnPYyM(gm~8@7CZfnj89v%z=Gs&?K63p)$`U zqyc;fq0xp0eXp+)QyR?>PHiU(huGe=H==p~=r}$oH$BabEldJ9u9B2XvH_qE=lK&K z+%cY-bRxIlMU_TJ2GGYEjy(C0x_l(_^PlFPd9v*5eF43XbSylbh{O;?a9xG{fmCgI zoc5M4Q*jJj21okSR{-%0iks83+>@2h;*Ai0aX=tWIJf0P8kSH5u7^FKBe8JT%K^*? zPr)A*Nza4?{Mie+1d@9c<`Hihr6pg@C(x-3;mv341mWWd$e&r`6jJnVYKjZhnDr8( z1olZqfq&V77!;R*J$pt8NJ>b-&UH0QAt{lE0|@659?Tt2l&fVPV_8h8mjFA!h;|kK z#>7l>^3g@Gsk}F8710BKFRkA9tM!NXIS(CdBT0!l>OscqHz#QNY3HzQoKZ!61L7*H z5vbEng7*H|Kl`T&{@#4|CH~B2uHCJ36IU_1dt73v`yQ*C+~Ci)S7O#{sgYE9*=#SI z@gyWl0Q501Q$O?~2{;dp;CBd_yvDH$7fKtXS0N#g`a9lVzM0244332@|>LB6Z_eN={s*v{^HS6YMubdujoh`n@yUK|7vnb&nPiO zrNKbgjAut;AhL`VBc_5gLjKICJW^>MX21&&8VL@O0wLBZdaGWBqcGzVxP?qyy=Lcy z7oUkf{?O#yUaKr6)Qubn5m(LURZuz;~8 z4SoHGa+YZn>+8vKbUrr3wHSe5JK5tj%!DKPDU2Q^c@r1OMogZ7h>~y>pvG!SHYBt& zp&2?eJJJbQCLt}w2e4y#fZBWrMc#9?kEzLv8uGRTg2s-Cxm<3$a+3t*tu;MFd?zI! zeYB1!7*QX6#jMveqho=7H=`5H3IZ%T3GxalAB;jsg$Hmp*KWPr(j&wODpk)!PgE)t zj*D^m_A{dsHTa2Zabu)Sq`=6q59|-);F5*txw?EVT3!t!r7=^r1~;|SbG0kGk$Kk&TLa(cBU$EBJNl~wA2iQsYgakp%BGTD#c$vyg$?5=wYuf0?|zTcS{=!ECGNl({o z0j&X@xKF9H-II~6v-!z?sL_&*4A;%;$!@|((yoWQuht{g@N{MOC#k#dlyCYCThu+Y>k;Vhm=+7*vIT zA)#3`WwoY6r+$monqBw93|fJCiW9gVR%#K-|&fS}Bs$CH>DHlu5h7+Ah4_ZG2LF2oI~rgk)Y z=3+j5AueMgFP0|jQm*tPfdddjm@8CevwLQz%QH-nKXKA*Wi48i9V_t;Fw=FwpSY5fTVNM)SVWLMAgqzs@nW-E7&ub)@s_uu{B{`r-OGt0|k4F`a`!%L}*rK)igI;C3Bhl{KnpwJ6H zOWkwl_wIL|F=m#5Kmc?4R z8Djo4uTQliq*1(eB6xB>G8oQ#=A+kkqH&XP;T={Se5qmW@Os2R3OzyX?hBdJj(G$= zVGIEhweX15)G%_hbsFcTjjVoM6R$j1v-OTPNll{SW-guzo}f3|;P)kB8q-e|7pd-; z4$LU$ghX)%vv;qmTM+_^&;&i^IT-!veW^QdTmATDGB}kf&|0W0zO=4tTz}=-o5oI|87=ro*}M;k7+D_HuOK@bv44 zr{3_V$9*Zuh=_*Zm?(O}1>ZtUx2EgGFMeVgk{1O*UuIT_Qhy?{P@aNm$dSZocijn* zwANC?vHUC!sR>VGmbq5!HCtW|WhVm$Ru*cWYI6nHhgk7m!lJt?OLLJkOEGy^dop;< zIdN1{J3pC4Yt|t~69||xRs|kK=1dmj(B%h;2BHJJ;V1M%Os4_nA{cb@2|34q$yrDE zz31Qg7jv}E+h;)l0RQw!L_t)hvz=%I=`k(o$DEW0{N3KjOf!{0u^OlhpUS=WTK1<8 zrEj@Ko+kY9k2Ck&U3~l3jkzI{>E)XTVFPIFwGd$ij+svOCdJ)jEw z)D44_YEC*^Ugh#;Q(m=(kO1D)Xa${ClxTph1~TLEZ$FLwbXWS8n@jJ!*7OWt-CTRn zg+?yPl$X#2VH75}FCkoynw?p`{D1x-&jxVe#ztD78#BM2!XUwgOxEp^v?R#5 zO^A?-=(rH;;$NNkjj7gHheI@&Da#kYxTMj_ygA@Jc(8l_>tXrG#~#`9c_9`f`vx-8 zE9u!}eYN6<-f>b4K%OMInr?Tqji#)S-FQ%plM8K|rKQn-@h|>+1%EHU{Pf)1a5Uy! z&DP?j;?)fRWj}$WBtj3iXg$@lGnU|&vf`S5Q39vpCG{H9Plez!+4kiRrNBO|`UXsFW_A0uF8D@&Aj!OZAF)VuFAnW`$xnpp9Nghg8)x z)e@pdI4br5Z#1T7 z{=_;7;_AjqSePEn%Lnm>;h|iY+s&wxWBcol#9Rn@cpZqrX@aoji(#a8=57lD+9=`V zm=wv9W@wQEenodn^02?)JnW32^_>Gt?Pjz#d#sg}t>6Uon2_o?@`)jY_5zDJ`L?zTgthZP}_ui73hJ z3KeR#E$4ghuRQyU%-wgUZ@;bZ>ld3VW8HE<-%wU!M#O8Kmx4bI^xtlIt$5^D_3XU< z*)ppOjb>yvQCmyNryCiUK#%Qd1Ex%zBJ)wAaZ>P{*^Ek5Zv<}i@|`C=uwEL8UHUjU z@g-L&sd=mL;fLISbtTH<)utETG}dEIs@xq3&9+*-TY(V0VI=lffCVN^>YebP=(J@B zZAoMyNCC1tr4!(LOtZyl((>feYJJ~Q>4R8Wl22Ce{5oUPx8$d(>MP( zbKkwC&)@%kLlj|Gj!7p35C+9B)Y*Rs!AZTf!wo(rOAyB_nf64nA&VRc0jtn!F(GoZH#uaHpBn-)P09ePnqH`P6&cRRbLYK|85)S7?TJy0BxF)jM(Sew1iTd;@N}dAJ_QV?u?QWQn3~rP0b(oSf54ym_Ji(82coZ-jR}y{O=C zc)j;**+lT<5&=9rnkaSQALu-X&FL9Ci?!0`1_}X-~yUg_nb(37&hC#|!)5XZi?{rnDt)xn`Kmrh(CvlM} zqZA^4vM38rsE=x&_S09sj6ZNs{DHgYr}v>IrW`acYomRdF$Hvl7{z&ubNopbgJ&W< z=z;V zsqY308mW(-$=r2k@;Oye37d&6sVi$m_tI6K0 zk=Vy-LN;502Ot!Tfx}SePS1m1Bea5v&Da$ zumlbfqk$I~0o52hOovWNN(jk|V9+(r{ZxnY%n)YbUVWrzU^I3^50Dz1Kt1A@6RlkS z+DXoG#!a&CNki5W)P{avLO~#d<@ksvxnRnRzJAiq=;_R^d&%YbnX`%f9CebK^^J)L zg5=TWwKI)qCp0Z+^442qLGjlwHGOjbR1k)18GwUkGX}z7UL04d;fBc>Oi=!i*h456|Z}e6VZaam`O9~(*zNIb(#^mF;`sylp{$!KO2#KcC0!UQfIw^ zZ`Y2$oXcH%*bew5;ky$fOrS&vk4=;(OU@FifdK*v(ZOvPZUTAF1Fo&ZTRF29PbGw7W2W&uoojpk=TvG^&_ z2a9Sh4CNksBz?;**`GYvoV(OT_0&Zjc^rpIz0nLwcH9Z2{a%EW6h)ya6rr=Wi4aM` zzgkzN?k8p9fB+p;8Pz$GL8M$xx(b>w$T9zRI&mT!x;D}lQCslGh4d53O^^~aucIvD zOfWM(6FN;OKs8(lY5R$Q+-bu7F*Zh2#^kEaxvQt^8VpGV8>qKJgdmudKopaWf{C}V zYLyP&CACQIG0TUT}tQP>l*l%E?=TXtES z6ANkOomTImi?7Ek4<2aAZQo~Qr$yEO7ogZop!eS zyY>)v(~5WEFaPq-75x45r}xRSpKD|1Rws9Z9f`3zB+z#fN1zrW0t2T)OQ+Mf-B#KC z396(e|7sf?LGQ0Yoo+r^@~)VN!w?q%6J#$>4f(%Azd#3|5^+0ac6E{VdZ%Kmh0DpV z#3eLE;=o%I8TtGgY^Yw`k%VJ9C&J+V3RZxybcnlYx8zNd@ouKtGCR zPz`Q~(Z+JJidL-2-b1z}#~3ySLrdiZW1fqgS8IpRsXMAeR$@x1SQD|EX2NG|Gr9tw z*$yp9xHgL#?&$z=Z~?M27Cs+2GqSdySu91*fqB3il(qaz&&(Pkuz(QeqvzKA=OeE_ zO`=JB{ubgzfC3@R=5DrU^thTDMr$}7asbc4IVVvNu#5wu3Yya33F#0-22}6vXGfv| zuE#|5o;VUC0Rfq;iaF5WV=tk8j-C86b^ERBum94@O^Hg9pmrE7rMtt97%geK&6QIN4wL|BYK0h}1{_(jF zhE~5JfC6CiRk1MsC3mJva}D9uvmBELQAgH~?4Njb-}uWHSH2!zJqXjpGX9+ijf2uq zAv%L~E<}{TXXZ(ffmU!8Bn97UM#Qo}c8s5FB;`CtKpMbj0QguHE`%;QPkjRr#J*u; zHX>+@mi&aFqbGA;U$P+0bg5hcwe5C2J*P|63%LJMvXL4m(duLL38a;y`;W=0FkY;@8kpnKVBZt4+I@*jZzx*J)#mEtMClqh=h)gbX* zCDupI@JSpg`{FNRkzswYV+#QVa%=7N=}u%}quIOZPa%Q7**2ZbO8K|%WNyDbbN8L) zkKbub4=DcxMA$}X)(s>CG~+Gvs>;Sjw!2a6c8e9Klq?t0)k4cjlrMgo^`C3Yeuw3& zSIZk4#Zy3qFVvUq`1a!1RUN=9BvZ|(@Myjok+OiEj8o`(M)|lQ=2GDc}n~{pwcDS(t=2I`*f~}kFh*^)6l@24KYhemRg$yx8AT=`VV^X@3$9POq zbL}WZ9LB2Y2QQFk9DqTFJpL`yOGqfBDEI7>3PBwiU?#zv0>$enPNz2#A?>`)8o@k#9{gY-xC=C zk$?xLfJ+iX2*~Ql<7V{-UAQl-T=+J1`)z9BbXkVPWX=MHI zLiB7fOOy#@$_wf8LaHR+VS~$PZqge+Hyt_&&Kp?%V#5F3CEr)m;bVa4QQ!W#@F|+1 zhDdfaQJh*&T`bmsYm3?P67X>{aQKpU_t~XS_fP!loAH-VEqru#>GLbTBUpy1We16O zYB$1nW1R>EwnghUPHFn2JxL4EBLcFfji=-%j=2i;K!_EeA(xoTj{>1^Hp*NAR$9Dk z2A4pNWHMTUEwC+0%&~yn?^u%s5BaPd-3qRX$yZHnsNM0!UdSe6RD!lZV`K>WCmPx| z5FHZB=mdiR@WCEtfg+{Am4g0)niN4C^>AQbr#($pKwCJQ=^q49Ke`A+aE79v0Xc} zk**#5CVlhGxtE{KWaUu?rEV=yIrwGnmyhQjc{uyPec6W|$UX71;_EMGyt0Oh`n1{A zTCz1e-Z+1{aqd(*w%D$P1b1F-K;K_&Y;*;KUh8wiyd))6a_0N*o$tSIRa@O$qZ7#2 zree-Yrj{K!RGUAeKPg4ajyIi&6voPRU)>3k=MY`DBa3_rl=+tcA04YBVYQyecqRlji70U@YTu5$7l^jV_NbsO($M%_^?buCnkYy6DBZt)f$pq&x|5c z3XeYBVGM4J$T0{~@dWlmxFPxwG!q4ZAhUvC`uB6O! zEuvt?Sjd=J_Rz>iS2i@^UyMr}CI#v{d1OKN3Z?nd$$&l$Mz=7G%^RdHn@W;+1ggfz z7owNw1Pj4i;lU{4+LLxl<|NXVPqgV7TB58=YvqRzb?$#VreFAY=wSPf-G$!{PZGXx zE6Q^7vByZfzR>Il5a(Fd8oDU~f99h;c8D90e|=`xt~+$u@9+NZM6FklKu*=<*Z&`QWEdyD!?xWdL%We{%8zg(r!L)nHyF7LA( zOSr$P8~4Xn(JZDO%lBTU=3lYZt7(!NhK>Dz0y$6rYS=Sj`TCJ|F3b7i1xXknnQC;B z&exB66Y`LT+c>-3>_%7M8nbhYo#?91Q^F4-0@`XP5H<{vMv_w<;s= z(-m=yxF?+ij|-FCRH3p$Fw{=uDqSKmf0jOYGkwb~rT1R1=RCwu6an)U$B*t%8Ixs# z=*v78A&VVYGI*2#ix&_xaR){;Hx-9eda8Po3(8diLh!(#_E--f>=5mvvdO@4{xx!t z)gQTODewNv-54gak{r_KL+pi6WkA5+_LV=`8?NrFHM5<~w8Fdq40L`IqPe_!U@m+d zdktg&o4s2Y{J9i6b9wEX5#Nzh3m>0f{)!7?1qzpm>Cn+Z?;Z?A`zqADD~a>j@<4^cGG zoBeY;@hcNCo+Fh3Q$RT6atw=lS|6LG88J~x5cAF*)4>*1_z)IGM$~57q5a8C3jV}i zO_pV9>UjLiNq5U1Ld=&D=i;OBg1q0V#1ybd8z!!uuZGGWzLmM_j?8`cR`!0{ID4}6 z?r&0e-zm5D9=I?65>i6FR0ehq9yp#Zi*=*vc4?pNw40xt>_hRRV+G zW@gURoytcayz_TI`cbu6@#WizO1$8#5_-sC3S?0S2jZfpPXY>3!q|x2D1w8Yt&&IQ z_C>$?x!-$qAu(8VBtsJ;xE!LHDuo!mlDv$eQnh0nnq~PHLsFGN)COo@ho%#36`(*s zA<$szz%@cGy>S&*M;jajMZ*l%0z@M$Rvq~Oe73SoKNRs~5sZWwO3!qKkzo1$%qYbJ z6%qVX_Fzt2W$lxe#3_IJ3htwbfu2FATxf-iOpww_W^EyMK}wp`L@*Efl$-1X!H&Er z8tZgYxf(9H<41MV-|uj;M+g~Fi?lZ%O8b5zRXw>s`|tx&JUsP8H?h!dMn%GA^KI%M znlZFp&(=8Z?z4|*-`$|HHFu@kae_D&%N&uUDhrAASugR2qu` z?_tmisq*<@!3(SWS+uBxjf7{`P}Ca>{Un`LjrJ<@&F1P&qvQ$ zxXiztL&Wj)=yAl{DrU4$+Pt zE76PygJuZ@XdEqbMjH?Z7&KK}AWN!W@UIr+^doq5>uwCpn)CF)>}ZSzHE9yK$n2bV zH{OvD4wo=}C7sbs?Arco)$Khi-YJ@NQP;00Cr>+6ms?wsJoGM%$KNI z%U955?(xUEnO+0Na!ZVf;Cc;5UL4j@RDHw~rm2F0h_Pg38f=)|3Gi#Ym5dq7&&cAX z34lZ@jdfgZ`$y?SW9?@(xw#Rk+2~^;Ae9?GfdcVva0}7iUWmSuLx+-g-QM?kH?9RK z=Buk(dci;O#1{WIdCbZg;sBzpCI^`+Q7oJrn+=^9T0H>rqtS@(@PKFc@Y=!Y;PK(L zeUm}iU6$yn^Dj5ne5s*SX?7}zZUprM4To0u8oaWGDFdHnAt7{%xzRsr=Ahn`Z|4&V zksA031O_g|8Gx81HqAG11?=Mzlu8@rSP5}p)?#o5#4vdp_|v1bXDrpU633i0DLJ8t zlQI__;8ZvvxDA2ADl(-d4OB*gDUnn=Lh5Bkwl|ys_B0|hI>y1DOd%#8otyQguUHFE zVrVxrI}#ITPZRLgUN+>UL$WL;OI+6W%COZvd@>yk_qYufZ(?r$gDj1u zlg`RT4wQ4Z&HVv{O#^)W=|#6AA&s@v2pJCPSr1g|=6vtcRRazAQbiow$W}dadtxI? z_5#fms_W6h(tLD)K#4+E62my>%F?0ez(?!TdzR9}E7?hJegd&@ITnsxQNyT40`f8I zGv+xVg7r09QbL=Q;FuZE5Z42aaF8g@VGR6g;~+2sT%zl~s2B}05CH|V=USS<7=RCG zNc_d3@K9`z+C!aAqO%FmuuH^rTT7!E_GLVYlHBEl zXutVu`ui@3Sp>+GBl(qDvwt1P)p%#x@z+jlq4L@LnY-@H+xtlgNlI7-dvlBtZ3iOpkGMRB^4IzBX2GV1Ws!FmoBQgbh6+}yNDwh+8 zaDSQ+NmQOnbco`(7R8ae7NX~J6>l)JWzQf`BR!){I7dMW?1(BN-mcvEW19S=L*rSQ z@)GEf;Hf;&20jr8u7~c3SGt00`$y3PTenzR@;UiA*yflikkTfCl6nCgn$IBmR5=iQ z=mAS0Sp>3k-sF_K9%i7$*u`*uxl~8~AU56EBwKZovC3+!Kn>IXae_VL)d%-C?|&!0 z>*=Kj-i?F&pwU1cd`$67V4*lyg_0ec?JS%Na4|I)mv_2y2bod&KKRy0k?_J(Pd%o{ z?@#{ZUxNJBR^{DEtuFc+OCB*bo4bB!Z+_9y5)LBFnA;}&SzjBYEUBG2K%d$($gg1} z;C_^lpCFWo%rQK@D;mnkciwa?x#e12SvIe3;I=3lBFhj+t4-PZyV1&mQDBdFOKKo< zVHF4p)3RF76#+U_W;ia_eb^)gp*h*Bj+7-!dedJ`i+|}{A5GJhDt$5v()(FxxAH!>g@oJ-W^F_NX&AT9f(4Kr54mIyL>I|bozm0ItZ?5W-}GbK#4?>R+F_yrTE zXM4jPS>bonX4@lALY_p_2QCqvpgLK!L+R>MqOAJK1DQK+uV0b{LgjEfpEw2GQe|nV zR5L(R%ohjO9F4PxdzuYjXpHM|72#3Uw<&52sXq(D80JCfriXBT!YbDiaa%J2`9(Bk z-p-~Ig2v4BzW4+8^nKoq8jsB^tlhZ2wo;c5e% zhn_LeTxEGBxn;W}7!Vka^><>rD=F6FOAAIxmlhE;ZD18nsK2-51F(4~ZecP+zQiB+ ziLT0xb-S7I?cqGg{qxYYb{EpLYC15{8UyAr8{!r3BmNcapm??m8VhyA+=;*L#}<(4pAk zR@irq&|_|`lk{|Ai`~TXMkUA@iI^tJM{A4Ws(i+(lv%1C_*?+uJ$L7xe5?~*d;h&R z|KczHodJKX^>y!Ux7~X4%|8xD)~|lw{QfF7U3T5ZbsDX7r4i|NbE#AWjQHxSfIrSR zO&h1Na;Y+Yz;Vh7{yI)MTW{2wv39r8-Kcdo>YZ+_-ppoe!HN^?Zj{^IVxyIBG;@Vo zELX*TVwp;4DSoL`Pqb<2A1{EObn^s`4`_LBept;P+qpZ zgz!xwp!RQxBuA+lD=cQp@+_=9zhl(?A#~M=b;2{*Cm+k)eHYbv{<&Y|PV8yb<#v)r z01blhj}w_t+uwtd39oWLL6qmu%7fw|TD+)t#Cx`^Xi{%K6t>`RPRAR(e+$dhC_pOCx{q{p8!(^g>%pw zXHc7W3mz~`jrnez`S|u z&N~@ocGs3OEn%EB2Rj^Dh+gz(sKAG<AQgznkxfvF@SmSABKa@8JV2{(SeMLji`A z$VA9fksnlP26baUSan>FCd<9l_Lgy^yyx0TmNsfgr~ZmQlARBA6#(ixF27#(FH zF7(xG$zA@s6C#r$d0-R90Pa_V#6HpQT5333jwUPV0KY&$ziN}ors9QJluI*^IxdWb zxKTK@C1Wu)#!~h)B>~#F79N-*3|OwV6a1vgi{wF^NY8KpCmC};0aCdc^V^a&I77rx zH-SCn2a8g}cDK~Vu+hf}Lu)RU3uWVxv(up+_9lerpNQwa){;(81grSLNSj(0#>S2J z;rNB>Dn0_7Ab(+U8XgU$>&NzH?z|(J6~wlAvY+S^f02L9Q-%=Jfq*yDo5)OwTnxk% zS(zKegliPdpM4$n5kf}AFuazc5bBozBE_`{)c*7+0lemf6wMQnuK12bfA&E9{=28I ze5s8=4j2-@YK;UB*sbjfx~byGRt5Z^V{<@oT!@^xwEE5L)_VsdzQfRjpH30w5n6_` zqmT)dR40-3)Fm!KF)N9S7rocMF+!vxAQFJ!n@p1^%`e3+V7}h?C1Nh&4C_P_SP4;P zJv~CWp>qiNV#EYiMC?yr0bns_dZSRrRaR5OnR4%*BVvUxdb7B4jb{iC!DH!7lBIEb z&?g2BLV{a=<_h37QJi61Mpp@FpAalHCPTKQ0mz^BFn`Xqm#R?8k#o7nG!#t@MNck{qC zGG9rY&sBSlr19c<)ag*0uI3xp?ucPte1 zP_tFp*eDk3$&EX4=N{guscTWxH}vO%mcqr9OGln8GW{RBo7 zgs%CM1MS%ooJ4YydX*9aQNU^?Q)#S|sPrey31VI#IShk{jVdGg^+0Z6HhgWX=RPu{ zOpze^&O=lnW<|Wmz-#B_OKuN*nBMi&;)5UezVPc!25Cw9kL0Ha*L6oWgM_NiTB7dl zc11W4qVB@sMyA!y)&vjrX0)ABNiTp;k>5Z6=l>^=-}3TUr!5x9)VQ|0b%$pQ%}-(m zXixz(XK)!YMRV(x>EK+9q8utQkYZ)z56IESZBZ6*oN022yMIV!!n}w%dY^%r_LXp! zrh-xca6o+KS}t5kTspJ($;w;5Oy7Eoch7J5Nu17nF|yNvRWWtUo_JzAfo|e@x!tf? zyEj|0^)zT>;Mm*;1D>xguN^q=`Rd&Am-6q@=Y!teM8=EWJ%kv7MWN6gL{Pn`4XIIT*rEqSs?Gy>zW;V3v}(a$wOMS{@~h(mx7~K@ zop;{x&IfNl^UPEK;jjMk*onhezi*~9A$s`HkN)bu`|f?}nO{8q_+x+ir+@nBBR?U& zH=M$|@4xxn6F-0c#b+P=`A_NUvBw@sqyzc-niiU>f~D9X=BLNoiLwXFl)}2)`=+O* z1${y}AnSbQCwWesKe2x*0oqfy;DaC-Bt{mA7v=~V8WEsSw)fHi`2Z72Zay4FW3F9I z4ufMLtXgjYbD&Wh)Izkv6D6+6D-n`!ID&#&}S!#?Ajf&_=2@Gnn50+w4nEXYaW?bN{Z|$peHJ9Nf5o>|{nc zD)Dr)dgNa~IfXucG#@#ettE zB5(}HBxvvx-O>;L5=kh)h_K*4T2h*$wO-E#3ljaI@xY12n0$4LW4MJeQvk^0lG*aI zS#a&$`=d__{vhLn^2tqtEg2oHVH8j z(Y$9hIqFT02eOOBx@?4j+%%0ruCas|4(VN9m5<6_TG?mzg1z=D(qNk8$V+STZU<=Z zz86;HX}`S28C_@ zbWdk#Y4l(Ht3Oik_w>_`0sfK+$&}EJA*f(0>KQjW1SNp5;Sk<157dpvh2MCJ zFjc?stvv8xn$=r7U`pgnx2ES_fYk?(NP=>M)wP==gi(>9HeqPWX{F81IG{k;SPtkw z&Y}}+0L!sgSz0o0r}ox+%y(Z1L7c&QF?cdH7h2vRga(K9PwWaC#v@31_T+~7$g2JG zdL&($o7dPIxfr5G#T{TnRWEH!dX-NKnbimP zvVBAY^ZF?YLV(GVY$5|70T445-od0tsf0$Mi--}PA`5!h}7bM3+=VcmXg}^D zdX_dDY5Y8p9pzuSac&AAhC^^1bB1&h%E`k|NJP6;qC@Q&QA&6X93wp0_yvA1R9C?A zFoUfF?~n`Stm1lxhA|RDs=PSo`p^yiFcDOO&af?81X!YT!7K6@lkCrq1hMHvVGf9l z1-o04<8eIO^Y2MADQp7M#L7wV1R4nENtKq$4f!ZI`J1WfWZlF`Viv)In5Di)56o*R zK9H}TxG;BqcSUnB567Eawo3_@kPWXl273!wp9qR7D> zBx*#?;y!v68JA;XI_7~VYaYU2C_M0p>CkB{7O}?Z@F|cVLdGQ2^&k|{Xv&I$nsmik zTTKpuFBxSaHWJE(d>Q|0YEBk5%tLJAlI^HBIqgY$mlLzgaru7qVr*+>X+$Nchu z@Ah>Cl*m>5Td1x1b2F(*z-eXGD*9Uf!Gs}oJBe<|-(H=_Kk;*NaOKF?oX57A5dzWZ zA@*;UxbzY-5ZqGqgX)+yh=dqIuvXbZYpKfwO)D;>gq#TxsFfh8O9*tXjTQZD4~aP%ZMg)X$uTYY6HH8cphl$`Q4~QDnqY zu027(%v9u!R4$>7`&~LW=}gHN^O2M1mp;F|dcgfF^97yr?}G>8_wK7cc%ZrK+2#A+ ziadOv^~87WMl0(v-RcxBt?ZExfykQ^vgrg&Qa=EL8jT1NE;;^eT^7dRAAb1NsJMr& zbRxN&Z~r%+Df0VA|L7l%k6!@%IgK8I>5vq+Jrb=Y3WI8RbQ5Q!3@{S}Z8M9h;K`Y( zz3~U{$v*OMr_j4E+}iq_AA~%Gv4(7{2zywgp2w*0Q|dPiz`%Ej|0*cX;IlG2^RQ#H zC9$0g$z_;jEI)%P@!w=|L7&QS6aEfBBz>##*UhKE87N-w9(Js+NTs6*=4{U!o)WWMMH4hbm`2Z}BbCJ2Xr;T)+VNx(5qr0QUf z*cHb>`R%WZZ70%%W(p;beAyux%}<zPV8^jWgS>AL?eB9<%bi4GEk`zh!*9I93-iuXb47wO-DZD<;b&l zvid^iFiTBW5L7fjqkagXL4SITgoFyv&eY1cskdI1H|^heWuqb+2s=))?OS^7sb2up z{^BqG-CzCHU;g!9|BrtE3b1cuqsYG>eDLnS`8R(W4*MF-+|{dBqlfQVp-YVql=~^@Q$)_Lv$)Eg5D7BD;;9P* zC!aFICDWm7Ch~WG_cwq0H-8ffdHmtQQaSSB$M5jd^u*=*`dEHqf4-Uk^ZnVM|Jf_Q zelb&tteH*xu>@4f?67~Q8O7RlvX*doT+!k=ONfQ)lhDbp>**1U8GGP7;Llx0Sz;7Z zWy*(l^=>atL2yCB4JS-30W<^@$`Z9KgNe5q9raQ^|JEJ3CA}0Ij233omDFPFJdkBM zKIKU+Me?#wnAB9Ym9cxfmR|=;M zYWn;QZqoh1)avBgYm>Q0f0DWD&ideY-(X8rOPcvB)A> zRV0g^&2F*{yV-{AyU8{*O;aR`#bU8o-dCEc^gi?6ym`I9=X!55s|VQM7vIgulQ*-H z)%^r~xH$KmI1yib_8)QL#DU;M<}y>mYnh3~xU2%?Mgk*22{)%{WEd~ba_pF|xiG-i z$_HpJDld||C;v#XI=H>>y)5*=yE%E)wQADCWxGa6l2*Pq&wE zHUtv!x4RKKP+zz%au0&S8j%^g6QFUEOvJjD4cv(^c!E{6G5DyLdm(y3@M-m8jkauGuk8+arIN{d zex2^Yz?KtNlf^mYPtF210IKMMB<0OlPVYo`B6fvjkgEEx0Z*qvHJ6s(zUluIkSAi_ z)a=q{KTkinAMhu!tFfj@%@VT0x^{IOC49MU#!f^_R0FN1N9wMHQp8()$CyEyXoEXw zyV7)A=5z@Tj0y4XUERviDS4h?X8HkhL=1u(;bM6881BZ%q3SH9U;YaCuk_jv*Yj%| zBt}m?sF0pv6 zXTyBxHdmVq=j7umR8nh(U^3@)Qp4NsMp_;D6a;2OM56#4+U6hv zC6Nex34BCbKpd)?4sZLojW&%C$e@NdfuxqtyC=c{ZJ|qS4$Ffu_f&C#j;y6`Mhc7M zc+e-7H{h;)i(F5YYCaquPLNEsAyAw1YPABXORKfg-Fq?3{1VBuDvcF$}D{MgIYI)nlK00CWq5JQn;_+P%QqGI$XL`P_3)KmYu*FMRcR==m={mx%ZZ zG4H)!`d{~b=}SfLbo$iyJITf0{_+RhHFoy1N@y~jU-g9MXzqz4k0mmJaBh+83rZl| zki9VSm`t=VVAvW;L6`^V95h^Oh22RSIb$X^fNTntQ1kEyLbe;B%jRMsw?Hr|oX;?!h1R zU{nMCXo;)#I8!T8tg$ehd-4d>p6GvVOh&zCEJtBd1(64I0cuglox;-NdesJFa_=t|YJB@V;-)SSx+>SPbyD@14w{ z7Z(rzL}va1*&>?K_tSwvFfhQ9QoEaPw^Qq8(H`BT>E60LX1#q|cKRgN39#s3z3ECh zeD&(*fBSF$pFw_q^Kbs2&Yt}k@K>#Db+2+(BGm6U&FjH0LEj~Z=>q~k=#+7WlSsCn<#cSCAAD07KV5ABPEbZ ztrw`af}}02xoiA!pcout;l^>UAT+=Ywjun7&M*w-7=S^sy%{6EQG<5e9VGRo)w2t~ znhKr4ameQIOekKBUJLx>YrrP&CqItlrUa31?mVy5?PeMsf(Z(RZHX|Fi#Hb=aG(=F z=*al;Ea@0+D%6H3hE?bRn)0Q$Ex#joV7e40W#Dd>^8tcSq6hYX8T6-ky7Dw*E_!Zk z?ZmWM`!O^6PWW5T%aZ6XKV3fkK{!4_xF(nkR0Z85X1WO`808Px&Cu#c*F5j(+rC5I zqo6=Qi5Avws3oC4f*P@j8nAU3f-O=DmaU?p03g7Z8IgB2%wl$64LFb95-3SC=l~W8 zg=8$#gb0YR3ocBVIR^KnD5Ala(YYgr=pxSWG8#W&T%2k$yf7c2O_@}3YX6~ZDlB$!}u?8-Q zWf-d!fLK_m-}>NpcQMGj8={-(vOii_2K@0CtF<1Yq{AbGgD|n?)wB#{5T@P^Xs|d2 zJz@hSlC?L!!$>;!L&K0VS--@e^??X{o$#lQa7k*gP5@!*?p{pyeZ_+R|` zH?J%Bd;9I*{OOQ_;3I6OMm&7|27s6Rw}t_C09!O^PXGnc(9O9-h1!A1wm%h zp-$0vd%gbdJ8yE=?9{Dhr(A5LU--&%U;5JjKEFJXuP0)~)mB%6Z?57&LD(~Piwjs4 zE0I&l@t7I%S#xayj0TYdj)2Ay4pyh<=lg5^x@gwgTKqc$vBwc8L7dySu%# zCpAV@5Wxiif#h{!K2r;?IX_7#(*sNay&01z))@i&l2EbzMiS=_Mr8RT%(g+NpAbZv&U=|Nsgoj`a+VUBO3V`vAaud(n+`-UOl$s{AXYO z%&(JwhhADb{2l+1k6JTPXFhrs;wsT~{SM%7VfD^8BCy+DOwN52d+zbvk;i08yK6Qd9k|Op z)WQXDXEf!`sw6mMXjL{~c&%=}+A8qd>ZsKT;vp@Pyam3u-Rd=w^u^<9@mY511nEV9yK?i9;SMZN3k%D^ZC&gf;3QERYQ;j2#Xr zNC^i_mgKufmJPa(r(0>*lM%DkIm1yPR8ZzbC0Jp2*df2z$yVVVAq6WX4hOSiZili2 zhPmPW5D3V?kFY>+n2E}pl&fcdlX>9&_)~`$!WZx_205Kg@Yj}U1qZ!!B#0$}=9Oll z(sVfA>7;=E*b+RW2qGliG0!>%^=oCwICC{M0*bYe6c;8JsKk;b`fR=|>8n&IpP-@K(_D8IwC6XUX0+;l!uFJ;*W~2Rp1<4R$ zJ%#O}01i;Ij(2GS@FyYOY&edZ2jQpuGn<&f@<|wJXfXEqOK^=R=@>2}U zYGxluzjJFLCZ7RFmlo-W5;zR+qP()P2T{h89s=i){y~8V5aZ)7xgU@9XXgBwm6hc1 zLhM>7JIN(COR}moDW4C)juAeg0e?oSltDXUi;Rh#h05r=x3@n``NIgy^JQii6IsL)p+=nxZ$BW_d+DC6Q zQpvyY+o)sKJr z11A?Lm$PTjo%-kh{Gb2iSHEg?8!5A5545-9_kik>DgXcWZ~o1}Ll5WkDGUC3#lY=u z?VI2H`k(#TpPu^s({d$OiFz{&H#7dFN;4BrtbOTAU%GGKU*>BG*$C=)o%i1REqBe$ zPqaGacRzUhkN^0O-+b$}Xv!DQ_;ba?`bHz1lQ9_r!JY}h3)`ptAf2nnQ|6=m70g(4xS`{&YHM&?meM;wH5vJEM9;yA=9 zoP9QOK9~!|irA05gQk*Kf`6~$U&~BpDyyE>}qNliD^~js(4}64K6vU`JP;YD9FC#AzYhyh?|d_6+-qA4V553szs7SU6jl1 zXh&^nE_TJ6k_Sv4vk%A@Qni(wiw;g4nr|1aHO+^cQ4lO)KZJU6!GQTGkvlFfy+wYt zXW$mD2;D!pGOyt8;a643jW@G=a>8~7QcAPb628WYi!u3nPx-vr=};5W)417e&h8{ zZ}1HdNUU9=?$!Xw5)!};wV1nd4!S*gQ@Ce7S;SvLgk9BVe0H`_mv~F}i7?m(y4I4k zh5eu-cUz1eNgNhlC}9sc0v!RRQ58rL0K~{mdDuxJd^51O2pEC^u#rX;CB2Gos`K*8 zT^w+UOo=DLri2~sxx-5MM;cXrXMz6{I-Po0*~UwStQ84JEz(F&P_rg$j|R=WlGf9k}qwi zGo_`b#4j97Ui+mxNUhb0W~-h`JB%D4iYd=TA_i@9v5PRTXOxOHS-(j!g7`xGaWfQg6mlT?djHq5R(bf5FfiR<3z2B8jw$3cICs*zq>6K00YRs-AWXyVn8^*js@vB?DevXl?$)m?(Dv(@%JL6F&i5t z7-7d2F~BgLRYSBTEp1dou)@<1^(jRh1Sh0wV?~+Lzn*i&;O@qo_)Gh&NiFnH{SRq`0ugD4?pwF zlYjPSfA-YVPptUY8r@zj;k)eknLhZNo*N5?S3#D5ze5Kf ze)gFsp;umcIY&)JU%I>i@<#aisuv9siQF~}_&`eSP8=t+C$W$jd52U!yh|L%Ydq#- zfD8#p;W!IUK_v`-`DI8$dFsLVF?C|1UEG7?U~hQ1f-u-XlByAGGF6g?MEDEnkS4GS z#$(}Ph_Nhu;!UC{v%FQ@xtoj@mIB$8#pDd+P0QQ#v9r+>UXaE zM0&u*f@UD6V{t0kS(TntR<(7kUEZWNn*$7_Qa9-(ehI7$O_4SYS^mk>^brOctuQGt zlAl6rsDNA06me3fdjngQqk0=Tp>8ilBm~f78-%QZ;X6bn(fpK5b;twvQxj(IZgk4X zlaV3J5JONpRnb9|3rSC1@=+ox0{*5WgPX-rEvk`CYt6p;dM{>NZ^};Zit5}^?q=ZR zi0?SRunH#_Ew^Ktl>FKC83lh2{ycK%#l?r;&VKv+!er=lX#0jlmS_ugnB*cef_P=E zC2vA--dzm3Ey~KrqD$ZT&es(A{nLN?--Gk03@oYj#NX1Sw37 zw0nd048gEjP#y*J6Vj0k3eq6JakkoD2Za_aC-UsLXC{!0g0LLy1aIXQM7I#b-Nvv( ze2Tz=gL8f^dMQzuYjtC&Aefzq=4FFrmH!^3s-z2O(>$>96t=%uIY63L;L3^ufD+D4 zx|KyQAX(v4St{06?UQAwBb!)V1hF9stQtA+OI*^c?rI_00#;(lt&XH%D#5@g01_bd zVfo48oI08ziG=tXXQ(q~KH0CqmNSS5T&pE-`ad1^9m7O99$ow7+`_LfF26P8`)ISC z&!(o{3xDVN%>Db4$A1${-=gM4+0JR4p-!WX`N_*_#6voWxbP+-6_FXwD%aPnk3+X_ z=ej-Fe!SP~_s)G4mxn{pD$Z`3wnUxcr?JZ%m;uJtC0CdGtAlKvK#o{}(4AmJfe>sl zH!Ys~W%Q+|$gsg5zBoDep?QFC2?L<~J&dH`l8E1G$Jb;kvY)7iS3d?FBRE?NE(-9% zC{4rt(5cGfS4~!lV?=|MTO(lfjAhVm`mbR^Xa1miE6i0`skMSYH`^Rs4gkA_*cF(@ zydZTOMldLeu?x|S!q}NiY1HMN8ldV*QkHoVeM)sNh6NI$6$}xh=U!^SddOi^qFr#S z3gQ;3!r8QdCF!hr){bQp(O>{1#CZxc>?TJVelE*j8PIR>zXu@`%?DDgfz%ws>Y`cB zzi3_&;s8Pg{>*s1I3LUc6XS*Y8g`FtC8(K4rH#65L%3wtg5Ut)Gr5#ssht1$?ag=n z{$PSV7?_R9<`Kw&C;-OQOPC<;fn;o9OU3WK?A(8U{-qZhS3a%W{5*8@r;%5`lKXBdHVF(ll6MBv^rb*-nUzmHz%h?PoMrY zotJH&!GH6MlfV4sFMjs3pIo_ip-{|pdbM1wUMwdsUpbd?;$GkETkrnnwby{Cf%A_n0){Jw-c$5lZ~JJ?33dsKRof-vCmF@a`Lm|XU=^Fhl%PkCILvoHW(zt z@>4R+<9fV{QZNhx=w$eeO_?TyiQnP>C=0?e2?T^`x92N?DH+|$cVJ}|c{JeM)MvpM zKUffaz+L>+;geMX<8K2=r_3u3r#L{)hPRu+oPW*nB#W{s18OCgkW>nFAFe^_qB%kg zn#BTfN#ZXZqy}weCtQ&$=wZ90X;!VicFM{~ELjRHEw0bOQ{l%O?NXxd5OtxZjx z^2=V?k}qk()=v#chQJLo&2|K-GT0u7Z<0C$07eW}Dk4-~QJM{(kW4%YeUJcH7P%3MJiV?w;r}MhgPVoP3KhMmz4=`Ro|8 z$Not=xbSLfC?Naohaf~m_wgX>mDmP^02vX181&h(JVM<}tT=4Cyof6;CvI%2cw02! z3=J9EzVPDU&?yWaRx1F0H1A5e~-I?BqA( z`-Ji~75vi|`nZz3#!!#|NE4QM2#2jS{4rVDE~!f2& zWeM;{HX`Sdv`F?k`Dfd;B(JfU2SfZ)XSXW@L4=D(kv2?@G@s~*oWlV);0&yi7fZF3 zV%?+C$(DRXE=I$l>=-(>F^;TRFtc}*QE6D~+=Jrz8MB{))Ie;-GzpH>NqmH0U^yWZ zFj_!q*Z2tM+>6g(VaQ73a=R0+HUlKWpfg4vu|=Gm9zovJ4gO+Dv{Gxu8|_5Ntir}7 zV7u9f)$5^pJJ{?-!Hxu9GItMg<(A54fBaVgf2b9sgwKgEhWwflFiTi zfBuc?`)_QN(jYeI_U(G7m+!4t+udAuT^9CnM%Mils4awL)o8Qh)LKre5(#AiK=F1r&yBtHqElH3I;V2GI!G5d>>BtoWlZX3e(!F4|)Y9|(a%>F@^J5@K4Z5~QO&a$B z*bz5r2!B+N%~d>NIWgvQ{E6ZsXtLAI_%q%>J}?=+U}ptz4Q|I8wf?<{ZiVP=AF8*M zNqb-a)z1|9{iA>M4?%u*V`ocrmcF}fZ&zw}W4X#QeMD&3B!Bf5AbYO5TKUC~a!(#v zcXnAnfT^g@64;Ts9Rd|=tEeWLpH|bNHq4+C)ER{1*}<7Mv6{?Ybw1nhlQLQ+kP;QC zgeQarV=vhzxy7d=JY8zAqkf2AnGj7FSt%|?}CvLk{xI!+_zZj}^d4OeHYX|N*$w8x(26v_>#hwZfX;zzFkD8=^j8PU5M9t-@QZvgERrs{6SE@% zA{NkkG(SalL7hwSD>wj!qxng~G*!_S9Y?%y$gf)noFPMFQo0C<`el@`F7HIIrAPhF zO>7H(i0stk&)lSUqyzvo;`OG784Vy1P)MsI6J{ok%Mdx!oJ}^SoTdP4MAU92n)PTi zJy*H-i}k+(_@iHNG84Tt7QBpUVihDsw=G(tBQPUE+i=>m*RzKo$-VGQFR?AD1B}SQ zW>5%BKb^07JL|D#H;5@CSoLicIBtxJ%?@^F!7iR-Kh8XGf9?1?w?S+hIV^#D%_xmT zZqAr-^IEPJE39;g`@L|!JX3228OEhX-Yy*dYGw5OkZ&wja1zD&%Jnx(WAAs;vrX^C z%xB+S^k49$MyR9iU!N8{6@}{Z_L?7G-C&XZ=%FOM5jyBOX0gIr3S}}e!2>*zhkr?8| zVC*wK%4-dzB9J$N!p;d0YEif<=7d9OVf+R2@TP`zaVm}g;bJlkV}?lxndTUeB0va~ z;7Q){XFY{_%9EO(jaHOMG)0U;JGc@#Ahf^ zniuUvFCa0pW8A#gU#NQV0>TlYQi4PD5=QQ>5M48<(^w}x+Q`6$o?nQ|tT3X6Rg7Pt zWH(i;`fwJ^2J6B-DakMS18dPpNDXvfG;UDo76g=~NKU2_!0&XmsO7;D93nt$RUW;` zeiQN*IaT$$*-a?C)*RtJ*h%i0zXyI1eeh_})&pZ0k6?n$GcbI+7hUhlS8iqDV<%Z@ z#Pa13zL~4Rz&6z{FOU7}fBh#4{+@sS3BX?}x%G@pi3;tM>Ya#c^R*T8ZMU^T&Eu38 zN_8&*q2A8a+Kln?h3~zbd+Nw~wh#V9s+$Y=);H4j`4yT{tHynBB~(^x$vPRzr%H>9 zu}iW1WE_Ba2jEMwWT_9H?uLjJR(CtUit8q96{{F%Zh!_v1VAUAUxi5HERwJCMstjrsa!8%pK-Ip6xOcR z2;l<6NqlxLO2`$BjIJFw?|gi4WA(%Fh4*tWeL45UW8visI1VN)n+VEomwEC9c9^TK z&;%I@j6^6TDZeNmqLv9fMQQ!> zGDMq#D*@M=28s&tUWy@25+QC7$xk5}g$3LtAjVh&g;jGL6PGCiw}=ZK$RCs>Rb#1i zoJ-)F0XHKrk{dvHl?{Xu@Eb)Vm2gKv_?{_=H@eRKAHdE#r)B)M&EtTIsQs6Jz1apIQyH&^Y1(t|KNqi zo4>l{KdBZ)TL>IKj2EUcT`a_cFj956-~_T>9Gf&xG=XA;X`H;(Mi=Q^tsE{^3pJTi zD$Ca2R~8czydX4)0Zo(uzamt39$f$i4X3R5cO9Y{%W(o0DyLpAqVIPX87%N;b%)(N`y|hLM(PU zywdFr2Dn>)cany`fs?c%=ZTMr#lkD!aPGS=^Z234@prhypbqikm3Z0udWsALm`2gb z;zF}c)Jp229I}WfbptfEDgZiyFv)!UMX>7Z(11YHZ0J747%kxPREx`CC&<}cqP*<4 zjCp%g^2P=z0W-4?5a_-hD4}s8faFLM_vjRA;`~hH9D_{8me`NI1Obc?1tA5?L6~TV zWI!4wtI=hZj1<--!kc@%iL5qc&y-d>0W8KI)XdyOi%6{5mQ51OKKwHvT5hy;Ldu&G zCb}y=R?^*G9(XNk*8Jrk{kR#(7KJhMm<+E0$XcCppeI4-vIgjoxk%R4-cOQ{52bUJ*3)|kWaDZiR30^UzLWx)(qsUo>X}?nDu1q zWO`YdSNPV~a!)<3;73b(ZhSD`W*onT>csDc|8gxuIVZ+$TKyz-QX+&*ROfN80e({cRc~sR$GXq2c+k_5I zbVZ7`$S?6qO9GLJjRPj6#L0p43`nGg@Y!@}!MJT-&K!UNxP;MSmiQV7)iKMUXCkMRZ=*nOTM`aft{{$U{#Uka( zju43luV&~&7R29Z2tOgt>Qw}%(@XT9cC~&Q6-RSiM#kU9b5`Hw@9%P$0O%R z3_w^cn07%(41y7?rFsk4(Z_$tyxEAAYyL=WvRLyq@}9=xnc~UscJj+yRYTEMEb&)| zq}+=%+-`3Rw7bbzVQw-!dMhYlg$#$eBcDz+j1RV^uU6mrRprfJ)INNxy*k!Qt@Psa z`LDf@JAAM?a&B8y8;;*>^r$%oyb{cgGm65ra9Z4qlPHlffG%Ki6G=34;RENv2THH~ z&{l{K2)5gN^#oDpYRhZ6f0U(q1qCKw~!5OC=xjyh?~23=%psc?QNTkVgVfxlU^(f}RN5wIo^uw3`2 z%3*&l8O*1hN-kYaNAnCx=do?B0=yPtS3p{c;&Qg)q00*6Gz}PwmF-&z^hQe3F44_0 zri9fwm8C>+*0+fmkS8ZW49IOId5s{5!7G!H`UQXkKoBjgMf1@_ITt*L7p4e?6S zkCf@9@m3fHeTH%q{1ON7ZY&Lj>c`;ko=_#j6+{h^W`Ku+&?)0U6CdQQ2m%oiLkkn- z@O>nJmN(DzpROq3=?GtEE43p?iIJ^Qw5+?(lS&#S5hk$(1|WKY#;FAF_?^q&sSO{8 z1pFD%b$f;0dXCCt`593D&RC6mZav8|56Zzh?T&1N3c%$g7K^wB?z$7{ZZ8LZ7&!FO z(ql(!kAKpcjpw`O{TR6F2eHlldtp+~pe)TMoDto1WW-CJwqpaYcjCbZ@6&0&{rmqd z$j`m8^B0l~Gd5&cQf>r-&PYKPGLA;`i}^-$HFc}f2z7c<>{BI1tjj(7WIMS84DGbc z_i|icuffML1A+$dkzSac7cb#=oJaV?Oh!bJ?0B*uE5-L9QP5^yXEb8RpN6*VWPnTr zxUjwOE`-&|yu;>ZXG-cp232fZ5=!>Ln8}Ii{@6JlWUpFMGYC3kSgEyYB~TQ<7$?P$ zA=%vS1oDLhOC(Lg5dy@U2y0jZt_o%#i6aV0h+TONoQ#<$%(}PGf=1U)5D(!hoEQy9 zhL%02Jqss2m)}Y}{V1u#`N21Pwf@WC-CnM1a6D#~tqN42r)F`Qe5yptfC^%TDLBzc zPB$TZnGj7VMosSFD+YrVp$=V_g*N#`$VkAr>K6EefcUsA2lP~C6ALppydOeWR^Ay8 zeg>kj)heMNsxm6W_5_j@>#MdlOK3!$RBp+5vR`>7eel52sbAb$I|=yPedbSTF>w`E z^msXW9iD94Zc>+k4{?KD628N^38V&p#9~I0UuHThzuK%7oow=Lx=nU8FZY6;n90MS4$zpySJtRqCy9grF6Fp`@hP|_T#HM7m( zd{v$f5Oe2Z^2Q(1Abe95tWr5mARIap$xqTF#3f~18JYrArIrD2w55-zupyfBXXN28 z-BdGD8&ztyljVjCh-(e`AUaoTjbJuDnj3zrboz&tE5GWbrZ`FOa2xtd<#3A(HJsr& zjBYt#=)m}%0ygL-|R}sk0SJo{B(>IGB{)VwyA*Cri;{J?&KEp45ci0uI1nNY!W@2*R07e7wus732~G2u1-hPz-E=$<2frCxD)1 zju65!;fHM;<2IgY2emtC;4(DeU;+F|qSeGv|7052HW#>JqSq{J!q$oQV zMG(YPs0VL?8L;vmYJ#T2vN#$u)5zc^i4whBqm#oQF=iW>ly;T}cI=vIs0Ra38_+Wx zleF5TfmT#!Vm2>1*l+d3yQxDDIS=eF{o)6`s7xUsXRML6XFQTH3qcENs@l(+nLw5oW1#Dp{zlo?i-DImPtJ?KE*_3#tE0Z=! zMz(mR7JvZ>ApM1mB7c=Iy|9-5g`~T^Jn}8?p>KK~e7E?(hn4r|BEHfbm1~`Ppe?SG zFT3%LZUoIL&%mr!J1Uu_n*#r}yLk{>wGz2}{p5f8fB8EgzrX(1|N4m&?*aZeDQ}Ez z_IeNM^m6j4m|ni!C1oT_jbNuIkxJRn$L>;0R=kNMTVofU{rA@=ue2Jnc$71+jjqYQ zNSj}@LoYaq_2Q%`-K<PwI4ONJm_S=m;x9E*K>t!3=A;6gi(MiK z?hIKF2F!Wv7SF<}2d)kf;}F`lZbDo3?*KD!h>FRKSSb;J7_}k0Ol%cU;&viA9i%|a z?8$=r_??>s8F=Pi>>q)UceqMy8Ms}Erro_}G^mpTjF738uF*=P6|sQ=Tm3%{Db_D15v*AlP25_$RA)JxAej~>cCe4y~+mm8Np%@!BPdIEw$ z3mt5rZ-fMDm?tp0M_F8=gR_ydEAgwdk@LhE&zeZ^2ou}cfNnmKzbV>8|knlu!uIPZBv&8xuL8ypEP?(&@uE) z07{wFoeFw(wN&y`T^_Z_SBJ|@keQ$^BuI84ToQ&zOVmTVmi3nTq9w|%HG|=td;piI zU9QWQ$|ykWt2HB@ZNSXAS&ka*&r5VC|sSTiGW=-ahK9PqtJl2m9RU|aBCvRDbV+Ga1V!b;(T7c1A^ z=oLM;+x^^0%`_J;EF?B0t`6v915+Ko1wLgypvz7`$PHVOl3vCo+4B9jnH&# zq~4AKMv;ch12se0%g3BY59S_uxb*#RwSAN8sg?DNmn_@$-mHK6e*Mg`PGaeHYw)3l z%8CPA8rfoC@!~9IpeMmAs9w!ufUuTMW+nUNo(0=2 zr{*R+ANxOhd2;DPTfCa z#n=q~PozLN)G!&^9bh3h#@5&v$6}%klf>iXgW~RpkNePsrVy;iJnCJUjS4IvzHkQq zkv!59%pEx=7|1NFhDjA>vmK?*iQws2zP~jWLc?0z6-##k5_(DA*yEjvY zp(YmCPaf43T+EZYVTU4U(DrMO$xbD#2#Am8>WCT*A}a=#vr)5aqgk@4-;x5O*P3CB zP;!RZnF8ZPXtoJP-NX%~5vnbf+WkdN5R#vd%9OBux&+mmVe?Gj42A&_GjU;QD{=wx zLTK3*Rzgq+KT`6P8X-(nPr~^ChNCv*Z|_1xU}F0hB8&u`F_Xsnx40#?E9uPNp|34H z@@?<_ce4AB7T=ul&Nw$U0t^r$`d!E0>xrjBt#+)_lE*{<$y;H?y2XF z=(OLT{^`E}`2_=CFt28*w=UarV31vdiQP6cKyav6iFLU{2MaH~z+YvXSb-9e9yWjk zIMC(bOXdsR6T#0xg!m5bu$CDs*5jr}W{%Ck*`19dYM7DkZ=RvQU?9Svx(pF-=d%$C zpb>P0J>ThRnrxYTi{-+)j5ub(My^giCm&F!===#%QrX zvNkTj89bDT2SlUTKqU}bMj+bpW+wv7#nk08NJw;BJGmfPoJNDlA($N*UOg7f+_LeCSfSGyL|y)pH05_a4bsr$f-7MaxFkBl z+4-v~&`iN!(4jsS;3PR^A$E3j?HK3H{ND#xR^D-oi~bV0D{|(RW-6tc^_Rpj#PKRj#iQD0R+eI(!Z* zgl)ZAZ3O5ksGnm_l4Cr{p^|)obaL11NGL%j#?a;YFM}kQ#Ar}tuCiibC^Avxr&MYr zOU-Dr6EEcE6X$RtP(GNe1*(l$yck%B4=tt`O-}eT zi@}^{E$j8AXM_1bp}rO^tofWJzcb|)duMSdd*H#`V~1N~m+i>`+PSHln~)yN;4t{Z zLhK5>!6C4Nlbo3hUz~|t1e)8?OeA5o45uu@9y&d8>Sq{x4o6Sb7(@B)8zWjS%X@y1!8Fsb<|I~#L9Dsc> zQ9X}UlO_wbL@+yrGowC~NIWtCT{a`2fI2xFb_WcRx7GuQ_7KN^(g~eo1A`}>! zOopYU%6VLu!V8HjI>zOg$Vhy|WpEs=%1xY~ja;CBi6-(9bbfWlT4^deHW!~A51j`| z1K>~`1`M>C3}5v*%XkDn<<5LJJT^B?rL1*d;I@feZY{uXZ0%V<*@KDQYe%592U(iX}_) zG>2Y9iDEFQ`zpiEdMipyzI1G}StGj*GZ5>gR)?)cNat60B7R6BMsa9eMP8e^K?1|3|SsCPzaj__bET*!a z)>)Q;ku8gG&hg{?c) zT5@h~^#A!^{uc`Ve)0ON7lw|HuACaUWhY^5G$D$RtS{JQS6H)?Znu)vH-C*4<<1=i z0W96&xt7vR|H-SK_YiN$VLb2mrR9x;emykWP1!AhFqO6RC_@o~17~!GRZA+tsxfS* z*^V(vakqjZh!vz`Iwktr{^j3YiEK+2YqS~cNpNu6{{R8Ctrc0ra}#2OTly6%$S(Id z3m5=q#2Jl9xvSBNFx0_2=p*(ml*yLa_KUpE4kQQgBKZ<eQ$<43W9f3O(^Vw-`9W3PFVE zM!3;l!MZIBVP5Xhp(Xer4$^tz4iE>JMKC2}p+7QWy0j3ZU8r zM5~i0y2)(fW=4c1EsR)^f*zw$1DR!UhMplu0%~D^t|3Pg+|P+^nI{npLCE?LCrSLA z!F*N0U>Cp~HcetM;Ps4M6Dh^a=TGb^D9#X4`AcURFY*`p+}^w-Y^aNjdq-L(w4U)B|)y2L(OZSXAd1rJ%6OO zG^9=JO%-|kH>g3NFvCRB20~C_CW~|7ESxO+bBTC48!zW01yZlfq|T4N7klw3kYDxq zJKZ|NLHTMv1Ho3e5GqvDl_C;ox8vx}JooHdmyRVYp-rFToliCCNT-`@tXwL7^6mAy zd|5wP?0>iu-6@8HumS#ZFdMy*tHuM_#)q#oR%T=(lqh(`6PF7^N< zVq}lgflf*_d5l7ZFrXzp>E-FjrMbk+xc?lf9b95e=n5=>jF%E)j7QakP$;3H-U^Y_ zxt-8MU&!v9PS|CT=03BNU{7C* z*=avJiH4AdbusrPB|0U`H$5lfUp|t3^iVgt^$ijeKz7glRE4JWm?i{CZ^UbDKV|^v zC(xl6Yco3u%!De5KQj@T+v9efScOl<0HN$S#y}V(<^;v~C&`+)1802Mu~c<6+gxjQ zWB&5oOm4W+iNK^A%)wi?lT4Ll@Syg?jmj;o8W1UOl)I%to ztkzMyW#F6Vgg#$4?NIBRkon&Z&FR8gu$+P508|Jzmp}g;m#di zq*Ee03?x&USTH*!5yx;|k{XWeE^sG8rOSi@dP?OmLrUTn?$syPCgIzR~2jLhAmIL;SqzFgHy z#w1?R7CwtXGQhYeR#{lijM%qwcG8MGMDUqM1AXa(nu+P0BnpsD2nRrE0$IBg^E)>| zieMBSeM0mHMp3r2x%G|`u>;^(uKO6FE|{GKNt4JL&HzTFmZiiss-=E%Fe7j3*9v!% zVjvNBGX_{Ts?9PCayLgkYQd^Sd$0W6^ley0I-oaSdKhgnx&nK_iG&_ghMM)$nZ!pB zA=WJ9dQw0!61h$SEg2E%d1?S{pgH%93#ugt6RdH2dPj4%Arwr`KpL1Jm&&=t)W}=Q zNqJWk8zSav4YUi2MZF?4*|sb#A8vk#bsa1^UqqUM1!p499@x*=G(n<|}pwQ~JUIH4Xi zOuAWbp)8%HS(hM0K ze-%qZ{)B^QA&MVT9&m&kfnMyLv~%JqQO##KV9P6W~~h(QQeiYI2P9tNp|d+sF% zj0aE8Cl)9+7Cg6-oLS3YW6QI#{-@+7LKhYi6Wpa*pzqirgz!x(@|i?@5T8YBphku< zs750`XU1g_&#gu~%3uaJ=Mn}?tifB|?xv)+t*vNiUSB84$+Hz8NT*lOhb)$?A1QH{ zv28KGU16DI@!j;d_#=-wP{NdYK&o{R(PI|U8ET1 zZC@&aFg#sv0KpZ(*Mcj&d`;g1`y4VM}QdAOOhr2WNVn~j)Ks}*-^ zYQ2}4nz{Ku{15+B!QZ#O_0{>gVQ=sz{^gd{uGH%02wC?*p!GfYZ>vZU8(}E z`9`w`9!wv4$oJ-V2D<4cG6h<&H}=-$@uH#`)J+~FW8&|)uuT7K!mK^$_C^NBM-c-J zL6|qjz^~f*7ZTWoKAJkEg9z646#LoPYYM>mz{vrk3&2p=!#0YWpHkEWtwILqds8Z#bH@Hd^XV8c(ypt&DlowW0SG|er@%-eKmEY1wfD~Rs z(jW01NBI4cCUz;q`inf(3>eSI)y*zD<#~T*#3cc8`j#~C3(W8Q;%{VU+|oQ!)#p6@ zahgF#G|jP2M(AB``9Q>QiuGTIH4`EfCYapAI5J)LOu51bq=P@zAFf`i`#`L!$aUET zehqP>9^wLJOo)$xGx$ql2K^XZxd5m~vVa&}e1Me)7%Y4pQU4;W$2Z$)%Wi)SHh+i@g`lAd(e;e$g1^GNNc}vcl zu@RY=N*b*&Aeb~jp5Wfx=^w2wpJZq_8@kH(yBKe5>>elZ~6`GI3*|Er>HPMl@4aXFZ=e z-}?q8-44jEtpj9lH!7Bwv}884BfG=kn_Ip@uHA z*_Cei&Ky1#yYC(6k#Bhper@UC8`&pLbcfa|wo#>x4S55@eFm`;8{wzZl~;YL5%UNCA+B; zoX$V}1c5Pq@WAqkpN@Nu+s<<1bmSarMa#B4W1d<&FNO`2F>h$+H|)EN|DLedOJ@bO_$|0LBt-;j{4F=S6AK*IJ)yrWcD7-i&;ohuDo3(wR_pf@DBg z!5>f((Og%C!g{AC8&uLg01E8|om;4|XO=yp7%3oc+eLuVI1;A^wyQP zfN^*v!!6i1Fblj(6P8a-B6N~&#lSoI0uY34ddgiCphe14Eu$jX1`})S=*DN9i$BZH zo(N1IErf?}Z+k@I^h%!U&G*YA@03zR5Meu-n_Eea&BuqPB5*688(D~5pO;5|R|#!; zW49L0AN>`PEC1Y6mCue=htE}~uT{n_)-Il?pZc)+;ainAeqR3RtL2~npz_<->nGlA zoH^FKby0S=GWM-t{Z1NzIB!jSCm~pHEl>k+(`*rKQ!A<2Vr?x^m#2s~AoO;RWD&XsIG8e@VQ?3KFlmB_B9g`UlqWsC5Wm7e9F0Sv+)Az48zrFvJt{`ziToVy@Wf^uDsNipTaV+Rqnzv?*zN?L9nBa$d!!&YIh4e zcW+i<@~eN{$6rY9l9Da9zc_+NU~EKySbhd{h;{;3-_1PyVBwoDZZx*dNlWB0(+vD} zd+~akC^v!R8D0bCbkJ+ArtxJ);RFHN!lO~BTLO%7iO6W*eG>7S#hUV(Hh*pAMr%6I zCF45fWwgAOmiPK$l{`lQMQPNDQ2|6Ow}^_tdB1``&dP_(k;KOG}5o+IcM>41-Obe+5!v5Sf=?W=TVqB|Bv+)(NLw|C zmityQ2z{JhVzK(kyNM$Q88C;x|K+L4qiBJ9F$o+5Q*@VSz|-o=G#G)A^D@I~R8W-_ zrQ0lafY7PQN81&;o?3H#k@XKFtPWPmtwfA^E7fZE@g*V74O^AC5%&U&R@1}P zMt|da_f^U7l0i~{1db6Y0-+d}kO>)KW^-=={&Fw9)=0}4et{(fG)B}28K44kVhl!T z(#kuLIp=`~@~{1%QuNna@<`nbAk)pZO!U^r1?^- zrFJ(K%TK`u+9As`Y>VWk5`|gHfh%?v(7SQU-^oCXnPqHrCte(O7Ndw#>%IiPT?X8A2X$8Tju@%ftS;*d-!0+ya;B9de)y z3d6NHuYH7Vqaibi-IK)!5GOHoayj@FJ66dPmw|&+yP6*9dmuxu%pypov2eP4?q~Ip zceO9S+ekI0PZU4%Wid6j zl&^U@+dfbx8%zR3BsQfyD`}yLkSxr#5fg1%CSe#_id~(LT@;9EqT9GUWd?4_c81x? ziux}yXJkkS)*E*cT~jG(D{kua3hQ^V4actcTH>nl7kNX)HiYq@1%{pKhFgViJAv$& zc$}F(SW67Wzwuo5z=N%u7i<|RW@a44_xmYIcF!X6(Cc_{7Q-MJNL1|j(&c%O0s4|# zdI?(8UgLTpXB_mfb0`8VP*Xt{{32(HVUr9I&G7OHwJFY{7z2jD_9qyaH+rO)fNv9! zTb-!ex+p-|Ybt{${rOPL9-tKJRKh4I=OVki!jmAT6)y1rah;Kd{-jKV>93tn-rAL0&zaUZ9L|A5;*PO>JeT*l3}@5saHqgaAGl?r~p*P-U|f)2aQx3LylK zbJMAYQ)T(0lE(kP3c(naFj^)6mg{~uW~CR&;vC~2@U&XphTz(**<3U7l%*z8c(?g8 zq!%m9z&7qf%qK;1;7Q4s*4DGZ(sy3YJg`6d`MZ^7velItzG^F9Yvlm7P`hnrc>&*> zkpW-6;r(!E^`q;aqYJSM*u0*Hh;Q-2)L7uNd`&*dO^~E8(E!CEF$fQ$X_X;L#D4fY z9{Sw9?9EMd2ZbsFZlE?mh=NN7Cv1f;WaUj=UCYRaUTp-%(`EL=?4mC+=N1E|sljj7 zr`?GN=8SpnSxjD?O8jW6TcWQat1j%rG;?r7Uz+U(WnHD zW%(|}b(~5!$b~p2Y*8LuC@+zjfj)ov)y_cl0Rp~|)CnsLyD@GAjX?mYrQ7{ytRgtV zal0dLZaS4EJBrYUOzFiytXuU2nrx-VaD(D@m!T!h-Rsu`$tN2W@ z?xSWH1K5?{{He3=zFtb+;})YdYY}9qWHN+y!8S?^f^#l$0QDj19f*6e??x+1b4I_r zZzaGbZ+aLANMTRf3wsQztY?;g@~ZR5LxG8p7+n+^`E0EiEtPBSLZw+)%N1s0g8U5r z_TU3Z7&)T_kQrLAy+$To z)RVsS>QZuYA}rqphkt-0fDHCflgb$)n69QIaA?!>u}j!3=am6^#J~pOV zQl}yi1(90sg6J;*T@|E+zcBu`NWx9jLyH;^255bq1iUo}+&n4ISnXe244J!EzzmR> zD`8Zz+UA%Le&{L46&0WhhIuB`NF~HHOohZuyQGbUi4UCn?ybH5o8P(8IYOg0$exjt z#0{AdMAXBxkqZP|#(v0IB7W>5(xVLGA`j7PjRr;_A`|_9AqV{Gd44Hlfd<>AjESSVkg?g2H@dA}9(m*ECmzI3ggnp@CYmd09 zbG=|zl^ev>b}P|#t&xIAb&NNNPK=)crYMww2Sx%LNEmy=R<-pzkwt#@z2iLmy*1g} z`IpX-Pr5sw`RE87-DDbY1FB0AbJmnIM&m?E=K z+eWj9+RO;ZP{EfOP5$&-;J@0jw|-|_55bD%Y>JoBPP@DLynZ7M%Awl1sF>4EA2IeO z@zxsl0KtZYN~2a2F64tf?$D=X(a9b}nW^x#RKZK`NS5aBUJFDC#x0gT?Jq2;i1>?S z$kAjXdy>>Zh@(*qk2FL=XS_`yCD(IrwHYwhb#W(n;wo{Nu!h;|Dz{tylasR_PEWi) zJ@)SW)i(ma_-5vjhh%Ni&%al%CUsSb^2V<^wGt77+O*nAJutlbk!+{u{a`+NURB9e zO@H~y@`&%FvA{_h#p8%1m4=_BW<{sg0``DsZ%SSjAow)Q)RnfY3|Qi?Mi{iVx11?v z?}ep+GkkOHlf~F&grFz6N>m3*>8uuikubyoDb;casSOC95m|ri%ZxSKNucmOQ?bj- zkbTo2=qZ>I1~6!@!UMO{9WK!?m;nmF8^tUGmZ+iY z%y;7B>(#BOflL}Q-#!(}jjM4ZTUESygmD2*NT@U_p60CPo_IX}!gG2rA*S7mn>|pH zME^!zW&v>$y=qC?)t4>yNXZ8Im1>}eI9=lmox;6$;y+5}sw${a6 zV|BSF9?O08`8A&`6$LW|vMY1(rRk_=KCv9g+HXn81PKXPyNR4>h48U?br)KQU0cf3 zgM~`5ChKpC)29;0zrC9AkPmQgxT1Bl9O`nioQf0@1UR%nR+uoWwHUC1t!WM*h#6zm zSh&{AKqXUI8fYEBhl5~m@FvR=Neg26^hmf^GEr1f;0L2ou=@4#U=+B6@(@E7^ zvT)OFNbsOQN(n55(C|ciW`L+l34_Gs>_8bW&XkvQfCm|A__&IL5Tn-8*AP2p=xO4~ zL%C<4TF-55O#namxG-iWxosbn7&oFC>eOgMucyLi2v9_4>Zd$$2FOdtA-y^g6f&I1 zYB@-`(%b1E_P|~Aod8ALb4!v-A!nRXfueRU5h6g7#8qq+EzmV0BqteZ(;^OT1qkO7 ztOOP(aqU)99)a18Kv`j$&cxGnk@BO|1T*2SF z@4pH7t5pYQF$ReGd+XU;Jz^%z22%!#kTG6rh|!VeEKYKaHx1N-onY9OTgJEi?KPr> zuRNc7{Lyu%zrQ+GVTI|Q?M9^eng?LS;H0-c7-sK=s1tqJzwm<>6zf4dw!}}#n?w%` zL(l9a%$VLyhcAu=PIEx=(g)CPue3yqw!iw97LkngZassUDPx!-`3@PD8A)!=m||}_ z>X6nA$c9OQ-JvtYNis5L_@y4LQwe^ENOZ)L96~!NZfy0$@+UuuKmDk4@L^exe($}R z2OfxjU_@(=0EJ-Gm1z$Mk5sT>JVk46%0$P!nPhC3wgO_)k7KNZf6<9#KwkBpwj z2gx;xoAr!dB0&R7NLY9`K!q>})*^?JK8p27t_F&As?AKjmANNYSxnXC`-Ap=q=Ww8 zPtObxS^?0|ZIBsbXkTVzGWc1+piv?qe6&0AbX?s=iF`@JYw1xkfu2F@I*)=n1?c4D z&0M;N)=6MyNNsX?>=J2@s@&!af}D?CR=qY1Rzu=MB3oc5p&`lxdVKYo1eDtj0Udykc1ih^{6bQ#@yoqVMP67Y z+i{-mp!?O-5S-A3tvtGsD*ohq3{o2tm-KebwAG3?S`qXPf&ZYLh6_n6t`M-3FnVeT z=EmVf&mczdI%eZuQErKR+-gTN)pRH;60_%XPd|}+{^@LV48@^eU=27MYe5l6)hgFb zSkba9zq{iw0K!+JmB_MFFVEa4;yYo8ok80h$#RI5-@d%)f>57IM^3iB8+J_#(QAwVIw8yk}?V`|M1sD(ZfG||4< zf#nkCIWE=xPI+0LiG0?eKr!`Mj6qDX zEenjW6Kb%$=_UJ@kpMzdL=I7dy)-~{fvYx%L1-3K-S<{2I0aq3iQ2Cv8U;Cbc4 zA3Bdb)QfC=dm5r1ZpZjxZ)c-BSHdANK%16qwj)FsYaukDj<1t{mWF)Cu6o`@I4Gjh zAZCiFi9&X3Do9mH*u?D7JB8JpW~1jhK$!4};!qjEouMOvg>+^4lnPD8#kKKe4hH%{ ztU$Tj&X`*?0$3yst#72`h3RB*nji`CLpT@!y~f(Hc~w2K9q1$HlcmLvr)L%U?SDOX z@M}wlzU6)VgN7nMx9TBneSpb5C={G~`Q@)D^7|kE$A3CCJ?vZS?+8I9^jEFImbX-I z%SS;lZ+s0;#Kx3i#&Y-_QYH5K&Bq3DJ@Sz{0yiQtY@Y5TcKi#&CKtGCh8pw30Fma6 z&j-#!3^n;hnEFCGwL$jkzZ2@Mr&Hwx;t52^A|9#>>`F6XV8Lp-8W>(ZHtai2$(YPU zUPP_l)G)Dnz&tPsq^idR>VR|89j=uSlk+*5h7k>s|=`xyE#-_;tcU{ zpmlU%;#+@S*89N^(hoi0?7!c8@{^hA5Hvd*S@9=5nW`^G44uUqiCVT2)u5*P0iq1C z!p_S;w2nOkMsX{=k9LWfmdTyOc#JF`&(E~F{R~Sb^p{?DcYB6DVEJy+8##chaBhOg zNiqs$$6zmzk$sWXY&ZZUNYiGQP>Ly<BSUZPi7xlzUe(K~zef0ItCtSq(j*VElpdD4U=_9CXVCB2>YRE+Ex2=#OxQg^>u! zi$p-GvgO^xz5LROJL6)YBnALMIN$$JGz?%;7?UX`Gao2S3sVE>3TGh5>SO@z!u*2S zIgfk{21SnQFz8!bgl3}W=_dE0eyqV~UZqC3fN0vnECeRTugD~yc{Lc7z!+TvJ4$wx z7s#W;5nVL1U_Oq_ft46l<*KM~n9&TO#GAU2EX}WF#u!U+vfe^mF_da0e zuxDV2M8W|KbG!v>8nJGCp?dtS?866~{rk&5eRZQMxt0QTG`<=4$rjY9q&NP)g!!gR zva=7F5+RUiiIT_`Irn-p+2gJpoZ4(fYpu*;ViNRYD`}klICtn^?f5(E+0~6kjH(z# z)XhE=?#J1G0L?~kEM@Bcd=)q76xK?oez?&y&jN5)^WlGt84Y3&L_mNhqjMAPhsg(K zYHeF>j8Cu=GbJOi34s1@l`IXCI<9ymX7Gn$j{#1Lw^7X$NWbvOv=0qsTUzr$*thIsYri*j(agM_{YXnk_a5PwyJjYR$6YrUAnP(*!a%=_wj}{B74;TO;x#u=!BIm~fpI!GHz3!FG=b-D} zqo?Oyn~$DDp(;iO+l^Kj$$<5B=t3MLkP;ab_L0dL&99oB-ua7)!F)6q%g-pXL~JwL>p1KK^#`$R}NpA5GAfYR&Sz2f;kW?B7;1F+V^0|NbZcSi#>>g9;!P z8LH9<=WD@4anYL|8kZ-o=ZQ!*hfd4ss8^0YtEEL*{<@yoCFt5*(mNwRpk` z0-|1xr`QegNYT{*k*YQ8Q_MUg=*I|>0UZNEQRkh&A3+W26ZIB1Su(_DWJXDT&6Bktl_>mzA29WujBh7l1O#PWXb%X0XE?_(Fe4<69G&tq zZonloZ7KUUVLb!_a1Ta+pZFcwHQJ;ES@eV42s)?`YX;L`I-o{Cus1ax&3og;6{qYk z)Wd=73KG-a?LoAHx1&e353#u&Ps%oG;pUAq<=1|c5!iQs@f$BTE}vY__MdiPg1Y;W zlIAdL71XI=TK|3_Nd#=mBqBni*YjpEghslsfq>+GG=;46Byy{_BDGe0cIy|3lHf4)1S$m5NVJ2N#BI08w z*bhQLHK>wc4Il$f;S?O~+^Yo_AQqrO(gq5}9=MnBH-0<7C#q-UK>bL7=_?M#hx5xjkv3!54o*R0$609o@u3VPk!r z5Y}H-I6zn$u|@Hmo-s0!N_1)SPSTP^`OM`l!o3dC&;kc^-0}b+WTMT8@1vXkll+}n zI2L*F$;=}MerMi|Xtxs0hD>UTH<@2~hGiy4d+YIP+o#JyuwHka5F7@aNd|Lnq!Yox0D6l|sArYBafnLx%ci|?)2da`s2YLCZ zjH&Gm!vkV0KoDriNC3SM%Dl-TGZ%h}&cZeossZpT9xdCm%S@h?=bcD|W+1Pv!P1@L z^Gf160}1jChKd)U<$(fEeHy<1{rm%OI|skEboe{|CrS*1@e}rCsNmEVts?B%l7>_f)eQf_PXU@>4)FRKCu7x_9>tB zja;QwK)QHtqF zgn)w+D8Ns)B!q|%6zA)${xfccZXB zpQcB;yX|646Yva#fK}o@T|l1lNLpWkFuf)t=c}vbhCGm@S}v*l;eV4WA)Jn=*jpE< zO>jd*%ZZ_K)2X!57=We^H*tnCg{rsHN!$ZCZMC*`S0{L3`kC_L0DwT{bP274F8fB% zO(Y64IxwYqE@27-EkR@vq=qjk$feql(_bJ=&&jfgo8~w`dG;<#lp*CXEXEWDE=`&h zFz&&}y3r-7B|#F7)r{yZYOwjk5+Z=@opUpL5Q7OS$APIC2c}NqwWw`9MfxNVfFacK zI7uXu1a?~%S|O`yBPe||>oDTQS?bAFR`|P|xJo6*ZkO?bq|qKIuI8fOGG?g>Svo@!r}f^&h1v4S+wW zRF`F~YLwK>ue;8@sVd)I^K%zKp;+_D6x8OvM|c9hfhlt`=*XNlC*hw=)@)~HV{;t1 zdkX$*-Z-86%Cp)1_dEOc77jRrW$N@WX_A0Kw)UoE zaBN-+kPn2Ifp0&9Vk!aocoa}it}2TopxFdODnv@eDF~~e zTBi~!*4JPL!WT-L19T;|It_x5otzL5Y(DkNT?4%%j3_e**#vj&D3K$vsHX7_iK$9-?)% zid~6zxeBu1=_5CMXJp#%z3l#9B@Vr~_}E(oz+bf~a&DOKwkiHY;LslIaS5($7uI{3 z`T5a5`ICR4;P0zneVV^n$7}>9FbmX6!b(?L`A*kqcD6n;sqfqB*5ZtLfUN@zTcSrq zW>O(&n-Lv8<+K7foNL#dtMeI|hM0+7KvUKTjm1h1y}h2PefpkQ)J%ULb)|MM-|5Jv zj7SNM56<^=CB5R^k~Ox&Zc8*F2zdJ&+yjI>b*n5!Dez_=utJLJ7UOhh60JVT;V>Cv3Zi$*3#E~sp~LF6PP7&o64)LbhegYoK|lIlf@Z-=En9n2Qs=;MoAub z7+K+!X<3Q>#c`Wa4eGWMrbi%V&U=o&ntkX%D-8X#oLu!<;zzknPtY>bYC8uRzTA14Xs6hpbV ztujoeBkvyU^~$)8z$x(_L7J1P7nM(|c$V6cWny*DfFqaGvGB5&?*cXn_9c8Ds?7MS?&p z0xpr)B7HZhn#o&K3)n=3h=YjiN!>sJj(OOmM6bx8dY8T@NI(Hx67}#Fqt3x$B`3LL zAGE9S*_k1(l746#KpVfHmq2M7E|=a(C~n{k z$gkJw!%$N7&H_rPJ6@Qr{f%;V~?d7VB+U&qO4m`-(Q!>!JLa_mfW?boSlX zo|SLjV+=T_IT%#a-4G!-UQA9UTKRer2GAh-GNZanPFX&4Ni@`wXq@w?k6eqNZ;vde z(IY20#)nZZ5f<}+=eF5x7^kp?M?E+iZQ)9KixLTj3hk7Mh7x<#oY7_e^6nIaOB}G% zmDf&bk=jH!W&sAMaVjz*!)1n*Jux|(Cn$iSB3SHG7l%dx2|~Jm2qk4wD0U2 z*(V+={o)6d@3hTxSOb8FyxdMV)gu&kC?U*&3I~X=1EwEZ{YVA?fm0)EpKubjYS_W{ zNWIt_8d2>BoSSq6Ed#O=V5w9xLxgbjHNB#)w`DtV#gG(b?JF(nb8VlPe- zLo^7$Kgoj#5C34+J9(m;aD0hortegXV2MBUf|^kuHl{RSqV!9HKL^%3ApMvd^x%&} zhhADbaaV5yLedy(wU9}BKRN!+U;Ar+4dnNC|L*^FZ0z#Rjh*R2 zrJ3h0v$dXlR71(`aSfpYx(4TNp6Mo*?_RhG%|y?SWUgLyuH4Gp7&C7!B6(T8w_9v% zO>P+M55>`)Yf(aFD!>(MUTW8cO-FyGwl2Ly7wsAs%&<4Bgk+NE|wFed?>dv z8(*A>oLNm><&v8pQk$)WT*)o)k7aVOD^wUDB5;2fnA=Xh8E%mcJIQ=(GWYCL*@F*9 zQ#Z4f#Y(gPW&GskZdtpMO+%P8Jyo29r_gb1fR586Bu3^U)B`bzY=9?!<`!-h%}>ER z@$kyZJHxBTrb1_y;uk@~6M;_|$Wad-jfkjW9z&#Q2%F#*Y%!FZh!y9YYA9ZuqrZZ!Bj;&|uI)keU7zfr7Y#1$rP18u zhXwW>|7|6-ZF`OZLOzE2InQN<@~J@#jyiX}9hvJBCHG10r7$W6g@YA#ztOB!M>wPw z#U-Iad?hI#3PT`M;WPP~hhu;gWyBJCNrpcDxl`Gvj%1&G5|Mh6LwH?a&zYw?5w-+G zVC=P)t1V_4t!}|cPqr*U+As!tSm3~2U=-X>AGvC_1Nm{RS2+MoaDZX==VOc{)ubT` zV|4&8P?6d&_9j**3m9a-A$$jC1`RC7hG(Mvf1H(>ATJ zB$DFX99Y(D1Y=;XL=SBRb?{5cmiaI%K^18$KNJX>83KKvY-tbBuq)APe9&r*{$gXh zPVenO`Y|`?k#Bhpe{1!~hs_VBYVA%!-YsjAbnb|9c2ZvvCK)X+kL}y{zw5N$!w=s- zKR=pIZCeaVVJxTK&SU@E&SO#QIezUK5(Lr%dE>m;q!~Pb2{6~KFJ&uDN6${AZ%mpc zxoD93`*m&xUR&ozB_!|sK6Rv*l8>-clF^z@Kn@s^B~wO*8S7*#^z!X)PQGAUoCh4hvzfEFV~%q@<=jTNk2Q4;h=Euvn8T@f7gDQ} zv6YGNbs__?LbYS5*^YW$-ylZ3q!OZX#xMCc%u&^6>kSmv*pN|gC5n8D^r zN!Ps}T=Tp?w0ev|-L!m_=fpM7yEpxx630Zg;d8_>0x~ypOwB}E{=%m<4^S_D%@7WR zpsmv!A=hm@mN>b2Uf#hdnFnzQnQHZ32uRB9qKMGQiX_B~@lupw1~;M$J0Kh&dZhBd z2SZ^PjXua&?zYJg*b1Fj*uj`!Zgc!c8YcTvyPIi_V^A_gj3(lnG8a9`>llF@hha2`ni~;2{hEnhT29XRoaO15%+J%E0oS?{VJL`e zy&Nol>ub5k4!1_mZ^#y6vhU15NlRQpL>QTgP1_7n^D$zlBX&B$T|maxJKoWwq)J11 zme^z#QOWT}24~Jx@vQDSu-Re?WM}HssrMDrx7W? z_iN|CgH)oA^M0>XWQnv2vP3D-{L*R`{MYQQ%OdesJEo`|TXoMip-=)S+`>7KND=Bl zZh+trU87Tdh)IQXnSr1UG;qsZiupKRW(biQ2CU#07zU#;r@W*&z?a@i^Zh5nfm7J0 zIw{gdFWdziSPOon_+~sTD*`tc|H{)e3b(s4WBF=zzc1zU{u?*W{wM#*e+=^bqd)qi&p-bN@V9eg=XyJLdqb80sTU}j z$G(M)?O&8O=N;SxpF*U%PHtD*#$p3z5eWR-IH_Z1!k}Bi^<(ek9)GlX{WNh;%L5I$T50Cj*8zX|w(JEhuOtr;;E!UrH?|&RL)1wGrcNqscaoK68fte^ zt!^TPp_(P6?q2LlSlx8^PAi~J5t^({A&dc6sd;wTr!}&3&KP> ziICk63k^scm&Zux5prv^ql8mXpw!up%gZz`JlD(m5O|((oq5NO@;klHO&G1tPZ{0> z3^2a3VOgWoqH8x(2#2L+bwdW0G;!Vg{)q2m;K#_?@zJ#tS61G+y!GM9pLq$BMGzTbPER5`Vkq&87z*f7 zL}*Fdqa^v8ct@*f9UyGmLxP;4wrF9xBYTtfEfPK|O?kVXKFj1;)kDI76Zo-BSaI+> zFb#k#be2ozhfOcEFD>)6lAL^^Z8Na;lH^XZKG_Ad0T^sCU!J z5x1F_l3hZmP-hc?o@5%}7viEL(cH8_qVln(8G~uCd)!8m1PY*L>gS+~gj-Rt4jFFut-&w;+d=Pd8cAZKu>TOeMEzH zGFXWl>Hglg%aGJO8AtvQDrO`HsmT=^(Rf+bC;$``FOt~iV;8xR<7j>oJOnzAinNNfy?r7MBZ4vdle0xwKAjQZ=8v9J0pU=i*lWNLPQVa7pZI(ihg|3bp zucT%S4^>hFWzfq2cIT3g3&%sBN6jbg2|B2T=5*R#2@6Mns9>{4oBc`+0Y3DvM9;)k z#)@vlK-vIgXR7gLJ4&4hjlLr&`#1x!(?L#}?__*&-f|PN!m2HkN|-v_qI7+V4bd*G z*vjKyd6HD!^~?4*yOC%_MZ`h77pir<+1di3Z0|3qq89~lO5WrUanBu*u?jMQMt^EX z<9ePOWsX5tCAx^()R2&2G(XMA6J@o!G4w(QiEJcMh5_8}&x|r!#+;~}nq7U_i_n7m zFXLOR1>>;{Oqz`ezfdXTfittgYnk%mbDuR2f82QR&GezKFF*Er`my8fm1IZ(wBMiq`JaOP1~zuqg?;*JEe5ZE!xGXUM-Y()I;(`K#CCkA8zKl0 zka0cC6?;Yk1bHp5Nk{9nek3sEiN{Od`_@KTzBu3NWHZ%FrJ2Z-7sz*bWjHt01{TOy zjPtd2zPoNi%0u52QrXG+Yw6T#Jz=hOPZT2%Dw_|Jrz1V}s z_l%hX9SM>pTzfY9$i5~08L zS%K1!@0e_nvw93yT}jBEGC&SVshd+I=<4df9uA)lqA!WEr?$T zi$=9Y21ccZJbi=6yWAyHrsbv0Jl7{W7Lt{!{n3?Dt0_;VxsgN;nxr-WBFbKfU(vkC zd5hB_+eb2-dz#u!+{af&&9l#+|%L)Prz9a_m|4vjVt{H?OUQRB~eUd%$X#5+`G2AKCS25yXb{r77 zWZr)S)5rjzmz0+b?f~K$jZrNsP!2IFbVN`N7HSLWTBaOpwxYmI5(fOB9qiMSyn*>) zv9yJtI5SYE5&@AiIF8$!sGl(gNe-xIN4FR)oTEn-9mg03>VPHU9WG$qhYB$~O_szL z%m(3raqT;XjaI}ws+MoXj)yMH$426XIocwi&@?s6y}|QS;Y;J8E90SlGC(*%XI!2a zcVp;%;Gq?S8N&e0>G@qB&!I{NSM);bRMNY!c{&U67sa7gm4MDu!WAM4_N;wz~2G2~U{i!yXuwkzeI;fe{@xgGpoI1R^32Y-^XlkVsBJ{rsIvZtzA5*N6n+yZ~rj z73wAo*p2Vuhs5Jeho3mngC6}w>d-e<9)2zH(1#TrS18%O-#t|;5zyX0`hWZb1%Ge7 z^$Y%T(iT|X$aQ)JumZ>U7w!|z%6{gy09K)JO~Uy0C<0IBnLA z08qF^XZ|3nRdA+MJ@GEX)ZFk%T(VG$1myj;xnyZMQ}z{V!9qQltNN?0M5iZDawX*# z=W-R9ze$%Q0-#NiVQNT!VGLQ>X(Z5I*Y#+))1?My-K%*6ktL1mh2gVeY&R%QHM80Li95BwkHP&+4?g# z(H+$4$ru%FHafYMe=2w6QRnF+u{E)90w%6BaPOT6rzp!qhAm?w<|sCTfPG_u6BEHt zZ~0H&44kBE1D<;)(t(zuMpOoXfe3fn1d&bCBEnIG;J#OGF@tK5z)bW40Z{M4bHOU; znkthu^}kvdsT zxm1EtZl=&c)BrE9BrYz*&H~Ha=P3rSl-Jn~G75>xHf$-Bn`pGdnnAn01l`7$NKvqb zpb4f}2_`Ewn03&ke2>|F4}aiZq-;!WTT*8vnyakfgz$h@V0`(iw{6xDU@Df3D&qnXK4jZj5H1Lu|0*C>FT@jm6&l8$TXl(ZQ9 z9B6L9ME_9>UXN;;okXe}XtpB^KQO#zOX|Tp2xND{)^|^|yOg*Nj!`GIJVQDIt>@_@ z;9e11@*B_R4nESEAF<^vQC_hEWW5X(bJw;;U0?Z}!)MbY1UJlM+ru)GEGcHO6j6?n zt+sqj2sto_wbCZ02;omZ&)Rq~$ZD-sR49tH2``=XL_uu_@|IN(I zP%zkE;t7OmlK;9gg@&#Mk)86fOaqX)`G%hN#y|gFy=Y1h<FMG{`JnNxK z`00SZLnCXST=Tqle(BAD^ArYMX)CBH;M_z$mXeyWP(mnXuq zKu{;l6mP*iT@X&lPbM?jIG%gz2ytgUyR{{oCCb309^0V_WaG=72(=RWcYV9fO(cMH zd5PMH5oi{~Y@1V}1`rj!pmnT#IdPRvg^LBU7c%77YSvBIk3Tu=?7u(u!jXyjt;b>5 z2`B{7sSq^$(F%P*eUh{`M+*pfT)vcg851IQV5`Q4B@IAGuhGsdXX?|5x>-4q0geza zFj`8YGV6O(NTX9>5Zk#q*}COAaZ1A+8b|e%L6P76*^~Ll{g3V$FNoDO5AQcixLr?E@7F9UYSkYoDN@Hj1T$J zbBl>>AQ&4S51kzk%f2w?8R+gBM>24zKE9K*Q6<8hu5KnV;4<#E=ssP5F?0a|^$-*; zL)v4UilPYx`rr@Y6J#ifjUftmCBHAJc2FD!CN-Nc^&wJSn}NhkTe9IOy1)z+s>Z+j z)$GFuniH38zbw&N#fumi_v%Ti1sBi3g-~ayqqu}qm-~IaR>`<{7(C56hcD~)|&+1td zCG3+;DrSfCyCl346Qy4&a7%R1mcgR1pH7d$d0MyUp^Xi}E3(~8H&gli1Lywxi=Vt* z!>J8b8~$Q#buE3p*&(;es1j3j;~1OQ5i&mFj>)JS`@zcy2q1fRTqRzKVfRcH=%xOT zZXbNm3i`5@4-idQ8=efEUD{mqW_f_5710RUIE5c0fP1_fB~R_L!m75B9TZK zAMqxK(xt^atxCd!usRrXgFGb$OXeZ<;9W*9!B&?6k1R&w@4!`k0nri`i@$4V!c@|w z`FjvY3|{5svi@i0u_}a1kiy&hz=GJI~;5)z1k5 z^ph+Lng&EOoL$R|>edpP@Z3%%7^s)h1^y%__a%rZZ|#^~&;-BK2`)rF^mH{f0&Le& z8Z8nQiIr+tm>qIpD5;K0Lu5GOQLegz#3Y!SSwpb0ih^8-t>9WZFv6+uL%K;MnoEvN zN3PAqE{mq{G#3s)gYJ;mODsG0@2kA|^V{1$&~C|g5Jx2?i|)+6#J0d+g<|;`;s~Zp z+@VhGml_PMaDdlgh47F4aT0-NN=v?6Em2y+g29FAr~`z?)6-|1d++uA=G(W-bciL| zLbIBr6$D#mN_8JHLHmbq^Xczm0XT1thL%S8nJvm06S~+IvP2C&|d_EPuIun(b z`8A3uQAU1)XJ+E#lcDp7f_AqmG(K)^L&^Pj;F6_kOP+yZ)c}3l76hyZe=xSBS}XyW zh^TP^ndXC#b?6{sdeIdnTOK-pR3q^ka@E`u)XJ&?0S7je^dG2ZE3$Zl9phA59)|x?F zkEnuW{$BA-&2?q_4#_A8p$(Koo?Fjeg$ixJirG_!gLYsh_xR!LGfz|#vmn1*c`=@! z#09dIMN%HN2O&BWqqZ7?$bh<*%QT@+QNx53y-H-DU)$Lb`^1GYIfP*Oq$4}GZn1>F zXaqCCZI?%=+)MaEdf+*oNtrNj1Y<4OfV(91fFI&{`L;NQiZ!|str9(L$d6MKOHq!>n zhQ+Q(LHxpJKqp*M!;)d*<}rl+xLM;Dv?K|5>k$$SSY88i| zp&>#l35-74^SBT=6>jaLC~3%83~-I}WG`%sG={k|Y@!C_iSMk+GD*|vN z0TVslffa+njA_wLAPKkyx+ybQ3lhUTuuM~@OdY{F*_x|b1~K9bNRkZ7fCL-U*ntgi zHy$CZ5v03mkT?sYreP|?4t4I0I>C{UR&Gfxlat2%`wJdaQ0`*jKd|*cP{ZZ9i;~>Z zFV+k+8_`ZzwjaYy@E2PHy#SQ&4Cr@5$VU$V&^u-8Cgg*EY3$-J20+{dJatOG?1K*$ zU-`yHdE4{BJxM+QYI(3^Z5t`+cnsyzC?QBpF*yW>$ON%t2@}D7);CycmsF%{%&}Xq znJ}QIILmTEKEW)rYc;P%c7Czyo#}z_;$m3zSTd^%@G^`I1CX^-HF?Z3a3d8G#0E~@ ziD(y5RP!sv_(Hdv(Cy;O_0*B$oku@z9{5@0;7f}S|1fy?<3_Wywa4D?OS-Z1U;M?N zDfoNx$wPBhwPVh`%6XhM@2R&cKVcp1UU;5D~e18ZjR=b(aBj zwmKj`oDl-+Z(YJ!2uGz~{)BNw;mijZKRob@g-{7T>#li#0EKEu2IVIyJTNXI-RLSY zx=a~$Np(+PHwVfCfnCc_g|_XKIY2lL)-`YvW5dj_QqmR~93$BkAX?G@yEFJ$T1}70 zWM@}aIB3FE&m9;@SXxTlsQ|@U5?R3bL&gz?V?A)7pt13)-95D6IXFAFdtO`X^7sO*}S@odm57E8MyYT zj}C~bSt74%ZU&;yvCX~El+YRGNJBQ1t7UUwp2H4~lOUvz&Om8qc4R9v!74(RNM|04 zSlDZc1fML)qeiYq3)4u7GT0F3VGOm&6wdZXQCJ2sg?q{IsxvysU0@g3KuK!TREWcH zhGPzNByDEwkQDms|dGP@GBp-@yaaNbQ^9VlS_ZmScOk;1JdAbgn2)#Twm zpadRlNlQpFR`4vQ8_AN70EgLdi&`_k5FUsY5LC@G;@o%d>YJ|&%>3b&T%~ss0nHEv z5ruQ(i}A~lCq0B=ph1)cLPGcq!f7xQ}BsL$t4F15XfqKf1 z3J~$aHU!%=M>nwLU7*E#hwur5A9=kGv zJv|<}HXb^=mKMN74ZFgoRB5r@O_JDpy^MY)6(Yaxw54=uK`mSj9wO4=ME30g`U~e( zS!9w4m`zZ1dRVW*JdOay-8GOQoPqQB1=1i^61dQjj_$A%Y0)4~_(ViHtxNr!uQX-Z zH9TmGO2Ag9yp+Yd-g`s#51+f{zG}(cU+Ul35SJ(WDl_=09!!U2WQVFYk54Zwy)h~u4>)mo`L|a+?`l?_3dxpRXjY#IAU#yZ z=z?PYum-lWK0csBg&paKsKWMoAVB3+JO^KbuFHMesfuI$*=b!kfl=843X z&2wofbUu>2NsDB6EYq9HK7PD&_*mnipM(#6ZRzpfmR~;CR%ZS%%A~!gPapfEKl&q( z-+%NU{p}k!&g#a_x6KQ)`s~%}9pRI7@m8!32frMbm$!?N2 zCT4Rsn7i&zUmrIQ9OR@~k&j92F^Q-|7_{!clgOla4Z$s(y_G31kQC@R;!PIk^l9>T zIu$R&&xq6a&xr=c%W44_QAtf9ft)XQ+3lYucM<<*cv+0q=%uRi= zN11_#p?eUOxNV-l_IOu7gLo~t)1I@6af+TtIZJgo0*9ICsmd10fq-0`QpCfJZw5&l^H2mCz#r? zqs-eGizi)S>+po2F;nbASlrEd@B}qt%$+z@F`I+$EJ+!H{s6}q3MFk}4m3G|A$Cm< zN{Ako;D^4Db!ZM4hlN3=J5zA3wdpfu%7DYHYt2MO+4J&*THXf5h3d_)d+t|hH8tEa z-_F8t^(iw(DbqYA17QI)N1eoaP&sAvF3vERX2eFC^k;5@Zpn5KVst;?2Dp&PxJuTa zkI6nJ@Pm7B%Y5w0a%vJyFg0~R4 zh#DHvc9N0U7Iedh`K8){@(8?K-?qGlk_edr08O~hE1^@TvJx+4mojC9PseMmuugYD z*Z|!xn}wwOV#Jw;55&ImzU3GdAb1_a0QZRrUq6NZ@RXsf55s8uqeJNwsCJXgdSXzi*Mqk_oOAu8d zAAQ1(5D2MORyroud+~Agvf0Ra!fUEL4+KH}Se;W|MosuQA#x!;iU#>RV6^an!K`P! z`KO=EJ^8pDH9@u{T}CW=++9z^3i6R9c6d28AwlWHRJf0^fNQ9m$c#XcEmpxWK%ZGF5m=0=^jH2-4+-0H zqE2B3em|Gd*vvzd{brOpV=i9Im){a7TSOwdJ0?WL_u1zdR_sL&# zo7=_jL25G)$u3=;C{%7ma@VJ1i&VC_bE$+W21a1A@NmPE#^Zs@3QA*+n=n9IKp#>n^0FjbMsgRE70|mNF{FUijd8i$p z4g;Vsqk6LdRF27&Q68TF^Zrg+7~nQl$jW=@=LYt%`X`WhdaPG zf6ZV<_U8k2F&c@Qx0}~x_vZdO3f0bL3_3L)I=hsdosUljoLPAa+=w>XxeA?bMGCbw zES8><0H~+fh_%`>g$&si;Zto!zn6+@sG#VJMCbm8%VfJR{3TkLrp`>+=gy-_m_0Y@ zUEmKig>dLEy|6EbT0+`7m&uJ-BhZi=DI*9kc4Z}XgABT6UhdO%P6}S3U8b7HEQHv$Jip)&%JvtjXr!#-BU2lisfvPanDf1>ZA;NWwd~beW*&k)Jv)tuL z4l#6ePaaS$GU0%G?Md@j=GqrzUG=u}cSF=kPZ1_V;*Vz%fWO1?1Wbn7#tFj=%efLdisq+@Z(OBC1ZbJ3FKT`$9nT$rFLxp=2Y3ha z1E0;uNntmyd*8k0J&K)U3^*ofXeRQ-Rbg^O+5vC1gc%#LB%R89-nC{Ch8ZM3?D4X>Kyqf21b2n-y}L7Ypn}Msh<_W|~bS zl9IefwIZM8uxIW>*gs*!Jtb*&-u(in0RK&eWZKWpn!$_=EsRo3PX`|aDY}r+MGqvm zP1i(1op-QjDC|iRQDg0{1YSDp?%l2wbZ#jpJ4rt8R%rxvD+-t+BoRy_`ANZQ#+t>T zb5m4-J*{tkvjIYp@ zVh9z;j9}<|`1M!FTe%;6yPjCWVt_lCDH@~_gkWoiBsy$|ck~z8(h-TmcLCaVib#o* z+>SZbTaijr)&>j|fK=>&c#ctGvb4PH)E84xAPBBY2g%lZOv{ITm(x!k#%5+bC&_js zQJB$m3!w;l(eB761m*8-!B03Lenmt^^~j&#;;sQ3};U&5pC2 zsm~^xwU&e@IJ7qsbhy{`w;v8&0|}5;f>Uskp$iy}u%4^QcN7S7THZ~y&4qDj z7LU+*5n>A((Wx~h9GNspd0I#H@?joFHg8vSg|kp*CVC-P^I+9$+jsoI4Y3V<4FWHK zbGn1Uz#dF?gEP6u9?d`h^hP_D@2pLyZ!MOln%x-E>vp$o;Y%e0yIC>t151&ID1#z! z1YkPF(xnB47Q`Q{-Q;z-9mj+*S|k&w6(K9ag{nhy*kb&=>;VxxHNo&kwyBaYgA=7o zwKeJqWNzX3wspu%oNs$jiaj#lh@22E6K>eDTF+ z6#4zjfBDbmT^l?1)@6R0M(tg0Qe9{$#;%Y&Vx(GgNec9Xo|*8rcYPtPuM2g$=|-op zz9Fq!1{gshy+X}bt_N}z56NqG`a|d7L%FX!%T=1jm4N=M@^#Rgddse~A#d|+TdidY zt00tV!X?@5Iuyr9)ST{y@HNCj^guquff3*Fi%V|}`HoS8&PA>4_L$X0{Q;`do$w#A zk@OAt3pw%#-U=M~0|podll4?J2GHl%9Z&Y51Gz^JwfvJ9iC%&T4rBh4v4RKZQua(Z zl?Nk81|QMI9>L1|Tw1nKQ^E!)X1>hv?iW74hKLmi8Q(!5IG|}l9@pp$9LH|t;HII~ zk8b);cvCmPJhA*#uDs~(DMHX5=d!BYVUdxQ-YY~07 zNo&gi5_Y_nK0xHPuKCC3VKDinqhWAOws22r!ef|%A zyes!eoIFGdq({s0&;rer{k2 zHM?(wXc18=X2(CNAGAtIybB)&MUkNqkp^x8D_Y^V)|9WIfHQDKZZ9|GkrPDNV)Q`r z1G;6aDPG4x9hUgdkAT(+)Po+h$Dm{LY5-AObq@*uBN+2*JF!Qh=bYnVl zndY#oFD zvuR9e!*qcT!Y~1gKH5ie1B6)MP*Ul7Dw?13=kja0+-hR#22{Sl6a^?UxL&)?6PLKnA$4)Q+)C5bIiZIH8ESQ7G)gghsQ#!{OCyH?r4n=0-Zk;HB{Ppvhkpr#&TDn+zd%2n2@xaEXqP zGj#F{jT`F`|)c zBn^Y^@h}GzBbaO2-f8(tefaI%p%)h)f2#!eJHK490#q4xx@JwJnN{5ty>XIJiZ?m}+WW`<`2VHg?rG?#B??kt6=V(-3LG5PD z>%C9{?2?dehgU)T=mirMwHigNWkzz&Z0V=3X7}H}UYFHGI3NK>-Eg3CB|VS9s7~F4 zv7s+Q1e(2VM!at0cN5M<#|Lh|6XA5lx_k{Bbue_-C4iU>Ln(~Vj7DyZZ@!$gD-EzZ zfd4SCa8_P-C3>K1A`bygB8izgAvj?3!R#18Nty39lI5#s3NJjHJ#e6L<+EBnKq$82 zLXXSwt3#{DhgUzG2!1x~J7#uT(br96Lk2wk{hykhoVU2$ zNwbj)Bo0Q24C6!DTf_%|M6SAmYvaYB4%|w=dpU3;H0=9$bnW<<`2+~juhx=Hh?R3! z+yE|%%fmL>#9$ajYZ(GHk$*KahGk+`X6i@4gRHCR=5_aSS*U8>UBm3TgpS+{43Gxl zVr>mJ5WYL=-UEQ^$+Gb{{oyiwmKme!3W15X`Gr5i=xRz{4q=)uxK`h59PtDd6_^{l4n4ehixhHxDsq`d(f4@h z!en@OIwIT900OwH|4hm}XVIE1(H88%m8{2a$?WVv0Z8=N>Awn1h_~kg^-HYik=n2& zA{0hQ{mr&$79mg}t@PV9EA&BBjAYz#YAkqqE`D82OBB?NQ-i7-POxW=v$fKSQ<{!k z(i=6E?m-$6PyuY{l!KeNN}^R?qfsOY5Y%;z5CBLe04H#zy#UNbb5p<_Y=(Oo`B?FS z!|(+_08ka;Mt*f-l`@#3Y3?G^AHTFV}U zkntL#xn@2jMz!We;B$BZhTUiv$hh!ENdP)A8r$YC0+C5j^V&X)Eyb^>ohuRD?1ZBB z2nDGSRE$cTQDdMOun!*e$)=mQeZuTpX7579{DpyTBa(mq>G+d}ZiG%F@VTm)A5j4LdJaB#NG=r2yC_E z)ke@hrJaf1ScqSTbH;MqD6?g~1aj7g+HP8mUv`@u5QIcx|L#iL?OBf1kZ8_*X;;To zEhB352v_ZO8D?WMoc#HX*#|!;J^o$=@OR|>D&X(jav4ul0ird9ee&I)&B4P?!Zk3| zW$)H{e*fg3{Nt;mpG_>t@CG6sc6(|4UOa#KwM{@&i*1uW=?gzEW9Xv67M^=RBz!uvDqbSK}KkBa_cRa`xR< zIsHMgCZDtKnU&B3^((;`=@r-8Ic_1O5YX!FaLTo3?H+`G?X>@0$xLdP9j{ErWVEK| z34or|5J{E}+QN53lm~k1*IpgU{G+N96siAUmrSQ^M zvJXDsJn%s9%&*f~NtARP$whQZhAo_IFTfd+l(Amr$Xm^>A7q*(&~^R^VJr(AK)dQni8v*k3PHQ`Wngr-(Z*g zjmW2LZ_yYP+Qzgn^1{xzSKp%WeEbu@pXdEowFxC$2mz7O@Gea}+}m|Y2ZBS%2jyaQA4#E!dSiODcKRejTXd{ z3Gtd;&=h~w5_S>*jX-k0VF;s7{QMPX|NWH<$B_wu*j~lexk_dQ3~3;ki(UdH&_}G% z?7cFplNPAk(3z3QnOo_R)aIvOECCivbw7h_{J+}FEM*!~;jN{(hNK2P#&XE?S|@*% zNt8uBn4dQ}jCr{IGvJH?eYlFXs7M(_*-5iLyXGfgG*sQ$|@y4JR66o1jYPMAZ{Cd>`)YC+lng@B6g zM(LEXwu*%hfFUK^8AT94or)~Vi4GFS%t?8m!f z(_%~-KWevSwtFFVW$(cfSNASp1?4_aFsi_AR~opqni^5prkfG~*VAa4A6QnMR1NfGxPH!|LmXr{}lXv^P4YB&s@*t1iO<9oAN!6 zG$TO0rDw2<9$O+E;F1G2LlE{R`)_d(ncbImB?1C9_j;K%M_!iNIj9>TLI=LXEx@T( zGuB?dl{Yak%SxOJjhr5Qcd>DA{7$X`3y!x{++g}vJZDaZ6ba@5GiRH$<$;;{D zVrKS&^VlQV2lf|#^qpc#gg{up-moa5pC;>FX(l#Jl%p?OXZo34HbqBY2+&?~le!hD ze=R+N#4smBfr9w0HKR^>8JG?rE7a4)x}UxToSA6RpC~0tja0hq(QokFiI60LOJNm6 z=t!3q&9vxg;ym!f!i@EGr`sd#rmHRU*DSNaNHp5Wy=ElCsDthhMi7X`@ICxgiIhk5 zApA0-pm$oE(mhjQw0n-|PkVYz@`3q40%ICl68kU<={QdT@W(>@vMmg4z8x|~5Y$|o zE-f&`smr%J2Qx=+-61t%9I!Pp^Fj8&1FLU;*S&cMu080%n@vlB<1 zd+!at_1$sV3u*w9$?I~!cRU&4@E7HBmvMfn9Jz52DNK(huG~rwU2(1sWrj1`zg4Zo zpb9ysit~+j+T+xg68(?vD29K5=nmgRumfO=GxUx!I&#*>_j(t4)CUEGpc&U2Z!k%1h!L(l$sroWHD*NJGBl<2 zPA5Td#uC(+>FlN%xM|xmtUD36Q@J@fqk9S>uAM&RCXwNGY%P*B>-N+Pu)Sh^_2j(s z`0>u;?^h4Kv~=V>o%yTa2x|FXL=JU|zr?SGBXb{q@TMZazxVh4^XcguzSXJqja<8% z>-6$nS^v}z)U>NHQ~z4xFXGb3&oRX~AhVPjK6*;W$qu&gPSRTxzI3~paBh*1^@SN1 z!GhhZjbL9gy>#)FZ)6{Ss5N4fE~wfpuwAsFqJLrR}#%ZgRT@ zRgsb1HS8oZ1(IQO(dkKx*tWg2ERvD8DzU&lAlDv5c7_M?2sV!pAiG>dsoqYnWu~I} z@mzJ;DKDf;v*FB-^M^+?2ngRQ=O|i0wy)ry)v?2gL%mTau#{?<<0^N{uy%i$*Xn8tD z10Zw_+?o}rq}$73$J&w-o*9-e^vmZdDNNJO{`(y%_OQJBRp@dtA0@xon zk^-aoNpI@La#GgH5FANnbcW!ljt#-8vZMs$LOP&2ByJspYL}DpsWfmQmB5c}T4O5( zkUPEv?gpZnfG)TyZnj* z1Bl@}fK|J>lgtdk76P-ys0w>BFRtEliVN8no=HCXuy^KDUGIgI=v1sQt5GDXOjDM&EX=~t9v7&n&3H6klexfsW zC}y)MSke_qi_z+Q>|)rFiE3Tn17OlJG{*tf1-2th zf(bc^16fm%lkW>+^M&49zl@?U|`XFnOAS2Bj~+i9{X;e*gi!RqA%P6|M<1fWNYm>XE@#t zJ;na%pkCUWM%F&LvbjI4e9+PvnU$|>4?5SXd3%g7i%seokTm)t7l>*$_e{ay&o0Y4 zzavL$hrYI~;P1?0$smA1(d|a^#0|C+`PupT(Jy`Je^&5!`0#`Cb0f)=uieedioL<=$eC)DG{DZex63+$v^-wYRFP*Q+#ywUbdl34GQ6%v?(!d?@$m z;e{)2PMQ6T-2B7a&hG5APwv8Hu=#=WO1jX({^fR)rX%B-PJ;;`O=z>(W# zyCDFNH#I!aBQ&DYAUvYMy&c?+<+#ht8uqtvq1X4!#TXxm5NUucqOFRP$TJR^?jkpH zzs6I>>$&O*RcLRCWk`*{N)#ht(Me7QoSU4a2K3!`Gc#2NXd9PLMqbKSJw$WRG)XA> z($lHK4^K@Up!vL?ZVRG~iCxd`^SDAs4KHe#P=L zq3k&Iz(%Gb%g^O=D`vijT#_oz13r)@sFWVH%r4~k7=5Rwu;h1cy5C@+9$C0%c1A3l zDFnbMC%HsVv(;sgJ|?J7#u37u;vKi(qEs?)UWsaLXWaz2qzi&v+tH?PBKO$g%uCOa zSuroNh0d=?Zr(H?jyXROzB(JdG$q+i9yZ;nQ5dGhh*sT#s>Nly)Zbz?3=BqQ!Ov13X`F& zsDUql3+-PwnII)ofOu@ZC7TWq(+8s77m^B=dr=d{i4f2T)?!7<_zJVP| zEWq{b8Y^e#K6aiyl6(3In%Jckv%e{7)xs8Jn@e)Q)m5{`h^s&}ARvSZ5zUYoouwl( zERA}=tekp!s*?cyaGXybB!06X0FXQ95Fn|3Sd6fY@Vvr!h zsgM9!c!0PCl6&v`TH+o=JPZ`4XXTBt{(LqKF;2Gnf`8ac6ld`o!c?L#BOh-t2nO3D z*`He~8}L_`HGewuw^UXTpf&7G2%J8~lZ%%xfA+Wj)_(}{`}h96zj^lT@#UqlMl%ia z8z_G_1Y@`rWOYXxBDvCwT_f$rMy}H<)Y^gu6c)65vZXWfcgt!Iy0QA^r}>^nXiy|xEF4m#t=fqY6m=(pF)$Y)F1c~us1L;ch~S^ z@vB4(a8$&6V}f{#HW3S-zp3 z<%|I(DZzRpZPi=haCU+q*mmF*fE~#|<}=OLJk|QOJh#(22?GwP2YJQKPEmA?)J0-L zPiAuXD#ai!(OKZRd3t+uQ9j1H`B6o|3bpR0*4hL_`Ao^pC7R|J;ufl+7>v;z%Ag?_ z=yYNXG*?Y+ME|OJSVqJ_wHO5DkubOGV?JBIQl+s17O{Vw1>hN@;r7Pp<;;Qoxz~S{ zt9TUDf}dc|mV_!zKiNnmAMKxx-W&;BgEuvL1fo5)L@TOIDrt2@IP}P}fl~AqZYPG) zwVvCRsDy3;mwPyYNat`!mva?gw3y3PL$HU9x#fMyi__+F6xgx63bQ7g(jh~Xg_-FD zNhCi-{#yuNN$uMk{Npc2ciJInM?&d16@!gLX*pglEoG~&R1NZFtD!1$yH}1yAf4|a^o|z{l|{ouhV{i^;iGH)Kq^s;%are-}Bg! zxRDrz*=!F!u&QLwNLFqJGUfS{Y&*QAe7&9TtY%xC6oyJw_AYGF`LO8rG`Mtfc=?;l z?vHMGzalBL=SMU5A1uB0N~;;O!lY)f1qnz~9%fI(vo*+^g?X2G#}`Dn5q}{$;+}vl z!lPC~c~X);BYS0F6*MgalK2hALez;F5CozUOJx%@=aK^_{h+nnhOj+Y!WabkVHoXr zvl&a51M$Kf0_?2Hn#JBWR50`A}B*la8^!$GI8FI;!vxZh>^z~<7C9SRsHC;)&WM z75G3d^n?az7zE=C{ib>JDx+|D#$i^Eiq* zUyAGQl289(aV~Ndf7^7w)fhqn|H3f278U9xenHkv6N!MT1ZY@g%mk|AD&uct2aX{u z5>JVeL^te%UTC#kr7#>WnLTCnBpsyMo@7A%z!xM#6L5kuz=D)PXq`2ACc6;34*wtt zRPHzL`I0>FL+pUxW=B9L;%c-*Vx8uVBzo#>0-^w-~e7`PK0pYTYp( zQ-Iv&HLuF{T!N4u0BbgUWibihmc>%AfgZ7bM8Sv((`R^)EX`@C!X{x=#tE@&1T4~d zb?mZy=k3Fntrh(sp>7ox??z_07whQsG0iV0nyP@yvCNnO#mVwIjYji)lIY)Gz7!8Fl62m8zBNv zNusb&ti^QdnpOpr-@B{xuV4N3=ik9Z)8Qd~pC{9{YIEgrkr_(w*LSl%n)s`oH5KylR{+^pZ z`mxLc>OOzS%2~s0D4X?OAO7y2{?q?N!QZE!z61EHR6<~~o{~-?o*SWEz;Svm?MCIs zvOhiGT*C?)XszZkn`mK*q#)}M@>Bff5?$7W-IdrKtW>_@{?HY@g7w~N#Y*qLnZ9pd z<w7AexHp^|N5$H@q(U(*L3KoIEx-ZpDaf+E z)H2aKUu6(`L7&~5#Ckc986mDRIGKrDwnSFq7sS7nT zX0EqUr}dOCIZmil-sIQhj@I;z^xnOZXCI!r`3bfMGxXYu?oP-~!VND@^^#El0RQw! zL_t)azOwMKUA=%nz(CYF8I;d^A}HtM8iKjzK42f}=3s3-Nq*rLe2t`o7k~tE)kVa0 zdliHKM*Qc{8UX3$@+QKeDx8{869_@03esq_QkABBJQg84G|dBO_~aLhrzE4gQcbqZr8Z2TN;m-b z*wzscX^E2nG5{7GTu#eAH9MjfB`U`uNs#8@&tX$p2inO1G37;p0|WKA~*aQbVzeF-BX}3el>ga!P3WX>!_k9up$sTf(`Kt z_$FaMV}bJ{eoXBwpnpmnV9V3PJ0ZG>wTU%v-7nA*N{{5G2nukn$lFOM2oa&6*_f-` z$YIU9J$kUjPzEVsby`F5t>2{f?O8naI+t|J@PmZgSDMM`L^D|_JEskhn22sQQ>^Fa zO2pg!i zeRdjO34gXgneIC^r3=VFhXhT1xT&PF6e zVhA0_%Os|ex$E9Q?PjgBLIlGC$xkK*%7$S}$)Uu?N5HtGYXSM&)7fpb^GhKx0~$cu zj3iMIDLiTRE;T*vJ{h31tE)-aTL_F!1mp{ZfwYWr8F+w(F@R0*_w4-9k7WJdd3UKt zsuZ)vNuAtC0j;0b=iNik|Lk!^e*evX^IuI*4+H}<=6Ts>4LtiWFI}&ign-mA^}l3 z$|4bShGH?ZHw`x;RrNkgxHbjw2*$u%-E6{)%>War(j3;}yhVwGj(E8jq6_}CycDGd z1Cf>R0$bZ(pWvU7n>5Erpu-q7880r42fklU4Xsy#Yq{mM+!EB9?ME8v`ww_7zSmR3 z?a5ev?@7R4pXc*y3!n6yhj4IM(kXVOaDJ+>8eLz{RGORLXdwjc=n;29L^J$%+_5yA zqyrACG~``XR0ax6mp$oPC{6K zDth7q$(7o0U_u5-0)u04k3&)?krX{C8{Cqsc*42KQhkZ6Z=Y&$RoikB_tJ4Xs5#zt zs?q;_=HUMFiH{}qZUcWRs7hVFCJ7Eu9?;!fw0|OaZ6b7IJTyqoaNa`AlyRQfPFjW* zjm>pA(etEmjaG1*DKE%_@2w_F85wM(hT?^}#nei(li}~Uyczcc>pUG|*g>Q_KHy4~;^p%CnlOxQAP`K8>;(hB9bgBvlpOY^=BFZK zgUfw$G0#}Qxo$>iWJT~Fo(U9CAUGSnn5$3M+THg>fLw*TCsCd7Y`k-Tq2f50fm0Mt zxhXZkNaro~zV`*{kGX17E-+WM;^`$i=XM0`kOdH9;SV zHT>pl-VO919Ae3KX%{ww0UJOWw9mpw>I(I6WF%(#eil8duTeil)3#r9mPm>L%$X=Q z6}m_$q)`N(sVoq4tIaf)iAO*+dHroPmY;@j8E!!i@DR>Tx#N8}xO}n0@ja;BNK*L5 zvqmt+j%H;|;~h+#ZFw z#n#W6QS*4q&WNaA>^%0~xY7C!HPbFB2Opt>I;zBYV89+owCTjFZF$*_)(OITFCkPP z>{8OX=I_Xd`G-z*zMYe;(X6bn5ZM%Bmp2=|p`Q){KD1QVgE3>VJBKDnfdN{>tsMH@lBT&T1uSD znb;MdtTtq>IFKF17J;Z7lQ776snWbVetkK06EAhP@q>ib?xwI2@2SW$kEHkStMq?I zm!gF!FtXkSlwM8^GhB$5Mp~<38pQ+E`jHoUq5y!8RFNvXKwYE|+ahL1gmU6Y9EpAr z6zsa3YE$On*4C3;^(5tUVcbP5aK1KWsd4>m{)xv@2k%Sn+mkwUF!{tosSjVv1P5E@ z+nuCRSS5?lO;6$mDkqbXrx)Y>TtzpiLEMi3x&cY`E-slld2w>iw;EBss^mOIICPfW ztZKfsnyMWCD1Fa8E#Ij8-AKT;Jj5Bg<1`2yvQ%3l<+$SGqk*dy{+dhO!M81Z8*&!Y zV`_%Ccwq)mOPWVVq3n215``!;DR13h4;P5zIkOf@7DlK>ZbPINZ(<PDr&&v1d*6|Q-Oe0Z?%=H))+&| zhM;h3@{qilp}alaTI^oQY}db_!l0xiJ?&TDpPy3=PGGzaX{cJ<7y z^-Qgm!wV1{pu|4Dz=JSR>)LlnC|Yla#2FjW{Lh|AK6r3q;tPO|^<{b#$;oUGzJTs9 zcq<$wBFWYfh&&gL6{fQl*)NucAL%6260jT`pH}ckTwo$_btc?9ooR5% zmNR!wZ@7(d2!5?B=?g?pvp(@t%l}S4J3u|1&Bdr+k6OT z`A356+Y`XXev%RK66+eWZ*zB`h#bH<3}$|;a(ighe{Ll`UTHE&h%lA|pUg+DlWmEs zQ)WAk9ybJ;jc?r?s)tBYC=TJ^fckhEs<%U+WW0~8fo1{Cj0v&c9c>^{oVB5#hwdV> zAP7xK<-J#~>j8+*7M*`Q)F@H=qw#60?w52YKvUZ^{RtR6QKDS7kjooMU8&0QRtE zf-;y@7sYd)s)$D%qgOgI=hy^@7z(15yx58P!Q-I|$bpg!UisbZ1qA{V`CmK_%t}0X zF#6&XfnPrpd-hR|(|hhEVWb{7m^ykWwSQmg;QsX9J(-7()~}sT#>W}bt*s?yWXrwp zbXbP|G%~^%+M0`8)&+|;=un_hmz_SOT{B$M!6-sNN*d|JNjizOcC0l&NQ=2A9y2l* zhJjo(q*e70mCzy(nViaio4lJWxjdMAQxD z;FcA6HS&r(F5s`;A_$6X5dz?bV5%Lrgvnt=q1-sFV?sTFfC}jp2b|Y|GCa^05u7nJ zzg!JwN2QNdFUU#nVo-rVsFsfJCR@&DD)RAGj?n^zQ|1%H${tra390ljax{*dxr+TS zr^fLGZ3~)s$EZUpo>~;VF)Z}F%zDG*W+{?BkJ*>>?^C6@MS0S zxC~9h2DgBCNVFE^W3m5SU#?v^K}U>3Z8oRW^Gp_`&PhqA zTZh{2-5;{R0BqR408gDunK_`UW-AKwxP!SxKATS9rN3syi@ZgrubPrGwmZmsNl@8-6w)vGl9 zL`dfun$SqnYQ|<~hyJ_&?!Q&=_vGV;0Dt+s@s4#_q$LLiEK=Csj=FI`6pF^}$vYv% zwfy2Ez`k}TnXgAZN%=fCfVkqw+pY`4z=A=2*lUSK@7T8Os5xIJaIlhYX?Vv8C3T}YMYNy-HO zo&{%?Fjwojx0!_7kruloGP0X6mn|uXY5LL?ms#vA!Xnpd zp2jVK^MrmGNt@ji=^hfnvI$S50ZyV(LK3x^$;&OW#>dKa*-HZ6=qbHJSXKEzS$F=w z6Pm4j`F`fX2h#W6oBiV}vDxzo5q(Ss&Q0I^Bz5Ma!h65ZKKo?$nJ4nUda?Ze@5`UP zn|tafnSJ}Rzk9inkSD6ZEGkD765LH+v}VMD36|-uEJJhyE%qs>ON-IRSjxNA8z z%vg}1h9jYGy3dX4typ8KukzKqz~%VE4`!z%$!VQLsNKLH45)rl!A5Gq_%2RI29`1t z0B8zO3{SAm013}qbK7o2N##L_5UH_)1A1-GbBu)$eOm2AtW@-+rqBrZ49Mb544BwT zfIH)pZ|n+E=REab+>@d607|;hNxEg`@39AMFMg27XUU?=n<;xT)k-r@d`F(SiU-we zOm`A;P(*^FcMAlBPG{?w94VPF$^re=daS8)lD?o&-J zoW!MUbrJXE7A%C}?0|1`k4y-0aS0eiVXDGxKp2Ek8RwX!PDWSc3egKtvK0cxiCOBp zLpp-{Gg{C_;osT@Y7)PT_i^u(nfnB25+$^f9wIELWVA&@nl5{CwP3t31A8>>oL;rL z6Lr%%_OpF*5kfL_1ZLzRqr71n31)}9$s2Ixd}o3IF)5kgh(JK7mIq4&6B*)~MkmKU zOYhrLdiVF#Pm6>Xkd3oZVlH+I*3o*%A_Nxm9C{}{^qm4{kQ)%$nPKhqklLwbkXOX zP>BKl>TP-Qi!sys+UlnN!U+n(sqGmEJ#rrV2j~DdotKoTR{L0QrJL<+yOT|omy@Lh z;*yF&EPv||(Md!SEE%iAYcOVX$6YE7)JH-DpE++|)8=X+dGq6*d&*yuZr z$Bty5f3h`w-b(-I*C7G@;AjDR|yE%Dw3oZJ%%cRHG>V9Az(7fr6j*14U+=y!UAxNRwok7 zjQUbzW%>S0ELC!AaM7_Tk|L<-l!LQ&OOzp7=)zdijGl}aW-S&`&JaqE!HovKixp*| z>v}U%dha#)0OC8Z{mJxUZ7tL6n0s%@m!MD#`9`hK6}y%!&EuK0rO)zlKmJAw^6eci zNrh`EkRM(I3e1$Fl9H?Kt1YvD#M%wKMyYY5+;zA44b%eKZQ9mMoqiMpx=vwx!)lvO^Wjd*U~!oNB2*ke!%KjJXrTjrI;tNksL#ygGUt zf`RbH>-qpGCy1e63@R`cB4D<}i9bCMEle&Y`{)jw zaIZ6hlOwSooyf%fZEl8^H+H&)#%I5ZKKW4Q;C|bLS!BIwx~b9}y}*UBPpjNI1I3NK z>vS&GcE?GSkK`t?bKo^4kvS1bG?*CyG&qB5zT#o<>8yc!(s8tcn!Xk@-tJR(H{0S5(vJmyIAFA}P^-r>#~zG5bjUk#QUf5KXom-uZkb%)Zpt`H z?M<0y^yM65D>?mlJMHKWL;wv4fF2SPg8`B$5=OkuPOjOJ_`kN6_`$b&Z%;HqULeR2 zxQOT3s)xV$(R2u$pbM2&C#JKp{5J#Irj zre3F2;iz~ECXOg+g9131ikNDho~Ad_kP|H9B>0TwwUb=PJ@-_4@1EM3FV{OMaq?B5 zYdle$qkeuh%D{TEGzSpIyGUtT6w{Jm6T~_>E)T-b~WRK zL}B{k313Ss59EINv&@10@xupwZ@)OYcycOq9uWmHvQ*aILX<4kmuO2si7cm(&rgxn z@UHZ8kAu%DpS-(Xm&fJi3$6WRT+j@0lfsAsTVHKOJ8jts6ZJG3QScvefvZ*~e*!d@ z0;{2^((hl*?7uI)=ib~;9x1&1LTjS?>Z_Be1hb>R+dW^2l!IREUs?f*O@;?u@v&%L zzPZfc*m*C23_k7OJ0ZLXJIhx+fO15HvUYrukGuxsh4PS7&4tf*V`} z5vu&T9g#}nF?;+{7&9fNV@_O!pVHYckc0RAU*25WVJ>|)(s>$0-Dt^v`t?>STr5q+ z8*|Bet=(NqL5rk(r-KnVdQ63p6YSZyj0sPeB0|GNZCnF_gBnqHEI-BhT-C!bLV*A6 zPdAhp4bxfrjtZz}(*SlMN+MVt8Do>?-6MI_u4arS09=qE&>4@Q41*T#B02fZM-c%c zc%Ly~`Ff!lN=;H8^HaowIv}~lyn(2VY7Ly%XR=O04#>)hmLPhKJHQoT0jHP_U(Pp> zQYv1Q?YoAVR{GjAs33sTt$MsIuh+3MUG)niXh*5vE!iVbhnm zJ|DfTU8AR{%rHCOg_qmORC}bCyw7CfL7g>*ncpa3*{7!RX^hlwnAfG84H>@YIqt2XByV z7ay0BD`$L(L8r7K@YC8_mXfO*OA#!?5)C?ud}C!KJuv!bO&I?W&$8v&Gv*~0@(Y@fc_ZOxpb z1)AP*M+kLEsMgA@uZ!GB&CV`Z+VSLef;|ww9_!Sa6a}K$Y!6!6OakUPiLvqcFhvKL$;tpT%c^;Mx_{0^e!&Mi!B_&y+=oR0|v){=q|+wok*v$XMHU(`v+ zuye5tDgF_@bZi4{rl1f_7~s!P38RY=F<53#y5X^NGoB$CSW*toT-43!Z;TT10c7&$G7t&?<8Z3I} zm!O7D2~y}6p&Q@1dJBK)I|T@H^qpZDzqnOvASu-PF%?8%sRtzbfW$1-b zfdn^dAV+5!OTO|ivwc3&GAOF2`ng|FywSQ@ph^o@&ygxm<7#s0tCW$W z2juZ?=GcSP)1S4X^J}%ROaziycbPqc&^PkmL;$zavb>`z9~7}=oP-RCBU9n)li^{~ z7%5o;B`^qKI!i)SF7bUA3$X+oK}z5l0vVi?8YysIpio)N)I6D5xLC?oEAm;7Y;`3) zP0BQq+X`in(j!9@Q$Vq?vEe6fAVH`OV8VoH#vyFeW^i+ z=!wh$qhL*1Bm^v{=cnTpZ>Gvf2GimUW@8~f9hoz`x~LIiv}SH!rnedAam)ZIQ(53D zpaef->4^F#zl?J*9{o#CksC-6e5QqaNQY8b4mzqf84 zhKB&L!=A!eBgl;YI?oV;5HhCXOAM;m1!-l+aYhR0;6d3SKI&8iCgh2CpNue=*73Cd za<6lTLexaM;(*&hHlD=Ixy0ylc78E=vm4yoF)D{EP${y-Tj3uSQne8AS64_$+xyr>+q!TtUbj>CsIfexT=N)xP%=5A4tV>=`YO zf*7Px4?-5FTTkO4h{AkzS9)!HUp~M9|N2}E0dg+}2FObm=ZHn=l8XYIgm6RpsINf5 z33Zx=QjD@J5A=Fy`I|n^7dJd#USIrdc;l6J4zNj-=!`$zxea5PKlZ_#lTaUOT1fPx zFXSVZ*;SK(2@MEHxNHz!qZNsjJ;k~#_~T@%vAA3v2-ZeHz??z0+Sx7O@9p$MCp+ie zB}8HB+!;ba`TWZ4?9e~|=l^>Je{Vi}WOlm0QQuq+0b})AI9rx41PcChY&Gh9Idse~ z@8gqw)G%&OVjBkULSnjW`OfMNWyI-r=lnKA%F`7N5PpFKsHAb_+w|VO$=81|Z?;E9 zi5goNnAsaGiGv#;jy2jo+8n=GOdk_(42nFZ$*bwB{h7Y&>1+L&8|lh|-R9!Qk}jBY zl5Twf&zL%DrRhf9ADuk6aPg0k*IrB?IU*l2{_qcrzVm9IO5_(O!NR`9IdVC^yv1h&DUx&~Fq97|xnoXC2W``gw-wr!_2-^TSjRmjX70661rAG2K zdDKf_!Y=F0Fi`+Epd7HK*@{vTsYqLz3d^gMm@HZ+f{R@mYM75ea0??Xz!qwz7(tet zL2xY8e2a;G!Zdi!DJDs-(W|6A+(R_6nyk0tp_|{5*E9DYT)F(Qb4L#%evdQL2f9rV zgdegm#~4T2tWt+)PO}9u8s6{7kBg-wwZ!&mZ*B2u+2%#}_)0rWpuhYo!Cm#mDRloi)lanuN#f!7C!ZcX~ zSd%KbX1(9}u6~$(YbiB06|ZNiS%i#UxJt+%o6}thqo=goC zKw=0G6N==f0CuPVQv?KnBZ+97bVe)4pYE=0+Km)7MsrgT07A}eU26fsrzUCVd4z-5 zktaqDp?5Tn_Z90BJwdd#q$O^T7iMrzuF_?SVUrRU0%zxA*RXapf`x~&6AT7=G6&^p zPQBXz-|Lt?<2N-MYR0I@5T4}FLSh>IB2~nq37b4h0dfX0fg}yOqSu%x%!jh$=ogVv z$x3<{@W-GrUYLc4p16S%aTkh^x4Gq8J2JOw3qU9i&xH-D!gK{eD(-AWL-I8|SuTTj zYhfy%^?aLn_;BvY$JWdY1lXEPi~%5L$*GPp53&W{gYv0I0~*9IreLOREbfPpi92?U z^p8e#p&lox3Mr{a<4w*aL2Y_4v~=pi{Ck5--B}YXO%K$1H4yCv__()k@$&)SiSzS+ zyzKsnTY3ug5EiQkAb3UX3L^+0b`qCgF{ceg2>&V;DBJL+8q zbvB}pS&sCxZHbhX8-=ozP;JU9 zZ@09O*i~<(b>~PJ)2B?%ICF=zV=M4)U5@}bCfGnWVW_pjz9f?QfmZB5_YMgi>5iM+ z2oR*{KvwqovO*?S%Q)8TG$LST<;-2RW~$kd2Q)-F0wu;*-q_ZkV>}8>rkh_lTT=2S z2ME^Oh}AMK*OrJ88xOx_gDw(0>4elv7_|t}N$8S{NO}gcG~4NPH8dW)ICt(3SW@Jf zhsNjR2?(QJq{i5;2f-*RrJrODG9@`InwKvNa|t)Y!ssMS0)dGX1O-Ai4D0H;LS-pd zSm3Hkd3@%}_#+Qyk3E=Qyg?SHW-wDv=I$X-3(*{B)~H8wWHN}=bhR`eRvW12DF4U5Ghy_Gy{cm6Bs%f2*$KF`+&wYkpQeuMusOt*QO$Ub5WTC z;Jk({${8q)Idt(nhu=vHRql=pl z7kY@w7h-+fQfUT2lAp#Oz<<6>BA73=+6g3v7hw{V!Bp@I;w*k*meyW_ zRe%Vb)LTKcPvvA~eHNLoda!W*aw9Zuxnmm+Osct6(P9L4j3?=HJ5?AzE z&o~toBN;U(f_3tM<1^qSoe=W4)H5)HxRD+K$fyl#M_hCkUBd|sBNosY2vXGq@P+5x z(~svKd8m_NbRo&U!7#WH)MI>{dSG55H8t3VuwhU>E~82TMj#gLMcoVxs2mII^L~Nv z(`$y=*q(|aDesYVAI70Fu(*AhW@z~vyF-K)z%ua*)w229RSHe0a40|MJ8^a4lR@8? zAG*IsuGyfx|lrrC}v_=D(6yCvUh)4vehg4z)Uznn)P z3Ya8Yo41~^ReGlp=7RmU?{hA|AIIn2Wt}{uW@@9M9t2P+hh}Go{`J59uN3_K@|Vw# zocKfDw`KC1dt1#|s~N2{bLdp`vQgo7DmRuH;8|TbX?;CYZROY2x_@D~vzl#ovXy40 z(va`e*_!23Z|#jUj)}%QBoUf1)zR1hZ6yATcdi;a( zH=k9%KT*7NBDT~=3@7F|y^_oby25Q4(cznfQ0*XoM{W}Ntjb=b$hp>D#-esy2aJ!n zVmBs&-JL;o)!?Di=ITG&au}(v^lkTOrv^O@}TrUPXo! zmpOx|3u0}(JBeYOPvg@j=HcQ+zN z6FVC1-1No-gZHanr|-FE>5ngQOs``3=^Y1NBoB0KfX)m}+X5O9IM0oGhFC+M#_VLz z!d8UNPDV=$NuOp%&zHYT?YXz~&g<=V6qL!;Pa9i;<<%bJyO_96ih!I`ZVPnZ8|@ z0J@@At4&c5L4hDk4ICinLTNdfU(A%U2C+GF0<&67GVJJmn_PBE!^^#Tfiuq zu?W*9XUn=15UM+Vov?)|lGoi^cLUaODhI*LSi2nqtWXbjg)W?8R6^RAU)_ws^l#XF zmz|FH6ce$V*%ycd`ht^!u|O3ZWApaKKqc6-x1%q$PgO1g(K6^oJ7w?Mkx&XiN7>Mo z+893;YY^U;ng`<$Iu7n%OiYc+0R1Wq(3a&PUYJIhm>D;s7e)evApBRag06@g?wEW4 zgAhrqM6k%s@&J>>94vbC>nV71MX%dNVT0})QRs~9mT5xHoBVWU%71P;boS=*H;6)P zK6OBCAzAUnm%u{q&P}6#4zLfA*gO1n1Ab z+lk4ObSJ?TM5d^>b1*=QyG2WiIq@ZYLRz@i%B`85oa?Rb3cpGt+iZ%uRfF0Q)0QAb zVy2$7{NIMSi-!1ho>8iiCaT`z=YJ&f%Oi^oT|f+dm0P*pZ0c))xSTYO#-&(cn&`n; zi>PI<-XY-&IJmRXJEY0r7T1#;T3eBia~wJ_bM@UB?|02wa7{-A3|7mF$>KaAh#){n z#MGS-&=PT8!w9#iQiucjst@^>Ix_c9#_74`4vENPd}K2$a6IOhCpq?vB`5eJEs}bA z3j83+N};r@#Z+1`TWW9s8w^=V5KF1)T-8UE@Fj1~gs=LNL%?F<|BmSP&nAL^E=N(q z--&gM&ly640%3#9Yp+6{#Oz%d6K8>I3=5)#DZm7w)}kmBLwxMHP03Uz6Pwdv+4cn@mMsVnw)cOC|82%tIW|d41Xf?n#$juuZtfjm42l+2w4h)Ci<}{n=-qkd3DE z@?s$H7kr?ph&q=xurD^`G^z36Ia1o{8X+TIHXrq;<25q@fZYe=snb;r7Hj1|?#ahw zbMt+Bvxn}_?A?>zb8qB{qqCR)I3ZtL=*v|Z5XhtyX#lv1=BSO1II}*SkRI$`EEVvC zdD%0xrKErHB8|?rfRY5kwWQ3nZ!ANG2rlGT7#IuQU}zP~&q{7KV#IWCi7BIHG)08M zq;Ssejq*u*0n?@W@=SDiIhW7Zv+=_0tbCr~BCVhxYOq3^2%ZB}k!vLz$*#y_q()3` za_iRls0qUmA2w#gU+fA~1O=i33{R)HN#xn(p~OqiDv}QV;<1VG&&FKGw?7CbNz-3A zfls=IofCRAzRPeWGB6!)6dRe8?2RJtpr91&8K>ZwI5i)=0zjeHP%t|VMqh~E@TW&$ zGFh6F8K#;~V;PFmj^H)P>O{6ag=?&&hjBE50x^gR!7)1y-02`~aWD7)(2NOj3;=TG zFiXODGuCR!@B{V1fYbS%1V7>2cxwZDp%I(OfHG!y+Lb)*?ii^p(FL4H#|BcBc{4!m zgh8`A-iKru{E(TA9fn_GNo zqX=A$0RzxULGDLFNQMXz}ATW zx_o=!`KN8Bhq#MAQiJr=d?wDhwu}yPBU;n!MKMj%+6#zutCJIeu!-d}&UrWpOUqR} z+`hIhc^zxS!C~83<_Ae-BGZJ+-&|V|=Zm}CGT3^x0YI5FZyqFHoF5Mhh|froIuS+v~ISh zf~>@pzVCuRec>Zx!Jm_eZ)k*$%W)$L+WQ~>$A7Ef@1cht;BWNeyQ{gKAx^!Wht}5w zQSnzKZ^&83NnAp_jaH&q&y^avYExeDT3=7*s-bm8T&uaxYL;Fg2TBqlw|m^}>+hi* zOSU^vZ{m6+KbkuBVD#~$<1?E;oN*4O)g7of%nxZhYk-JdOR2%0lS*WwMmvQ0kqUb* zSz>Ug4r0kUdA1ul!5@|*UlaKF?ex9(E`I(hXQsjzv0<&B*2M+PN3)h>pV~>{Atq;U zcM>;h%v7S1cyYGblAS|P0j^i5c^AwE9TbLbHT54P1y#;WZH{Gmm_1`@Ce&AHbcIZ; z@a!~)w%0>J4G^sTCOIil0|NpQ70O11 zYR5~^H;~XWKbysQnQr>@E_pcvr*P>V6?5Rhbv9TB%K$uerpk- z86mh(3ULH0q5z(QArV|)Qntb#x=?)M*TC!4;roLxJ+bihZ^vi8)Jl|S#g`hwI1w+J zLU(k()s}65=tZnB=SoE8Q?)`ZwiuJmfoT^`zq} zsHaq0)`1!4(KtE7h#1$1pYU+vi3-r_c))NO;5tO(>SC zs1OOmp*3DA_HSQn#Qzb)Fd0K%d1h=Yqk^M zk0FFU1fzT0hOpVC3@pZ*=qDEAgt@9GT@Fl! zBtcGx`v9GyFyHBw*Plz@w>SCAXQRP^a9%z-EQ3^sW9a%DSj7UwG=t{>3fb}k!y^SK zG=~8}3#NDXN2S4hQ*YnRmtuscM`}S4Nech<}VX4)QTdMw3W>Au*e(;* zQ+BJkXqrx;3sTWk=sZ1@VrG*X1_NF32EV5O%HvI ztG7ew1>xIHsYWPJsETtX5@V^S9?k#kS$!EvgGay{=ZOkZM* zDjN>mdrx}Ly_rJ~CLrZ8RIk=_}R&?$t(e)@eAz<2nUONV~CaO{gZ z$Nft?eBlG{z!F-m=;Wh042DID|%Jd*{|N0Cs!~3R3ETllVosxdP5dlOx%EZ1>yu)XFZni zM-m?gv$E<=zG+UJC+Ff>L@LX?67|42k%zk+e$friPJ$C0yyv8oxP?r_ki(uC4_wIC zx{o06O;WJEbmydf*>XnSi0!UJBV@HYnMyN@Of=dPljR{vc6{-+DDBT6PzS$A(s{Cn z=<;GhzPfZ*&xIWcL_!A;z5W%9QkAC_m=WUE7|Jgum8&d}^|3RooC5q}d^UPwor?*X z8$*}5ilu#ul5Z(Bh8dCaoqAn)?YY#xJ*lIIA_HHqRzuVVX#zm9)QQ>I z!qB|=;=t5#<*W@?m};AXiC#*em6U?<6n;MW+bv*f&{?kVnh~1F5(e zA}q<5aJ&06(>w4JqM!_nVMA)NW>RO8gl+Ch1ASl?mN1R%IJlMiDqLe~~u7G7k~DL>J_RiR2Jri@-r#ri?3kof@dTYQErX zjAW2ZkNhb^Lxc%nfo4rc1rV``wgR4u#dqJx9yy%8=bqrpPj5^CZUG;H?ZASei=+V@ zl4MWK{>(_Gnw?M9y~&Wir=kHGMWZPzNd&9r*Oh?TCk%UrL!EU;^@ZyE+Iqav36vW0 zG!s?Yrj_WjYDc4_txbu(pl(ddX~vdloh~y_!3^j!0x48`KOBrvp=kPrr2+3;QCUt( zl;^xH1LyTd5bH$|c0LTE<7gR8nbBQWZU_N>?7hl4!q+)|C|a1dHDEA^&K;kaifk^A zqZQQ3U!>HN+cZU498BemBnhdgUarb+@G0S(9)@^3m@~#@tFV2CD)e4 zWI)gF=ia_B|L*n0&u@6X7+m-w?jD+4_$L0KR)81}7y15$>AJ2p++px3L)1MW7{(SE7M{`FXOg;P{L*?unquzwzeOjbe@{lnk?lmE>>R`B=rS0A|DBkgLSeB*rzh;6iD%|=v* zK&$J?dMC0{b!VH2HOCvf_IEqci$)v#$JKPB6>-j4;5$8qe-x>C^qkz0a6@tgmgbxN zp19=s;Frok&%8cx*1m?koyeG2xQz+;vb`5J1mqc`U6T(k=v1OCcH+De;lh^~oQqt^ zl;xxLptRt|3o*D4R~g7zZ|xyaW4#$_HzL^!CqRD5hYp9#PDvOlslgdNa9bJ7m=fGKwUsmQap0t%v|&aqXKLUA<&#ocKleHGP9>WC($gqRkedCP))fZQ|A07uSLwm z&z@WU`lRF1?O=2(otcXcli=CjrNweXtdJX>fp2v2)Z&-FNj~ym=KlSq z5C71~bhp8zBmt`j>B9pEk6_yBL_l4XOqS+kuBhsn315W0a($&!4&>kbb>`rKTHo11 zHC3qj%QgAV0j5K{LD{!YK3GmDr@W))?)HgJL`Vw9jOaedNpTO-=NBVG4%9>3p=nNr z<>dx>WH}ePO0@)f91p?b%!DM`B6q5kAlN2zQ?vF|2?s!8WGPY_y(X7a4;4}^P1s@^ zh0RXgTVEMd;*4FlPlhf|MTSQM=f@2a;>>jT0#b?>W^J|Q z#tLkBQ{Hf~z)%v91WObKJ`(AWsvS!Kfao$%1Id8=xMUz5o_vn(V6W7y59m=G!bDKq zf-zt%I46wJkW9IyZ&HR#Kp7Kd5#wBu?1?<}(CqN16K4Kt zgJi20N+LS$MXtfWQ1IEH;7iJeOeG@GL=@=ubV6Hi3=N1n#eY z@hrtObWm>}4RnV|{9Q=M$ByVY>Nc*VOAfl7RXu8jbR46ikGO#5drIPTT_9-6Z~z;= zs)(N9W;Ui3gmKPf+Ss`JX_hH7m)(a_xd(DTnf zuE_7-{F}d=ogI>mo!3*v%Wto@WY(%)3kw{Vkw)BKogd2&Ur%3KE_v6?CLKRWz^Rs* zCX}yuIo9o<8q$zc(SHV6+qgYpkk~NMU~1}fz?1L2mu@bf#s+%E?bSxS<(O$!-mK{G zbgUF1sCP&6T#|XQd=3b|1hGhdvQU$aV}XE-Rmc}aKL8(Yh40vU@STk?yGbtjg6kCsMT2|AacC!Ybt7l58a8sH6G zGqVew84X+;Svh-0;13;>)Txnp1OUQ_IpdBA%0|<4jM1=`q-`^nm2WqZcu4S+r^A%N z@vvRUbiOMQ{?0`%;{%COq|%7DJLbL7PQ2$?_{h>X%M0gozkdbG%Rc^S$-Dv<%8uEH zsYLvZ$QRsYLA|a^!z&2Kqy*Fu%8iqT8`-)1YcGQdN*}z{Zboa3Ai))ggj;M!z(VkR~^9=O2qXyE(Nz*X+0n5I~{Mc$$q@@Ddt zdZ@dU#B6)U0X>2}Z3Qw`bfdi*L%+lwEC*(gfY_pW4FWieY!L`%1Hy|H<->!p&0jPK zW3-C|dcJ!>HyN%4@#8gV2J|+==4Wwn~(L68vu=A_%lP3 zA({5mH+67uA~?pQmB5U4fliqh|F>8#0>N4s`5oouwp0 zDN&G_m4WQDCrTm;gipK@H#FZ=g&#ox>+-sK^pC$vKX9;o{S4^Gw(caFrcvBkE8I$F zP(3z`Nno)=1EdY=8eTd%6%s3=Ass{^b8v0FEsIY`Le99Mq-Tt#WR9E`F`nV&)6Vxr z6vlC8z;_(X2e|B$iM=iBTrF`gi13E@ONzk~zY|w~=l%8tZoIzud7tMCfa9qDOrf@f zxa6JmhQGD(EgXp?Yl%OtZ9GXtQ;q0a*4J5{DE|5-+1l;kfx>To+46KZlKf(#e)QAI zp%*;eS3OR49y+z!w^YOwceMF*$}=_9|6lwU|5Cx<@85U@@K>)%$kkj7&#)--yTou!V4;F*v^fD(K%}BKo)VPg@GIk=D0g}Y&GAp^q9?3p@v=x|= zC-vs*M~vmHnK4kOHeq068j|7SZp;2|Ls))Kpw^Sd)8$1yM$V&VYY5KcP);5ois3Js zgCO{H%dVx}zc?51je0P0I#q4vI;$c*jyXe+i58}9e!oL_@|CB}R?Al-UX)0|{%r07R9u`Y|~ZPO;;UK#OyC#;9F6V?Hg*2;n6`7hH4?#tYNp#0A3>*XMt0RA(iP&2|T z7`Rxeft@iU`ep5gV@>Ux(f$(0my)vOHGiE!ob*s`EYl;LfqaJl$aGXYLdwAzC`mG= zgXB>L9P~FlaFIOfIckf%P%)MC_+I$(fAPUT2= zaqAbXNzxYl!O2Qy1XJGZasb3HW91S5h4J7J5RgQU^OVgBWhtK?Sx9;_l@-!CLo4T~ zaXWFZs#vMrU7khOlxb>r^!f%`x`c3mQ~Dg79I53I7t*fO0~%r=@;ViQ7oDw4g)bm& z5`3ZJOBcME?>3V*Sg)O?>Hg#pqjM2lYX((T-K3sy_K0sG!~Mw zeGh$%<)?vM7&H7JD*}W(SX?>7Ni{P}os^GKqWNh>R1*YxBSxLP31r6TNLbdGOQ;gC zXaF>Q;lSD|HmLz(J4w^>Es!Zhjmo%%>?MKTymBki*(}DV495(;IIp)LBF0zNLm{FY ziHDJNXN?h86c=C^ifg-MBa-eUr7L>P6~C_BLOQmlci1xs9wAf&S-P-Wz?0KkEsX`f zpN+`AsRrM7>!CvI7T8KdD6XfEyAj-KXXzvTA`sbDAmTgSq!^N<7vyy;hril=?p5YZ z$ty^MlRz|_0zIM>x`Q71>%R73`kuRsUwshI&-6qOB?=S4sJv&X2}Cz(nyc8JZSMNw zr#HNxPX@oc=z8Dox`I8FYLaLfEo`p`>d7UjhC!xzfp^PFKF}VZ?W+4DTk~xQzz1GD zJNxGO`FC~l&%PS0H0Ed2B##t39hsldcMg=+JCR$fvY)?=Dwf)=;lc~g5m5m&;XMc5 zedgN---sRhsr%4R7mmD}1@t;)-o*I1K@i*RhMUmfs{-6IJL4M&-_kD%p z<+nPSd2GAcN;Es!)@rWO%$3{0vE1-lIdvmh zoGI1Kgr7Xc4$GPcgebtTh;42(%b{3W#RGFa*oNx_+qoMZu< zlSmo!(M!6>0Rn*9OV;lQGB_i@q!RoZ-_)v1a*^Ha7ZW!KS=d#fW~M?{V@MCqk-sk~ z^ISVNy`7w^FM5d935+UgrA9l~Y|C6ViR|`?^3F-a^~PTTLJRRecYN2!zVvG{M4FaG zfdc-xS(m`youWcp;~Y-eMH6R2$$%=0TBFX&_Taq_vT||l;Obq z6(@aHcnH;-eKL1;X2fFGMbUj&+H+$*d{uzE zl>h=k?AS9n#*^s})yJ~cg-YFDZ$*NI;(V$KOQx`d4+5f2Rv}n}Q_tC_x0tut*k};P zMl!}WWN8-+pm88(vNV&f%ql*nLW&V00W|s$+_{|2N%Rp>s7ZiV@E5^e8+(gb!{7kj zN#HhLUm%OyjZ~Dl1;B(twbumqbZIV_?LPFO6>6qVj&&9v&doE&3-G3QX*8URT-8}I zz$Kk!h)GEbD13MNi2j|4+?a~=%|?e75)3LN$Y2|EAy-*Mfanp%aup9MaB|y2FqSgQ zOY|??hH{%<`BYLgj2Xi)SWx$Nh5#IRqB1`okT<@&3klXmVvJ!JqiUYe2Uw~5_T^uE zE*Tl2MXkX})*6X{(;*4pxCZG5wF*QFU!roSH4ZMFyy$vwaOvyetDPvf9Qq9L(k41dfsj4{EnUMynelgU1?SNJj9Z2 z?EHWKH-D+%@44q5=Wn^xHHN~szg{i+R%ImC{R~6Bohvj#f-xR{nizx3VSsI*>Lsf~Wssmtz<)&QKuE!F1EFW%vpwtoD* zwHoTIMQY!l$Q(S-n%nu~jkh7hSgLt*vJr=@Dq-wI%t;ozQ|~aKQ+kl9X}u9`44ki= z_^|xmA4;EnQn>bgy%0niDog~}UhVE*?Icr4qR~oM8bKN=RDFTuNa*BS*{6PzJ^X-g zR`6Ct-tP=y_SU+{l_Yn~xll(w*Xv$N4U>%U?of7uKnJekj4wH4_cOxd_)AE%p~*?a z$sR9&FynsjS63H4)xXo*KGUkCKBc#FtO1`mj0GYnMgnv&QCL|_^b>pC=2H|Jg%BMF zcLL7(eP3U8e>CVjaozJp&n1Wf8*$ia6=o13&P9sc-mgE8KqiD8xFv`|Az4e-$H|^z zmL?HPw$Mfb}N#*(qA(f#v z!vcD%Js00-_{ok)nFtGuC?i>%H{eh9s#r`-10$-90M=s$)=~bFpAa9AMOm_pjd)H) zA32;ncwfXLvlM#C3C>7bn4Lc(Upb4UN6KG*kbUOy^nLp>2liJ^eY%$2GW3Mo9cN!j z26k@_I!+U$5Psp@6}<`wPzMQ_vKp#=i!BB3T zWJ%o7NeIgfS9KLs_ph1JQGec2%)CRRiJu%C$;q@0KnHvYCnym`WX;#>$*-}(ba-Qd zv#=rit(=*Qbw#H{zSK?N;BDS~PgyfMa2y$?OD@y_STQRF&yM&n-dvH<0`M97IX$9` z$=ULENAPC}-llwKVm~>W+`n)B>|30flnvrHCbZ0GiJ*{eEC%YM{_03DJB~n*q$fE) z8LRtJTjsPtJjzeA6A?Z)<{%AhlAT24Wuvv^xY>Xn`GXEA!(F+?OttNui(V#$D{AC+ z9kvpHlBGE$W0!I}iD0CP`G&PM8+Qh|%0QO!>ulKenyAe__~QL^{PW*v0&Ap)o8o zbjh0pt|5~vH~q5m4+BF8R7L*448X_w3}Hv=boYFg;G<_a&^dTZ)CpYUBz}rK5vCT# zgcO*1&4=$a^y7Mnh+%^(a*gxY0Q#Z{iUnVJCcSS@)h|AUSdfMjms6XjRm>8<^CWIC z7$9Czvzd_SZddLkGQ^dIkL?TrJ#DrkD0FRArbciUyaws%?13q6~AThgb-{DS;0%)fhf_76SC4;o%N$snArNl(pt=nDI=3X3Xs zG{smk|LWD&k++h-zC+K=Lr4A~8#_Z!o@oa&-4$szYFP^SXO4gUp(4M3@=yNp=;&4d zN_XjVJ2qar^wytD`AV}3^48X}jdo7wt~#q=mo4Cr%t}eKyw7xDU2cScjB9I|)@rWN z&U4G^1`<_*H(P`7+3db`XQ>q)tBic9iw=7(DHUpqOUXWY-nEl(q=^l1sRdT!ZctSI z`KRD^FvpJdD{%>HiRPw)*)gye#>v15^HY6kfz5t3W1Xdm{Lh}v+;^YMl^i^f zIs8ES!2ZnRkJP970l~-t$$rx_S+65tmGSVC;2@W_Tyb%V0hIEtc>4ZMJC5zh-_>Tats~~V0 zf{F9$ZbT3^8CKYvmZGc#{oaes_MInRTGm(1rO z7z#SqZmq7S8G&Gy1fS)Uyln2g>(3^lG|UTvY6gfc%Vwstr;H_{ajMkaaNsVqf_n?C zK`BC>Ew>{P;~Hk%3`zQt?^`h1zEY~m9@ZEl;Wbg1jpnBS2bcnX$)@mUR#VB>oC@V7 zFd|ToU#_aL=IgTi3BilO0U4A~2tcuTu7_r?y^lfX&U{L!vWcGv2w?}2eRE7h zL}%ixS;un@QQ(T?7=#W19e_|KcAGj)FGxs805@RVuWv0;jFEw52FBpWS|`VVMWdA7 z+%Lt<846P&_!4Fed-B<3s?~``41!+J1NIhDZ%+>NUQ8MLahN0Yrdjr00&E(V`WCr+Pr~r%uz)=Zp)#R&d zgD@;^Y&J=uEjiB+-^_y&HLxqt5~9;e=q!b8owSGq%=7f~x{#}f;K6-KcGVBO`t<1H zNvm#4C={6l^26XBS|qljH6%G6Ei7lc8;=WnW-o}d5Y)y0nyola*uZ2;V_5|-IhLD&NB=Qegv z)kTL$n=t^#pkAzN-Z%?ThGJGb$PmdCs$Ot#x)O@yJg(?~6C+Y`G9+tlyG`%()EhAp z6JUd?v|q@C*lH`$i3FHLs+2_X^t58WXG-~4UbfdRROPLC;v=Gt7iWnu7~5tI^8TQa z%;=}7J@*EG^)!sh3c|X~4QQhfBHGY6z(VR*WpO@UnAtH~4ET;;biEHs)4wPk6%(UT zpMs%gJBt0IdPIcuP>1n_O%Q2JQ3j&J%V%I_F>wQ_nz5+7tvu-aCR3K7GROeEXG*f~ zlHp`i$Y8#y@b~@RFNc@EnGRhXS~`WH-tc^OeettC#}wdI_eT?f)3t^lTcRp{VUIpm zs^MZ;Rw!}?d$x9>1oC_8bo0m?@k7tfAO5-b!B0y39{RcW*k`p@t~3j^oZMw5m;ozx z`W9+6W3#hE|Nh_qm4d$q9@xj}b(n0G1C8i>{mSXg{RcA#_7`7$skGvj4Y4c!@&|8a9ykabESx*l zs&5%N9_L}e9q%J=0c~|ghuaZ_t&m2^M(PioLBCiC%xM10RXj71es^3}>r*H7 zdo%eNd4KsD4T0PI=KX(5oQEHs)qwP&C%~8SmRZ6jodtQ|BuJhD2-ZO41$ZD&V3|ep zg|IYulT~Q)DgDjuMU;>^-SofmG~?Hq8}D7#MWK#^7x2p&Gs2OV&h#-c-9(tU1GNDlIHr7|<~5@N zd7aiajRvXBb%p#oaRhDZH^ zOJD$g7<6edY}kNrS%gY4Is#a9o7q|HoZe9$Pe(i0FycZ=0CbF&4&sRhkw_Wt)xsRm z9l`}p1SY2NVq$nIY@QJtA?Rx*j2!3-2^ANBd5$gT5P$PkANr*iI&y$Xppx2*RJDOM z$pIKM%y1Xhl`6TYoG!za8E##H4Qx{99`I=T?oABnTrd5ihEey4;4dC$#5mLcA%&5Q z6^?QuGG9;8Sqv3xLB$dYSLNd$+M^!2=z8zk;%CmaddMwb@hZYtTLU$^rh?tr!q{5{ z=p<*g7`%?Aa0hHYS)50w%Y?5$Fj=Zt_>9~xGBvTUN&}qCd zH4!*_$@RVkf6$eMkCu}I3Uufi9CFYCtW>%SwR`MpB2;?vo92VRiyV5+b@-P{M?NVX zIo>+*e*VzU7JmMl*#gTQ}{U(ci6_l5^j$O?jdH`gm8yV_5N!z!$Q>r%n3`+47lbyvF&_3e?AR|{-WA6H;Z>ryZUOD|4 zzr{CS%|3iIbN_+-v(GdJ&Ntgxi<^NR&B<%BM)S}Er4Qch_`7@Vt`%46!xzgZKQ8|I zCGJh{-2*V?H}}Xx*<%kDfBSOd#@RIq$g@t2wG+v=nh1B=939_Q;BSm@D7)+r(%Jpp z2#*M6WW}~JhK&{K3?91TRU&AR&dhVU2_gnDfxy+1M}8Cm<$WoEfJ8s!3}Kd7X?rzC z@-@S=-dp~fG!?#BX(mebXtb~p%+Ab3hFr0mvys73|D~J$3($C=FII5VHL^T`;x4*P z#McKFu8r8e8*w#~pHj%8p@Gl?jN@K%9sv=Qz=4TYDm6(n2oyJv)x>6XEnZZvFV97< zkWE2^OX;C%BUr5a7ZWljAXL!@4hWIXrkxZ@-YmTTT6*6eGn3Ns6oH6BLk{kej6Yz;}6LU_HfM z3=~khV!_q51OR0$@cnXTWhJvvsHYc_Ax*vTfP?ke4{Zf9Q=WvpGJ?Qi42dBnda7B3 zZgPfuxltnv#jp(+(BwK7x#~&C`_WvI*Ky3W8DgPP&_J~gE}Rz}VD@3Azr=1G{WynW zSQG`OhCWX1+Z+1XW8ALr-I96qCN%?^@l}YXk&-7JUr43242TmBK}C|ERuj>}v<-6* zI>P?V<5a1cXs!~YgPh0e;7T`g)7qe=<$UITkgW0~BmUS?a_kx&yg zpgY`ZeJ!!Rb)lq8OQeUy`Wdt_`o7B9}}3^%5t^+3uSwZ-x?Iw6X{^-1n_QaFX2F)f6KS)w4Io?dl*^Lp~W zy^&`h9$!2~6R6V3iLfE_e6vVEh9#xBW+#GEI5q2}YYU%V_k8X=L!;Uqx|y%}2rN3K z+Cx;h{rz-!w#S5T@JFGM$d=@FE8Hq>R-WJ*)8@tM$>61Eep(*WXNMQ$djPROPQTe_ zQP5(dABdSNE;3Xo)I38=$1U>f_kJ}I{0>}*^tu8k3N_??2!8d9lR$nCo$4I^)rug$ zSNzAmY#cq=I&z|UG zJ!-XLrO~e|*Wc5UP1zDZ+3e)OE}OT@Y+rYqaXSguZVAZitacwU+b(S9{I--vvvybx zwZk{d7vEJRYO4~nH?7+P(5{Y* z`;ZhC{u*CkqaFe;azhSS3wl?}WavWNARbbN%6E$!Kb8p5!K|yjnyofN{)~Kc%N@Jn zNez1vL(^eG<@r&0{Z5AQAQq%S2k$~vM0pTTPhC4wvF0OS;TV5PDku&JkZ`t$VNcYAMsmLI>6dFrw3f&Cc__a~1OKmJ2AFcHd*aTncF$>LW! zMTB?34|YcGCwY*Ebn=Ougs=*_cLr!_Efva*#|twxQPQByq7~;TtOI>U?EoesI57fF zxQiT#b~)w@kVRAMcA5;HUrgMnnTO^S-cB}ZSV975%eqq!A#l(G%+Mm8B^fK==pnkJ zguqQkk#tVxU{nfMv*F7`sEUDopeSr;Mi#JNMkc^AVhtG-nFE*UGD4t(h>l|Z?BYtU z(370D6D?96@fwZaWY|H9A~f5vIL3fjC<$Y>HW~$el6Tci^(2i_2Gc?&*ci;%K8nTz z=acds5kVoSiCAf-kj3paE{ram2>$X(%w~2`*2y9SQ>_?@&X^nfX-NKyfLX zSWKtv#1a4z^Cl1jLtzFHSq32PMHieW-P)53PB0tnhrS?i`Z5tbHx>}2%T+D`iMUJa zhv*&VN+PEhGPU3kloGAb$IhytJ=9H4@fQ%VIws6ZvN47vmt;fl&4(=X6wTtfBg?1Z z1Q3A3GFUgycF&FC6tR9-1+GcJT1#Pg@X3v4@qhqmj`1B(BW!@c)TwDmbFJcdZA;-b zt<#)tC#ESdQJi3AUIo+B9XQt(Av6W< z$Ehh#oeW(lNn6-9+Jv+VO2Mo=bfYB9y+`iAF= zKF=56zgS@cu`8m2fPM8^xVi0p*e@pP$G&PDerf5@bMp`WCUo?x=Ft;v=-A2j@u@;# zwlDL@(d^TYw<;l+?70_8r@XT>ga6ro_D>c3ef-fM-0qQ9QS0CXG6DEQ?;pYYolL_1+GOIDkDZTNF1c!bkodx#qPy_;`Z;1{=L zOg6R9HAPUlvAG+L5=b3xafi)YR?fhc*KCe)8#Zo3Gzz@2E4htZB`RhCD*=SI7>wN> zv)&1f2QPS%H#3!Byg0vo29#b9CyCW0Um`7m4)3V7f*8_Wg_>;PL)P!PXFJgoLKW;v zhBGe&c$0%1lezgj9y~__)JTX?4v^PE{CX${6dPyAq8>%eBJ^a+?sS=4sOjN+rV^cx z4QT8`7Su`dqdeXP)L2g4RBWm_7#PQ3y(X`n@5%lAIobK|(TA!hKdBF%U$4s2C9W=+ zFL@B$ms3N8OAcISONB{6$1+bz;0D+=+hO1uX^c)`+`{BKUM+l5axQuWZ^T4U7||J| zMc1enW^xq|9t*sHLmA#}Jj)R0Sxf1|FXTgdqfzCY&eCPdYm4evl&3ix4tfat00V(h ze5s)w!x`$(!~<#}=V7Tk7NZrK;5Sp2&oRS*%cNdJZE&jSk(1HF(qhUt6P=rhPRvFD zY9q)hmY)V=!7!pAwIhLAD;h6_motG>CAXN^vg1Y%Q3IkzlGKk(Y!pBgRE2((Jw&Pq z12eS;W?mY*I%`s$S&X%jV!;!D3B+z=6J0|c_%MV&OK#*AU3NLAo=`T2!g^b>`}d|)7vlZXslg?k$##GwfrCaA)rN$Eb+gUQYCFMS z_$S&bTtn0n+08IgImcF=@N4R(OcF<5csvp9ZeM2!rC?yl2Lsq`X32$e1bGU zY#Tsak_tM)r!ZQC25$&KT~hC&yb+*u4X!wkYhZ*^K{)?rW2YE-$mmTBou7Me(078N zIE*#hQNjXDl4-c=&W?_!2PVzlD20Z<(~ehH1C`b?BGs6Xt1Mh`e>~>@b|UcYN@_^; zj=q3g3bp`bP`eSe*4SugL4FS%Z-My^Jv;y4YZ00A>mt9-h(Axw>83C7%wqtH=JEuM z>WxmCpC5kdrRNm+{py9sl-V#5b7jv z?GF2}y`D37PV22`{)=bV*AlC(V7(bM*l5eN-<=S0kQ>e9p9prQpA=UA{x}9eB(YWL z)g5al%8AJ>pLU&oBe{QH?k5jdFPx~PytQ^JUrS^v{$?lJY^U0*TjsQk7?YJ&Fk4?% zn^BStv_tdlz*Mv71K&e<3hj3JGz)%gB{WUElI8v~ew!t$s-ZfG078Uu`Z8`yXytrQ zNhe82*>sH`K_oBkmFK@3BP)$#wg5hEoM`hFe6Z5=)316f+3xg87%eaYw1x3I0`g4w zBA$)|@@p^M3DG)z*CD!Q1Y%L5=qa1cDH-ySO*G&Ab!a+tHJqDYh!0EOw+$B!;F0fy zp+3@zGciGTMf1}*ymR!t8-YSrSL5`j=R6(I;U*D{W+HhB>m(I0pX8G4IN=`SBcqh+ zOD3(JrxJ|VWhOk(R-iObE`$xziMjVXUuux7rpcJ-57?qG!qS?t!s?|{GVZzep8Si? zcS5sk?af6_^pFC+OGhzqMuvI7>b1y=WIeNzw%nlcDt~j1t|X2~T1G9AHrk;mo+%&Lc?s z5DnDQb4dpi03c1tWQA;5_7vnKY-sqfh4m!;LaIT78<2pmwW9l2OgK9kFJ~9hl~^fW ztmk9p{9?K=6_-8fQ{wesT6-3(9gGNMat4XYDB6!Xfk#8k)28g3K z(qDejG6tDlyq0|MVEV~NQ5n)>w{Z|lSz@Ft4E05x+XjdDpL4g)ICA^a~UyEFYtG@<(g zI0^gY7KW4@BNK$q)1=K_;!l(cx z*|JB)s{oN8Nr2)Q4iP3?346hFi>a&0;w%P6sEpO885q}_iCQD%&$)&JC-RP@3og+F z557#)DeS7Y!i`pxGbp#-4z$hZu<;rcm#r*}ipQNbaj6?OI8P;nCiPP!$uYOoTbWm{ zwjMgQdh~wY*yEd&xH$@-?J z`v2lD{x1stUU}sOz+a;-A(Vzz^9zNOKVPrN<|*({X(V#>Sg8`OReyM5Y&SwUs0=gc zIe&+=-iYQte+E;D7d-W5#02df))C&GD6dLElI>1*tr<<V;OpiYE*Fw z5Jfv%u`D4@9$8F%nRw_B=`XW1P;17TZEj3=))1_ep{L{>dkZyaqs>;d1_&@i0wrz5 zZ06t-UAH$L&23!e*w*7DJlaMBC&8PUtdW=7sJYpQmMgLVT_fs_gGqyD00dhihEv*yF}tE(x1va?f4c$_VacLO184cv=M+N+jm zk)b1vs!TY54F;C@DFbO7x!H*Tez1RX)@)>;(iENMYhFB>^1vsX8GkI%v@bb1ZN4G7 zoe20uW9xTH=+vt9E;wc!ubEOpjG5Bwsl^hi)kRkjtP`iWg&UJ*7cP7wlABsEJGp?m z$ibQw2;8y!G$-exf}k}wKpd0I0A%5c8*?GIkpMxKimXd>@RT|2D z`-!~9`@n(x*m-WGjMGwq1+bbfyX;BqRp-fwwu|vTx=iapF;YJLB`#2{W)~Q?;7qCK z?=B=yaENi>34koE)LTLPa5=U4jRYmH*;!tPp|D4zmPwA+*X4P){^dNfo9Q3*|B zt9U{ig)K6@d6?H z&Ep<#O808+Z3xF_w1W^hMoln@@pBBTsD4^DwUO7TF>JJhts)$lp$ikC%ah^Fhusk7 zM{cvY84h)}I8qoDFwu$Do13{`o-M?$jwgo$mD&E(z_23~QIZ1W9`4%EUAozf!XzpK zv%-Ux#6Dq+0T{8Hzg&f}aX&&9+nXBwjIm|y)NySQS5jkxthrj<-G->jMER5clw@qI1(nuPwlS&sULr#$Qfhlz7_Iq>i0B%QLyMTbb`U~F9+Ip#RQ*^S9A}T zL%;AI`q{$K&uhm{wvV0aJa)PjD|8<+b^_D+pFW*^_-N((eOj0<^j^%Ht*b!JrN*+C7n&lhQ9J-obXQ2BRJ4C#%Tme&$*s-%`+|H>xMWIGZ7xfw2V)kWRD>-I!@gmR)YzveO1 z=66VmAV4ernun^3WL!;Jka@`1t$}0sBO+Iu{$$DTj$WCITqN<#N6ts{y&vaLrggA| zRb>kEsgHlpu*v_s=V4yb)mo}tmj#GiIe=VJYX7{B#a*qI&>TKApSpuE$ng{7ohK#Th_z zY2%we#hQGwR_{etuuV+InCKm;9Ur5KO2e-Ov<%MAjjOBicww4O$wYlStVn{tByzfp zJJENvM#Kkd#PTz#O0L$*1DG&Pl?nC$Fj`FXds2gQ2Jjg=$1Ow_%3!Y~Dmp?iRa9-+ zzysCXN$30`M*e~c=nHkKa{@6*z4}@!y}%7PiF|$gLYa!61gQaA-wJ;Tu?XqbL zSz&}~E%0Mi4B-^uKlsOM^s}}Q0$ka6hnl_z((;Wsj_D&U>Uk&4N3S7v>W8p@M)n-Q zJXP_lgN;f7y&Pv_cQd-xiUWyx;`f}c2bGbj6B&qhXoQquvje31k>}C=2ES_)LDz> zsveXJ>BPfu=)!37`fQwfuAAlF-F;%!TL~0YB10gvERtkKkFap6wMwUcB#Q+m*-QZIj6dnRFalx z9RuT}o=03VCAksbF&8qMy`K41};WCTwA)Ic$HLjVK}BS73lyPy#a z;(%KemLVcw0i!{V)$0DVp7{T*nuVuklvyVSw zb}qXIR2@6<-k9e!{+Kj7Ji}yoW2%@ySFUY-H4gR&Afg)cF<)a>XP1)0@<7ZyA)$s; zX|^N}F*bK;*|AfI&dFH1Twf@)`yl( zUUq*t=sPj8avHy;Yw*xhOv$!Ld|q2iknbvu5bP1ytx4ddL@>(Cgf9^TIYR>KX_o?e z1}`Hb5nf0ufIoyx+R|wqluHoPG9*WmvSuGbF{yzFnJD3pl2$;Xgoh8^qky@;WbhYAkf&n@Rw-_8vhjOwkl9RsF5VlB#g{lw0 z)RW!ulex%M$^*{m9rZUmo0}9;7;ENU2blo=UQA)jWxC zGw4LWde>+`06ka`*-`_j3nYYma1C?>aii5TWP>Si$~?jl{(&i5^FjBKJ%yGvNirWgC;_mJ6vO6JiJjxWsvVLkL+dCT_sI;wpvd z66VZDO-vA2R*bIZL9g>AU#7G`M20;$fjwGBo76xG0Ru@wT0TAh-5bdRdo%YREPwn? ztK`T1Q7iF%CEbOs>QJ{KED#lok*_5Qt-0y~{OBds9rdUr=>;PkGk+|@v!&#q%?DQ0 za_m17D@?`mQ-RD#y67StDQR}^O52PIuu{f{^cOSGz{Rh|7PU-OD{++=45^5O#b5Ub)RQ@72>ZJ__2gA zTa8Hl!r9D${q?}KeqRpK7eXzyyrbDij>^ltci#=3t{nfU6P#%#mzoXP(13t|IngPE z1L`7?(MMzj+qNOPqw15|+EKDF=5)jJ#o5_63B`m*G9!`Sd_4VjPu1ZqTV5m}Q&{yv zRoju4FF61PqAHt+GZnwlpSn7h8JLm}F`U*o&@J{u zZwTn0z@kx{7CDOs^qmuhNIt= zYb(T9s^u>6>(o%W?kDD_%l<|?S7}C;l0$?n2FA`-?vT7mP*d+oCFD$VSia>@NgR1& z0&DZzzLfqmR6+o4v?8Q-Ob|QMDAR0(HOE7Qdr&Yz2e|;$?2Qm*=At)T@rfJWuV%v6 z2baE`mbX?f+zk4zdrrjilflf$Z1@}sz>~FRvRA(9=@eJ;Fa0ciU_TH9*9JYWug zMjkS1+yQ#R1Ks3UD&N={lCI%GdPXIy!i5k^D7$6K#7T_Kb&?zb!n~l*txqNBIN1n` zx3`ca5(R*i=oLQc=7d=R29f{3+%O|1YxW{W8Xz;|qfh{wL+0FzMo3F|FK**YEhI|$ zb?~csRS;P@8KCb7!Gfgi1ly6^6b{evOyrX3j!eEH2dx1KxJ^m}UXYMrfPh7T?p0$m zQpS8@YbtbJhEqm*fF4vs$&lG{+1V&s!@E{eH&GLv0<98jv`$lDcZ)KDRI4Q~=+)zUjQ68Vig=O#{1L~C{I+y7Z3$n<0KsspT*Sck$OEu zI1-k`>g0Vx03x6neHj&x!4i-(dg=4{(fd>P-kZArKz8iAbaE26f;0hu7khF8eTNNM zHIW(uHzPEN=&w?OCGHi3XJ%Mw6t*EjDh7ll7;6;gNluic1|yu!&_VvgeHeWuiZg|( z2WQ`SekTvOD|J7GF%0Z*I&=|5V4S#NH!PdSCQ@=M0P2_*Y@G(VovbgPo~sJ@JKj3{ zbMN67J;%PNzdKm{6M|*5vl=h9WC?ZhgV(Z$?yvWqSzGIVU}M#MgpJ{4y`8T&VzVsy<4lI9i6{aY@q~{sW-zb8F|ALGw^QRHFrls(Wnw3AYQeE zMk@^B*EsNlL}x{$CeB;2Gy?; zrKno-1w<>-P;@T6cW?E~=W@m@H=@yQ{q=BjX*~PLvGjfW7<=5R21<>*eu|^D@eVJk zEmv`evNz|W7d;7Cc0x$EJoga(j$KhdL$yBd7lTVD;TFiqXbMw=VT_jFp1WY%Ss_f) zC>epm)+{Yy)%euvDq530%xMeBke3P3gr=Ut5De=>gFB}YyfuBZFMWM5JCLle_|iA2 z!32;i*!)KH*n#j1ehE|XgOyq@(5C?^e4s5XQH&&5smm4(Bub4cmZ%4?NT49LAPQ?# zqB~P3RZ)+wk0O9j2E1W!CtScV_|;5E#naV%t{T-K_G1ZWpN-A;oa`aGqX0t*4y^@3 zo8a%yBa(_52YnWhWX9a6A7y9(q7|8mUjj4Nx8~_985@i$dXCecDKfns96rLeMGpQv_Lu<)sVH#F}M!`4_ck*i{ zLU4HF)v~X$KBS{0ek+4%V#h|rB=nG;RT@r0F|>#gP$pH933)&a{)r^X5d2DoYY8fk z7iYZYjRA-Rsdh~I!Kv(nS_p2zxSqrSsE9Hk33`EtQ-&Uq=}`)0z_`RvQp-Yo%#~OU z7Rt?*04B=MhA+b{jlzIq4j@CyHw^bq(Gy{59aSQB4mQVyofsho&Z|v7N`x88&{=$s zV^AGtqf(V%XQC1w0`n9g6X&b)l?$T0vOzbUjVcjMXdQmELd>9xzYXSt^q4?gsLI?G zCZYI}d((UO1YUk}bfNpHB5_C=&wZaRx#>H#0X`5frYlzi=VqcqGcm6_Rb0+h}0z5OB_oDlSX3i#efOq)jgnMan!Aft+Q~wGsmCF%{VWLLS_Amw{sB zDve-9KBFm*>`N~7J7nlfi95)QsrkeXFuK%`X*@7JLj~*^7eKt3igc6OXb}|48Bvg| zrk{yWmK!J)3miTsx@b1!G@|2Gww>G6N7&(#*Mf$HFH&?Fu!PoI+2W) z$11Qldch?#+Lm2&`PJr7r3@QZlXL-lMv_=8)lN)*>3#pD#NmVTp7_g8EzHX%j=F$> z8-2+kXJ=s&5LRt4SnXmInnOOoL|`{r7G}hv!k36e@PNjbQiJdb#F3QWk#FH^#wE}p z8S{RO^cu{KPFro+62DYi3TB3ulLM)WEV*Iml_<T9S?1F`_g^YW$X2ChOo8xw4@ zbrEK!HUMFtqyT4~+llTY-i6ra*IIupIlHg4){5jleX_oAS>jcfw>V=ew2zm871RbW z7;+HqhAk1h=!oPXQ`m@I@{t;6x7v(1`{=REi_avJxHyMp%U4lgo^cs^!KHKlYV!6ex3WEp^ z_IO7E{0*o3htmD7(qyd_0Vlvel~)?_oKR=-v?QU1Fs_Y)w+Kq4R~!w0p;Pz;8gcd% zBA#e;Wk_t2iwxwpvqTfLNKQoE@}$vplV6D~x6+s#Zfi@1vJ+%sd#@#$AX23(kw!a4 zbfr1|?kL#X(0ufEA6$WO1jM4fBjCUc*i8RIe?Is_=ycMW3t3Gk+h_w#*r2RLuK;<( zBTQk%Z0`s1n~n63n&)L;5s_x>8iFe~mggepBSrUE$R97QR2wUS%pizOTfzQFHjISQ zci-Ju7#m!Y=cw3d#mvSac{>#qe5J=^F5~zMdrMYD()NYy#r|s38+z0Y*kK z(ldWaqWCihS}j!}TbL)T^i-mR7ttvUH;@^XR4P;Jm&pfks9k``W=FoQLP!F#RGZ1= zTrpnC2MZ+z=;GmK8Xui9eu6Q|Yts-JOFc>#EOKnS!}tbwqAiX&3B)A!(F8)EQB(s_ zr`&5+vgu8=LEXCRM#|DtrO(gyJwZ{*svWX{N65l^K`V zus5Ar&Q-kG+I+IUkcMjRRMnS7l7yi_%uh10dAHwmO$c~IB`5+0h&Y|q7{SzPmIL{# zZzq^fmN`uYGq5FX`9OAzkY`}=mduUsV7i5xY_yJj(s67CU9Xwli1c2FXtfZ(j+{9| zP*#AeM6VI720I;NU`x$*7>_36(;_mV09Vl?>5Xbh*l0>d&-v+MMYd<6TKb5-Y_$*) zFv=1OpV?S61G(dyiz3j%@Y1Op-Y;dVVe<@KC%v2kQ9{?+W%Ucpo-)J`5($-K#yale zDnh`RRUP^Wo&c@M3|7f`*oM}LSQIBAJ$<@u?7Yk8i0_-JsjvKRJfGgTH~z?j2!SYs zJx_-(l?~LBs$$p3JvtSq$zGX6ZiYjtYD9L}K7PadIe7?O&>VWlW_pW{ zwx$U{Az@SdNLn?vEw_YoV_YiMeJk0Kjpc6R8=rykX5zyH_&^WV(Q40_*tsE3(dj~yAg_}Yl?RIK3b zY(st!25&Ws@6&Fr)h$M+v|ZaAf#|aPBTwQ6Myv8v(s?fmSe~6EN|9$5vS1V-PFi%{ zYl$#|7a(oKLd-`LG^f=>UeDq2Pwu21%J-t%a-KAIC8Yzxw%lSzhMw#Ji7~Bv7_OST<3Tv_ay;5QzfFG-lSN z!3>d+m@e!^hvuVwGUBOvV4HeKY{XFN!A3y|w1_WZ`amCsQ?xE)1*2Wqz(h!IKuk^& zTU7$viQD19jsq-Vm-ek1Se3^>#sL^-q)RT^)%hD*fk0I9fX^gCN|KrABXv%MuDaqA zp474@ll5eZE4f^(SPJBe&{8%RE2Yev3b{r*%c!y5&edC)QazWd=D0c@&3iMcOf^<- z$wMylmRS^0FT}1R4b%aKBai_BaoSDw1!ZbsBG4TS;mKq>G83L=Wd0qjA~)O*XX6a= ze$$Zt(BaIAwOg~C(8i&_<}<6pQ8YO2-($_)O391xw={+#2v2DX8g3743b zD?T|Dx+FVw5y3NKlfmz<%Livaos_q{`{@g!vo~6TC8URtHEm>Z+qse*4f<;MDU_swEOYi{>p%6y<&_<3Bb{rO zRm7=DmnM_}gyw|T5V9RwJ_Wi(_0(X1S`4LU|mSeA|d3U#sG0(k0Iq>sawegQZ(Q5SUvV-mTF4J)>_BTSdrxuVQ zb9EfFpkx04L!QzWM(F6pt#-6>>ZA0& zJ?R7cim$%ZxPG=Bo@*uD_3T2S=$;6koeiIl8w^KULZ>3r%JWuaCRK9g?_b_ z_4OpO!g5e|w=ZVT2g0Up%bOSgB{%~zNd#xq2jY6ycH%sO;s84&ve|o`gqz@KlmT#) zYSn898i-NnnLzN24>1f93KqKo%fuJP&6*`_8)gXLl(biOB(CNv-E~2k^89S%5^$p0 z^b10DY)n{d1~i*PblFTpc8y=jh63$f_vBgAfJ&8(|)5DlTsJPPoJ!LK3{Jsa|2Uol*6Ocv)j2G?q6#-peZsD$b8 zm+?9^E8EuDGo$n8pRgr5qZ&@901>dnP9A3 zUx^i?i>dH(A{n2{|oNg;Hfll;;U(HZAQ^%5Ti z{m6T-Tt!fXs#QnAwnWI=G`aOOb{oyhgs~36HO&~@?8bUIk4>soE5RYTgy=wDz&D1@ z=+MIIoj_(_oO~PCj#w}fZYQ81C2K9>Cg!zJ%z%`M!^*6%aYkDk2e_p4$UJx*T{+{9 zGe$o<89Ik6mFhCJfT>_<3VqBYB-tQ_-x-6V)R6c~=rD5<-R|JaG)g7QiJ_%abQw7#SUOT`gpinC)hBnjJksM*y)Cb)VJ9dEk07AUN3IZZX_~)i z7R+kpPXNK`upD~fOlkNL?zs@}uQkQkEOq(Ev>a>xIN+~=Dcy&#*6_ZZtONLteo~fC zdc2i9cCvGFx`uEP8f!(Vm-uht^Zu^v4>>|plgV#W@m?9ef8&x z{QlLy`ajJ~4@AAgxep(^<#P59aMq$5TU*!2-|!RuNGF&tio)zqUHKBU_G9nVT|`Dn$Egv z)2B<9-paft9~{pu5~EmN_ELanjec+_-e+cu`3n)*Z0aF;07YoX_7S3_cFmq7XyZQ0Jfya#$3IA@ z-W|KHubtt-#1>~gw%Cp|8M>0MM=@_W!OorKsf1o25dF31duVw1%ygvh=E`Q6a?(;# z9`Zmd>6^*oyk;Wwj_B^fTzsh^!Zc_`9*XTURkNL72!U!EXszaQB@elfN^Ak@)K)1r zXI9TZgdy@@vlUC0e7>Z7;SGnO4DgOvsRMU%A&y5e_=8K%v^!C(qk< z1KKFBM$cU!191`qYp_v5FlMUN>PbK+#{>wH4F?czNl!5av$dW`gP@GvGj`wcy&kUG zAP&)e1cG~mY+y_fQp>C?HtY0rwcKpXJ>u^g_m3ik6Uk2^7LqzG((Zipiqqhn2Eeg$ zWqHFZ1eOGs^CGJ?XmpFYY`0fK4XyhF+@%juhR6QvM7 zv<8$CH9K#E0~kIE+S>>~M&_adRWT8SGy3&RPh8e&nD-v8aW5ef)5;VV7NR$tZbMJe zZ+h>&{@0!x^`0VPqI&8?zc3JG3=q49Otdh^^`_)7TE~XBfPla`LLs=2KCWa&42qgw z&UojN)o^aEiL%V{VQwK*DZ-{~)|SED@No(NZm^{r-Y-0fu|Q_TlN_KV zoS=n5O-5NZNTrJ|WW}XKY4g=K+NBbs1a>1pZlra7t-@f)8)FK#7ugwHUe~9E2qB-F)hKiJ>$FZcKV)sa?d{5&dApVX^Y!wNFR-9TaXw) zLDr9>l%Bvn;5&{+)SM_lf<$-r>X?x>N+h(>1sq>zTe*cxL(8YA4VX)0pcU){57HZ9 zJ5zFp^OHIRLXy>{L_fj~tt_Po{S1mE*a~}QM8N?9F#t$DzNeQsqsFF}Y(jnNJK5yr z@NYwhURXT#dF|+l_Eb1q>&UAr?PfIh<@2TRXsa3HE?TLzvh6lFJ6^wWHgo@h?30hB z#;;9J5B%j{{?`irUVQOsuwdq!PqNQGvYL{aKWmhlU$b2mW!X6MK@{!k8 zTC$lR_4pEfg_FO?e)wqq%&)_X=a%04Ip&ml=~-87axzvK@Gs27+>_yznaETmw^%4I zlZ-0WK)K@gosh@_Fc?yt&)aF%#ws-txyoBX|REYWIjeRY+ zml|wIpsM^mN%0j)Rq=H9{+*b6)Z#2NY%zD@cfBLn?$5>zfD@!OAbj zX5LR?Y(vz=fOmYS#E<|9xPr8&mh`XMype{i4&oM9Ot$@!)hT8NE{f4Q#q5n_0aVk& zd`}R#4e2v6J;qOowD!_&gkhsfPzqvMNl#TJU0xWS`4|XPk ziGK%N0a+M^xO60}B;XIkqf$U0@S%2Z@1$)A2`V>SqMw`@H6JG>4cE*}7))a{SOB%F zxI^YK3Tc(tO6BHhuY9QqaJ`fst~Nu>PA*iCS4263iNFR`MGI3H2b{ntckxRTgnmt* zrO)0?@40t1GDAWIvE|Ah0-VfSn4HH+}0EWmh%jVT_ znqa&R15QGu@QhT2d1Gy;nZjhXaBiwtPlk)-8)*iH=_AeQK+t4*sclCh zN`y&a+?bPQrbH$tb7nsRdPj3G2`4}n4dVXvC{jh7>AUYr- z`S4{|RJM}Qd_YP5rYfOaRUT{sVn`k;Nu(`ZFzX+1D>_Jc;nH+SmJMO9aLZMCN^O_{ zY#_{xSyIf6NYa-cDmRubXrLJBS+7!CzT%rP3sp&h`Kqs2T>{)|M|PpEk6;*)+*IxK z=kodd=bl=v$zCcl`(-kyGl^oE_@+)j7#EX4JO;qu;pNl(wIeP)=_Ib|o>MSP=vYn; zmukyMc$}zfqA^iRXN8rFS;{&bx{0xI3A4AO3%Ul|Aki)CHRVM`3ZMmL-hw{*C z=p!FK(OvELpZt@5Jo3jkUB7&>@Vj5Nd}Fto;)bXum-j~%2(HWL8L5XFl#|_vyC~dq zvWF;xWJv$|guz;clc)sI*(EN-WMUMemf##X$6&ry^dvucIGi3s&Q?=OI0*Lw{)oe1 zKJZ_&0Y$|Z%+|hLv8*N<4S(vy&r+v<9td6-UOLXmYVm_#r0>0F`NLn$g!=;-&v@v% zE86dl^#?PHvHVP<9G(YNk=pv$xEFHmzEw45p%j z;-nN?lgI1Zy+a9s;KHz1smtKssnb$@$$pB$5i^F4&>v*r`(h%Q}n0sfku{QA0Zl_<=TttNu!oxRYwXa8=e(Evd} z3ZM~^7xF=IB%00s8dIcx1dja>!0!U^sT6=I#7E)?Sxs5T?#c8LP$~<6C!|9h;jiE9 zYE5=Wnh1{Hw)t2P`Nqs0$_xRuQ74U&0y&_QVKZAmc@(DZT52RI45OaJ4Q`P+_LVbB zN!jR*Y*cTBG3ZEcf@Ca7ZatlU?N_P$4^+Yvq)$K$vVdFiD?~pHh#r6eI0VM|l0!5E z+vEvwCmBK^h>|NdxDX#V`&xBHLlc#zU{lxty5U7IsV*T+S3T3=3)7(sWB#+0Nfc*+ z0(6Haa5n7@#bBF3QlaY2mKSLeXF%d47&MVKANIwX$x?Jv+2CL@bOA|XG4kt|{as0E z)KBV-mQwk8X?0Cj!p+5Rj)&*WquX&c0`5f%gc~?F&}YjMdrQCq!e}5PpV?iE_mh(% zxk(x&!Rvz+LJ7_7n1PTdCSsme%d7z2m$?~aXRkac-{?R zNGM1rFqEjAkfDw88_0~&3srDm`#}ZBnHXmy8V9N3Ja%h_lJYre&Y%LBbTl(h z+_;>&3E%^`kQ6x}-oajzpe%cQL>NLWfBb7rkZ6rqVu z@I9)h7ivX!NEAkZSPROf<8X)!b#zYOIRoBOub}|8N9$I_@Xw%#8p!JeWjZeF_6(nB z8P&iT#RxrWCv=3uaEOyqj8=4@rL}RuUq!AI!_)btUH&p=5ZE2QEVCC4KRz4EO+@q4 z<@z#mFmqZLR??I4B10Fk4GJr!kqjgs-jF#hP@{H)^Q2hX!kqXe>~NA$Kp15d#Eo*s zOyXjVz@vH_5ADW!{Fl7WFJ?d`^ih4#L=OSufAuY{A9*(ex^p;Ht=8IDPZW?iqihQ>60+vTNZ zWUSqixjIs>7T%5em&$;@BkyDmJv)Eott7|4ztNDS4t88K-vhk#X5qpc+C;mZsI{`4 zPWMGuM3f&mKl0m`|J}d*mkRz4{>5JmKJrND(TC){kp1`7FPy&B5w2>TK(^Ig|K}tl z4Iqw$0uErFGca7J$=lP}imW#2xy4DQq>to9^y5ajrOO=XB~D_WNZ2~asQbkH=oeFC zpN}reh5%$@iODzq82sW1{;HSt5avX*$yYqcv(=U<7AzrUzF=fA4b*AHqTciI!ep_= zfM+3>o{qfoY0Jxe$yzns*($pMJ~BiCCXLXd7x(L))>wtSYj zku+zU&^3J9=)2Kf=GB~p{a^#I1dh^lxf>Bx7?xvrmJMKEqn!g2OVTO3o#9%^F3#SK z#{5@CR=DL1YQe5v}QPIv5@G%Vjy^)b}IC1m2ke1RiZjUaT; z3DAVFsPUIy&Ax~HC-lRcT$0Jid7WReg&YJi=tB^RvoZP=&2@({09=G{YfaS6)%3o-%WwU3a^*Yq4Qm4s?V>nL z6e(eKj0ZH1&>Tds!+F{1jTZGTY7;W!T4*Uf?#4;| zaUR272XKLb5XW#x0OBv0$(aDKL;F4lG!wdvougAO(Pdy0 zJ}8f#{pSMdQT`H7rPpRhRtmQ|5#&H#;gUWh)_S-F)#GT`Jib6@v0glyn&}sy2encR zuf&kxL6Ede=8cL@*HXa@9yc`~lUKYMykTb4154mLnc3wpx^P9W(Jp9g-Hcmc18#|XVqlIp z2Gq3dU*a;xKzX%l4yZ(9BmCcY@47I|A-PzBQ9fRpM1LS{~gGD=)h6r$rODOp&Q zMQmAlJ49={4ZV4zDbIXgUOx2Gg`*$In;*bI)4EL9@Vi>{=H7p_onPX(*-BQLSx}mC z0!x1X^u@DZ|A+tc{{ZCoAN~h_|J=uKdq%G|`q?%{_Dv7vISJ8|37w1iXb zk@9cQi3q$MUP<-mssP`iYHP^?eaP8yC!qprgC7cD#tgkkUKl4@UN);H7EZkyed1W` zp+kwo2jdSOj6HlP^6Vqgm!FBf^Q-vJ9|->PG4H3pSpNLwrMF*HihcCP%+$s4zy)7& zCYVn*+6*(i;3~`>yBasMJFSMSE3j0rhr&5el_*+Y3f%ZCwddZ_tG`5{g_ ztO!eR1%AMs2ysM39Gqj|FAj^G8AaO#U=Z@r=OmVZea%k3P+P`qz*huP!kR4)VWrN$ z+iA>yek33(@-c~?w_B9xJ_A=|UarX#SA-@nd=NS%9LN$;nLFViFVFb<2$z6FZsRIS z!e6zqlMBl`@DPCh-SG|2nLJd6IlY@;`cbb7;q`?98=rbwUR<4M`CG$`TYttko z<;|=EzZzdSt~P?COoU)f8K8zgz%4cn3|A*1_i(^@^5~ecW-KOJOw`*%Pub~8a~0N1 zmc^`*7@`KQ*`}#2D;sb2k@FBZuBED>FR}bIK?Il&8{De`C&3_RJO{jvnlLr{)m;NSI%s>OxHB&uJI6Qn~TNuJa&3n%S7C`9ruUuxK!8uTRP z6Ve#GHG_>BQn`w(4MlO${4{PQ{oNP`D`BFTpK3vFF#tmAp{<@#gc4zn--+Nk%s_hw zdj|B&*B+fKX)sO|FTD=uWJVdi09iPLA*t12it=!_KKw~~>G37zs%2%|xB zu(9IS*e3-R;@4>!2d_2)m?D;sim^kLIVL(61yf3G7@HHV;wd%)zzL>KPK8@KMO^Zy zZ|YD1fiOgw314)|mi}tI;sC05mcser8{W^T3X`Den0$^;3`2>I!>}e2h%{p}$MEuL zL*Mi*e%|l>>Z0rYD+?c)@Be=5KJnZ1ef!ey{I*o^kVN5)s6D)NvfukPb_hQZhy**- zFk*=Sg)!)i<94ET>=5P&BWhQGT})A;vH3a+!bD%l>Xre@bcay{;w6l$f-oT(6$zM6 zEXV_2BUlj&Sgm95pP7uQjGf4R_0x7!K1ij!?M9%zW1m(I{cQ2@OG^)(lEr_qVqPn> z?w0-Z>8k5|rvpsSHroalnyb}nXlkne$b$!T+V8La>VM#GDkb~TK=n)Cr1#t#UOAs^ zb{A6j5S28V;Z(8vpmTL&g+^0i?@FpP=S^ILa+U7w^ozdpYakS(-8Jm{BR(=~KWzqG&G33F0u zBTW7hHpw+u^$pJ#1T+GXinP^^Xl4gMV1$^l#?Re|@g&hk-bZwN`^S=gY{L`p*XPSL zs$-b$RrB7iS|bpdtbuux=t&~PB}xMLWXm3d=`nKhZ%@`BG+Fj+ij0_f2mB?F9VJaL z#9fiE`O6-wi-{ZLBU-^*sq_EO+JFDpb!BBBSK#Xm%(i zPh)j6A2^3Y2?~qeu2+f)d6N9*9Ag>m;w97QGuwu?PsF$}G-Ub|vwREs3hDC$S5Bndr)p#xQM zQ8YqzLcGA-X#*h&leRkm&=wnZVhHiiMrbB3R;4@fOzYM?OqprIEm#43;7#^o;_$}Q zI8oO`XQjxVz)|&dC7sk#!b|Imw`DLXgsk>z?a>VY<&baTK?)^gE4VGyU#xgZgp6LQ z`jEe7O@b+hXh09NOg#B$Wc%ibyA7*g?kE@R0zT6#CTe&}ia)HmLtb+mLz60X4--dU z*)p&@;z?yjq6JsNPToP7rgiR04&fdm?zgWon-< zA>Uva@*O=l`7O!M>Yp^mj9RAmpP&4WKlwd7@pbFefivS@v2k+rvlFAAbj+Su&~UXz?I$nATnYh^ zApo~plP70&g8YdV2tGPHECk0SXy;qLsCqkUwLnxJO&vFn2@9$g379tuRcZl7lyDmD zET*Ov8q%kL00WMzIcMs??n2)om!HPgKTr z#$!`GEwKdYVeyIV#hr4g#0o*U!}QTlqMJ5EAGqKB{%-HZz0vr9Bhhjudgh}0*zoA# zWXF-oAK#C>u_f`{hlLXd3nvd2&;Fb{aR|yD*_ZyyJF#^Sgg0%B96prIguN*jhSW2< zckJ{V-n~z|zJD^492xST@gzteUHLNb-QiDk2ip&Yw{J>3w7t@E=F)7`pXj8ho{9DQ zlJ2>=xFUdS6V8Q0>HE6Tor*;zwv=dqs8!(l=TxLcOB!4_Q>3t;KrCc2(u65Q$F)eq zJ~2q>8hD62qVB&ek#sbr61AGL01>HRUbUMlOtOt036kVNs{xWERuCwNki>9Cp*La1 zL@-@6(U!z{-B8j7n&a5u6uq=18{T7B3r-|;RB3wY1=eeml?$vW+C+3-G#~82ZY`f; zf{a4)CHmpW)Ni1}eA$hAQjjw{W0|2`Ip$yP^%M~DY1(5^yYq05`*@${e3$Da&JMt} z5+%eodWRF{YhC!pa*(rtzr}02(r!*}U|J>+;94A&h-}_@%?!;dlwN%k4iKy656EE8 z5M>z|mw--S;!ku;Mgbf!Nz!2?J5@6uN++7bF=vruth_rOmaN8~;ECDUcqo_3oIFgO zo%-?v0vW(|CfXWEb`wt(55X|~+Zm>3aup^{_Jzn^WDd*--uk^KgP942vt)z>Xo*BX zflYI#4Ik~rlN`l)Cub0=3}Oq|8Muxx@j`lBU`QR~w~C_T{YmdntbqA{1Q8nuPu zj6I|WpoSe)u#F6Xz@aX|z;;zIs=AzB; z=h1+?*;stWCAS!AzF`|wgl|m65J#Q!6!yU!ELCO?soJy&1M)&6?;u6>US3IBBgO0P2CXs1}eX&2U>R zjSc?9wPj6I?h%wa8`X1qw`^aIq*#maV7?lHVIzO=D06`srU2nJ!-2EKYS@z;rwuLP z7Pn;}D^JirBZ66B4ATYTz#c&pjZ4C-1ur%HQF9Nj3JtNaUxRO^=)}key(eAKPUO}) zeemqWSBx^?J9g2rkL1UoR_JG-Zuifp#y_XcxruLpeMg5s;+M1dvu*kyZLAyhlzMx= z4Lq?uwsK`;-P+Kj+r7g_7_?dqU}o3=uv>79+`cSO6|X0BAT**d?1BF9&%5)op)u%j=#^&y29K{b2p8 z&TOshuV!ZQ<*+}K@~4CD#F&5Y)7hcpuG5D;`%nMR5C84If%gByf8GE8{%@b%^M`x> z!{00N`|tntKlS%t428z9b7fUL@wsQ_G7A?mpi;vftH?uC>eT$=>7bKrNiOBj)&s-@ ze0(%`!EXE*45(VCW)X8~BWJ`|+viUmRb)8d-lo z8VsNOu8^CSdyPt?k^JDf$mv$k@mALi@=qCrbDDPD}Uby(*uMZ2K6RKRqwQ6 zf;1+WlYgDjHtS03vV<0}*ruI!a>eBSnN-n%`CWNao#Z1T15pvL7f*K`b|<<|j(v{P zSgE0v*mGHG{m0OWsI&jVNj-+*3i0u;g1t zCa{DvB097{BG3vDB3dpsI00~C*3%LBjssNyjJhzgh>sYeG@5^WkM0^7iw?u0`kiGV+e#g)sx*F-deQAAJnvUH3!5Qwoq z{SzX~(#9N;x5uHUKF@J-7152vM)EW9Xb2x5zK?}kM*?jqk~zZ%=!#NI-am4sks)hO zT;Atb4~!%pc_{V7quJqeDp2|?nU?}uq-L#z)iNRh5hjTU;0DZ&$&)j{6O&Rm_mjY^ z_E;WJj06U6Bvdf2?q@8yXHGteAzy4{4}n|F1@^EQ@)?}4U!}? z+ekBWi#@$DQ~GK08BQTRNLf&e26Kri^Bp`p!Lvkv^YRz?A(!I`(cD-(@6440!IZp? zm}Y2)DI;(iBXCV`>JOIrUWKl>{Rm=?48&Owi5wZCXp%j+%4&n05jez%I!C0T^Hm~O ziMdDH6_C-Db*@DW#9ZvMqA}B9vWOH5;Vk5X!{9u$$8Q0h)TU$Ry?Qz*Rz&|GGxk(# zfkMTVE;u4+zbNM^mJdSBP4HR3yp^^Feu`(Bi^bC$sV`di4#qUA_ zfQTRptQo~>01p;dw4oDkLcY18!2+&uUObl?Os@r?2yKi!F*XOt z(H?xsbdVJZyI4ukvd1mo1~AtU#EeB&ku%(dn_e>FB)_6-$&`X;&KA)t9|-2?Hhn-dRii*Mf&U-y9QxqmI&(TBFg)~<dIi@xr(>-;uAn$kUxt%pCU@C#=zhy?ME*0QIQ=tCawMM#DXxw{}JEUmM%9 zD){ck;X!$Ue3$D)muI}oJ_0B6lW1UGX)wTSR4nyCpW(?zA2sdT1H|&7%J^`r=Cmv*9@{O zk?XCc0VNo-ZObE5L>0}jWD4t$o$yT$hxhP{Z`!?20}FxLLK+x6{aXzn zl^d=^hSG7(&cpWGogp|>IIH=W(KR3}9=)pY>B_{_!!yx~j);6r**ZiIFb2Q~ru)IN z2n`}t&6wDTU>AG%8E`gj9tK4wRe7#a;#jpBDpbO`a&kg0EneMFImCWKvs&j=MBXjODL4l1Q8c%iBL`h}fb3tWMZ}HBW{IEZFV_x-(U9 zkgk{!Ay{)fY8tU!um(I?B?Uy_Af;KF1#y=EX03=FQ@bo`~cT zvXmudSECU^HTK3fIt=nq%f`Au2~`7J&X$7nQXOezvG2zKz8#q<@2X7J1hUC_DsTK&AG;qbca2CxCj1GL{L;wfvnIP`JG;+}iCES1) zvpEY=#{p4CEH`fIT|qy^vL~AJ(GMGb%QzYM*9V)T5*-pr`g_q zupY}&6$EnSM81-e<=gP->3qxgcl;LQ*K+F(0R#IW-;OOUPe1E6>PZ=FPxX|J3R6 z{clb0dBOGa6RtO&a(wnu{KWUAj+6Q02XbHTNj>#=Y|ZM}nl;JC9?5;NCwJ=S>S$Zl zGmvxjW?N6B4}P6_@3qLYJN!GhdSBTIcAxp>wZvCX6rC5-dB;TPygLan3ZWxcyw9H* zGakKgCnYj3*CNGIP%)nfvnt!DZ)oDD;G2)co?RV&@PVmMU+Nj%OBHc``h2_d*oDdO zq4vSA1F!Fjtz8{|=85FM$z*m?a^jWqLg0ixihR4JK}}&<$-DTTG9{!`fh%)u7yVlM z)m6<9Au=O1Bx#Nl*{?*x!jb8a=*l6?OuVTcpk~IKs6(2-lSOc4tJiFa7r z7FjXe9?YkstukE6H5NECPky`5Qr-%(5FQDhFo}l}DEJ)@o+rcF9To=k zPh|$PSLe06uzj1z$t=kG1RQd){mBfA=tt)Qa3tW<=SbjG*WxJr0`DB*7KoHhKLb8_ zjEu;@wuWNu2f|?^*k9d!5$oEn zMd;VE6EOy39&9Xtzv)Pu)l`WSm=&Xv9tdGtJ2sI9N;VwfixZ)X2#7!s&yU;NC?PU< zGD&XKot&a2ISFGWc-d=u(!YIK7{L+F3P<-RHf>11_R@S!3LT~aX@0sIQ7?ja8IEmZ z-wO*-m6{K5U^+kC>6X`In8pzRO459D9Thrbg38_TZs3k)bSRn|)!v{%pIl%i3&I9H zSZyF=N^gh@sDXBwW|v#Of(j2Dr6nF{qP8pzf+lH9$|R>cW7G%Jm^F$gLl6Pug>-or6s zf#7BepilNNFIZIstbYO;m=p~#8v>0c6_p9I&J?F)0nglEOZs6J8f)ytD4dHt-HC1_ zqotDej9#!bdt-|*QD3rOs>alSfZa%o4vMk>++bGB08Z!@6s3ot#Dm*XFF#*PPK*32 zo&f`H{wk?_P`y2H$Q}S_tV3-{hBku2HZX%^G29aS{923iq5*brPheRTi;FVGZ@XCZIIqr&&fKe3iK}1-X@ADkjJ4Y>I6c~`8lpmf9 zosxII*JU+Vy2?)?2Q0_j&#+9^X`lJ=+~hYc)B9Ve51tzP;^)El*=fIrPYJo{3OXXP zRy6?Dx&a{&3H0)Cn9rB!!zq~Kl=p1(*(YM#H;?}$-Rda>w@Nht!owJlGbIqGFbjTB zr90MzScsX(vr_ew!#Jx~?&X(YOSY3M_3`#(VFDz_S*V6-8Z5GKI}vV$Hv3#h0w>=| ze7ker#63nN$Vi{E_$>u+vF!CEx`{BHH9s2#=c#*Y8mM~OGC#jQTk>*@NL@d*z|&9+jk|9-=9yG(SEcvlPaaFwP?0DgTzjKxD({pb>|J(GKN39a&Gdr+06pM8<;S8@ zHB8h^m6C|p7@oPZTo1#f^ZW-eI@dFGsz*)J~&AjQaw@fTcA;|8N67MR2f47bZfV0_=6HSmjW6E3Vh zzn++{8CTxg*5f&H(Xkha^?HujR^Kmo+vENP2qjuG-*lzmv9r-c)*)T((>?fOzwbC; z1F1?xGVdwGn~-Oz>ankCS*K9I!yb_kf1inUVy-jM4p*#$98CnH4rB@(rLiReb>!xJ zVKhrr9}UVEV#yt<#9AX!s-;kbp4CJ|HiH*0KY9p_1uss92Rj$P?E!m$gt;s4*?@>J z76^f?4ZZApR>QZQkOhHnG;o%J6%$;RA?ASSLBT*JZ4l3mVO7XQrC<@_K*WS>iWOI4 zls`Ean?~F^98iW6*)R)NvbYM|spVX`ul|C=BzHcB8*9r%-Vp;wno9$8NS&nnmm`@Z zna^?q2#bed1%Jqn_{h;rX$qkmXcfjR!kH2IP`$|UGO&Z_s#^DthcA$lF&7$>4y~Kg zj4#P*6HquHPkWq42q?@I?_}=8HN;4+nw^ukVNXX|krIIh(SiTqf!?f4!%jzZESyV~ zYOz!?m?&mE>AX9gn@MFI@x)X-I+Kh}$HV?K^_gC8T?hf0aw?LYLKjU2XAy_Af`Qn; z$#r}5Dz8&_L>Ar!MSz3&Gm;%4h2x^+SG$%=@>$Pmv&^~h;$>8$I+ciKatWr101>ry zmUWE)7y(8H9fCi=BKDrGHZY76s->9*W<&N!<9_c6G>FO+>y-2cQ?q13$$^_C^A3uz z==51~Mt<+-^NlDrwro)QTWKoNrni z9$iy!aLQ6bdbn#OGvbPMVXMf*D*Fg_>aDrr43ovK@FVtPNa_d}p$Z>q!xi3?$W5RT z_FF#BhG*g9X7b?*y~KKik4lVI#emDC>i zr8h^o6@3v>VbU^4LO+K{qAE;?2#KIjL}2t}Y}Kmxn=gjLJ;Hg}gW1DdwGu=N<&qDV zM`+|5Z=#3UxnrG)+&Eo}S>~56hX?Go0aR3Qke$85%#j_H50&0}qnPYDye|%-mphh{X8mOin`MBe?Q}Ri- z?cWwRJw3AJoxp}~N}KmqKW;7fQ;B@pSEvZ0lJaTv;KzUeza0D@|IPF82Jia&ylem9 zS#!7l!3~{HKmPfK`~UU7{?{PC|KtDue|O@E9eq0=^*yrn(Es>fKl%H=%lZce$G4sZ zz~%P5QxA^S!sE5PhbW4Pf`$=b+1yuGoaxK_dAD4yU9lp%dR2Ji1A#}kdft83-FqaG zbu;(sz=h17x3X`)lH2!1B{YszfUAhWA=}OG!~p?n=BZdL2j54+mZ^}8eJx-3Ki%3h z`dyFnup=l>$e|RiE0l_rXttazRK1ld+j3#uBJc3N@RvJ!N5!IgM)$hkc{a9beRTZ; zlV88q+4c$Kf8lAEk36_}a8Op4bx`~|k()$@3eM<9{B&Nv(@1hO!BgHuf&bDVS6cXh zf9A^IWqIb*<@AqMp%dH{TI#)$lK)GRMWNs}Bxqw__7_LKLh zkRF-$)O!Y^o)92QIuMRS)w)D4lOfp-`UJPi3; z{Hbw&YHTXnJ00tfWXFJL)W`U|)!t5X=IblSgy}GGA~+=x+JZ3#)n8p!fh%)!>w-_S^qI^0E~Ny2l8#h@lOj z4NJu`u*KO%G+9iii(XH>2W9Kfc7hEW>-}vLp$qf|t9k`i_AlPBWf6bkS28v8{u)%E z_l-fMZ8T*^X)r@4%u7uOU6|#}g&c|4*~11^8e&0)W5I~#i zV~#R+04v}aBVh{k1Kh*{*`AKHQK=L3$wmw(fIB~tEy>5ll~ufyv0U%%imh3bJ9RK` z-VfX~iV|bdp(zrY4=pA7r1-;T#DnC0mJR`$=0YAbor*cTyrW&7-iuTF&Q5&Y<~&rc z2?zir5rdGb%Euz20N_BP*m4ClW6>wI2YN?h#ta0a(V@Tdp$DW&|9WMg&Mi6MO4=I0%ih!PkX1H?I zU#|EhUsh!spnwY~laO6>49Z+E8@Ah=Kb#!& zK|u_sJm^?Tm}oLT=1+Bp(*0O0L(>&dfSwt>3bI_hpfgtvqz}AM9R3-x6iWW0SuGPX zw+RXyT)ZI2udqEI%hV=9#eRRjFOY1F|MYV9#QVjupuRwe|Kuf7MMx+ zC!+7X8Q-uzv1w!Ckq5JT-l}`$o`-5RXgySse*LBJ=JhjgKRfx^%j4g_F?jA%V@qAp zoIhF2K#_bFST;MCfXcNbHi?BJl2{NQNkKAdH z$d=>YR7baG8L1K?h!4zyfIvXDBtPiC(C=M<8DIcwF7o7VBSfz8CVR*i;DKCuAr~`E zghou3l|MKDw2@5-=sJHTGFh%PL*`%`bZEc-%p&Sw%m{P^5zgpQ+f%zVwIpu(Q+-ph zUT;dCW=a&~Y7Q39F9`$X!2oUmsXi*>7jc{HJFm@VqBpQ|!Sp%srLO5AYI{$uz)Cta&teelpxztoRZIpC{2z|DZa8ENy7Xi8{1( zE}mz$!awNs3Yw%VY}`3QegWXIuzeyrGZ1ulxsFoHI-}>KS@~Ek zb)-P{MXUxPIwJD5K_^NCzFX#}L>Y!JSp6V>HDD!+F$h65OO z48`IE9Rz6ggH^Df930IKqYg6hta$?w$qbnz4eA6zpEdc&RVu%52Oc&oYhYDhqCCw8 zF3&(@k`%KV{vY?B`ZueN{U840ecxJgi9L_7VN zWVVtjR-&~=vQSNha+&F5F;>VlW)nmwsu6NQw(P4m@sNQA}- z+WusJ@60cy^kh9hQ!D!#^}wuo&m5fKq^VNMc6umT3MNaY9B^u@Z@?Oo4g#bI;dDX)r3k%2NC5k^Jf(@K=$uix0Ei0% zM5=YczP~a;Ld>Yi_X38Ukou-x$ zVz+8SB*|n|o`5b#WJvcDb#*RKFx8J?gZWUa#$Hmn9zqVp8BSlg=MN(4>7}cy5y73Q z5;x)4I*Tp#Mi8gkG-REvQU;jM+2K60JiG`d zFbS(9K)*~Db>M+?i+4?%$4xAU0TwWEREFUafG`FOnxpaj7yyF)sl@@H{pO2XhM7~u zK`T#V`b0^3rVabil&tNUWhX?3-E$U3H72i(JgYZ~u^)!549zc5FZ%SO;f)Urp8r(4 zwUaC;nvbLb{^%BCWA1X><#J_@o!|}EK0!cr`^cJ;NlzK_GZKhv;Wqmd7q)Iq27*w4VuH0Cc^KP_FoL zMR|%}mksC~#zL6^d;v?V)dSSibc>+O%7i4pY{@kq?CkTNgnB(E_@%TR3tbFm1p|R5 z7Zb2QQyz217Cu4%Gl)yKm8`oDb+Y_oOEhB}FV>K4-BAGH2+RxPQ3nK1v&VY#0;eNh ztzj(ir*;Lglh`T&aQuMhl_z6sS9g!>8xNk>V931ew>ns4q_^;Z3qb>STbfAF1VEw6hwy)Y>|cTaA9)deWL zb<4$j9`0JdbI_s(o*KIM`SE{zqzmK+{loV5y}RBWfBYc@f3Al%pSnSw4uOYiBVaxE z0H2xHUrKJ40!2ldAD@oYJXyY+ca5Bl14&4b?3rQ}R119{SU zLj`X-lPOVz#41&RL>4hqu{yo|x+EyGT$XQP0|@NRAh?p37uGJr$8^wH%ewNVaH14S z6a%rZo^*74*XhEve(sW58VGfw%YDAvC0{{wyUrzFd^Ws&)1pG<7CHigrD6;fWyv~j zJuq{nonRI4V{|Qd+2U*VqmW!ZSiI*4hb>h-SP_j;rRDNgM3VmFoyDq;XxY?{5`NmW z2f`gdPP(*#{j;IHLHV+qx%|}__0OcX>4PUmKcQx8+D{6GG1x$QsFH~{fj|69{T(e3 zb}Y7$14LuuNz7ar#0IEltp@n=wI_v4=#x}MpldqxH<5UEq9v5?8Vj9qr6!6Mf2|P; zWV**g%RCmXaSYNBO_)_Cu_#AmaKI<;)wg0kL1Qd<#pBh1(H*Y*42e2n^ZXYD8IZRoAjM7C1$)3na&L*Kwgj?K+Nuoc} zC-(76=AfRV&;exVaJ8Z*zIKiKm7UYxbJ5(wN*?FpGbYha7OTJ}f2Hap2Vm%iw-|7+ zKUnVcmB7O6v4}oXg-L2b+AsthYKN3fa5x%jb;ifMsWHGG@Rv3+Yja~08`=Z5Le4{c z7MNqQWV@-w2YE<5n){Ike=;dXAtYJpe877mXI7!;lhF%h7b4QmaeLw#J3&j@cqvWF z8+T>yB7sG8h#~^10c_V1>2jsgfW)ajx_+q-?@Fsd; zn<*H#lyXqLj>dR0Y@?t`-H)jdW!MQ^({9O;=#e?%#?$7hVX$%{C!aQEKP};wZ6uG; za~9%-J&~;ui;5b`?s+S^X7$*Cw=IU1Kqm@tGxB(*V;8wvDxxCi?^znq=;X25&Yx`1xk7=&B)o3FeK`1Ix5a@kSQGa@x8tvNd56!edo z!9cI?3|J6TVVl#5)Y`v-1|5jTcx$)Kg|S$oM#4PsgbL6Iz+K%Cw`C6vFcLs8qhN0U z5$q6Bj7|g?_RCiRMuTVBgBanHUwQ-jzy=*c>K8P?JU9jG!h=XcC{*W;xTpsJNgNvR zo*oZ(IwHNU_&_}GD%GO7av)WhL9LL!B&AXfzzKaWx`V7qz?DwQBKBwk0N7!NrmCi} zxx(gY1A7!vpnu@L3K;`NnAWu|eo4bBL$M9H_3-kNEri4XvNW4H{84PUy6R5(6-0t26v*H*82!V4yqs{nN$ap8rZVugaZ>)<2RZ8U$(vewXF8NG`;0*|EA~0 z0eM?KPHcHQz@AOJ#x}j+*z#_0^OyN;2kINY$N>IU?;Madzg?s2pB-KQ%*X@JjNJR& z_}{NTtKjdJr-$EpZeQThZ2@@%Sg7~Dy8(ZZk&C`^Z>jE8P=&+h4}KL}y{dS0Kb~lI z21{kHuK&qzIiT3om(I@3na_oJhMaL(%3?Zbgi{JNH>5Xw&(0>wwRobKju+D5Tq2fF z#`B46DPF0G`j|cftX2YL(?6*MY$TCq5#&JvIvcT4O)eZGH{Dq&`>Tc-7_OFliLaiB zBnNxFXZn0+J6y-1)|vA?&Z9#UhrG$&_)Kej!+O_S&se%9N;FmVu6PgTO|U&V_IW3N z#^mc1YPT4tFWHyKjbrV2S<{Kw8)YXkAM+!8CFNBk161!;cws*VL*9XZw&l-Rd1os2 zX75Ld&M`TAzA$O7!=x&?-yNlBw}?)OkShVfwqUW8mU`u{Cwj(bM*`=D1DD@UPlUlY zJ&7JEw&g;TtQnCwVAVR&P6%8RmJ*IkxI=D8gBbz!n5H)&FO^dwb|HtRPL$w*=^#C1 zMLb#hXvp70_;|nXn3kY@o>Sh$M5^dwYJE$V7@^U?!c{whiLOT&^d*aN^e_@=@AJrq ztm$_Pb+xDu8Jeqtw4 z8!wHT`@rx+H4!W_kRBj8@hAA&k{66lM~9iV$kFg^!rT$kcFKGoB43{I9{DV`a^>_F zuZC@JETnS=MKr0xRJP>KmqBuI#)U(o9=ZqojfJO2!l6`g;VT^$F(W3=)My#ckLlYi z$&Lg5^FyH?XRM2)IBV8~F(WD`h;8e1w&|Ztpm7-@jbTqrNB?AYrHVW?Y5j?CX{?z; z_k_~&?mc?W6`d%CnbNcPj|pc4HDC~DVX1nGot&`_G)>+@o(i%d@)PRB)h8pvL_>|~ zbc+v|#?pp?@)fx%XK}&?x!G3|q*DN2cVtErF= zI7(xyJ(!Oo0V4z~LSyD-b$S%Seo!S{p;P{ZG1?d=r9rp*=vb(g>0nC?gajCiiCbJj zjEexLKv=)CGX=?8hJTVGl7WBBX(lRHORdJz-Yi|)_dwbPv?sJ^drjbvKjF65ys&V5 z@jWltIY1Emv2Yt35(i98f|(&zm6AnF0buR(w(@zy}dH@l%)KVE}V2G!}|jCHRprNIZ-UCHL-1?R&23@3bEUq z0kg-UaI{j}ad|PGd3cuJZ~lB_>$kFVx#~*G7 z{G~htu`>1B!fGzSH2vj=u?_1A=MLlDgfe(0HZCP^ItS-eiT>1R+1y*npB6Z?9BNKs zx>?bz)?&3rverlxtEq6l>`Q0lQ~E||kjSSV&B&ugV+miqjY^;K-$lZ%UqkUbwdeiP5K~NTO3yKmW2sF6(h0?RFhKH}SPz z5`{4w5F)kV4mwR(!duDF_H&g88ZZg-n0>bB1p0X7Z65NXcofPW9F22zIuJcKfovtI zU2XXb5n0>+d_wr?qCc9S);TUEiLNGijs#@Ijg3VZdJ=9Y!kxrw_MxR13s|$jLbynJkE?| zXkcPI&SWLHg5g=wXaE1n zcan{|y~l>kci4~yS_fu<%c*!ch3Sk3FQ8`nL1=V75*nP07sMOoW2|30)g$$ogd@GYlKvL@zuu5HQ8+ zjnsvFRBjNBQDrK>u#9Js0xueXfpFvLNE@*X(_|F1p!Xr5HHJnGiYG2dcJmf>;1LZp zs4*fN$WyP6sAI@ZbN!e0TJdApgRdn=ccf5^mk)d|jL@-7Vc5as?MMX>mVvg47 zmf0}(>F7YWKiB4xk0N%7PKn?ktsf{Dm?kD?odp4`X{Oc)=bWzlaWo`gkNXg+8Cy=9 z5Zcren+Wla2IX!x<}S?^J(1244i$)q%h(dNK0Ebj6LBtiPJ3YbFaS2Sj<(PINU9@Z zSgVYHKdcTLv)VvZ6pV=RV99iXmg&c4gh%i)t?qQ0jcCJu>KTLNEg3lW3F{`6&Q(yGea4(x;$=Hmw~?+EhY+fBrzj-{WP!=j5TpWGqRn*dHq;2!IRh( zNa5+{hy53$+3{KputKV%+KJWca$fnV z`r_3L7`EcuC29kZjeDvx&|MwsD;_zN`~LIzj)&vx*SQA!+xz_oU;N>xZ+ni9RNg&5 z``(4Q_bxP^J6hekzrJaI1qitPK<)Nzt@k|Evw-{-Y4wYadtRKp>FMG7UUF=Bab)zd zop$hd{CEHO>3{h5;`NJI3d&X8#f}s4HEY~ozu7e-uhRko>QZ01?5mdix6TlkQaBoyvxCnQ%S} z#S582HQktnGPy=9P{_s#S$fEpleDSUQ@a*_k;q+j+ z;=@{++E_%?h5CH*@$|9q1uN7b2Y@3ssedl+)agrr<=52V%cB;oF_;<>87{63M{}c8 zFCYQ(4hfWG#|HZmHC<_*#Y(Mg-sIqR;*f@^r8d8mXhSiH@9VQWv}X^8?` z)!NB<^(%G%1Y#}#n`ky{Rhw5MVieKa`jddhj3&aZi9#Tp86)JP9dzwZjK*`(a3(lt z-ZhAPi2MX1Poi5-UmpA^5%*_e3*TP58fkqzHz${DbPouCIauI{{S>d%_m&!%PrX!F46{)y0;WMMp*?hU3d-^{4cja-O7S85A8 zmB_xxP7Tx|Y}6U+@Fe;I>2Yu#>JOv`i0K2qv;DpnQpilSLvbOE$+d8=6LhjL3oHTfhoUtc<6x3(jFhsrf(b{}M~NYl7G}UsOOk9@uPnAm zCk686C?-oY29qhWWIt6e zhcHf&cH5WX4G;L9-+?L8A*$Dbl;~4vF6vqQG{UtBzw(*)bz>eD_+v&?P5NiP5*v;b zdjjL~&Qj+O{PueU)|fYa$T9=$=~+s|ZnbdxPKcJU3fM(WaBla1J6VoKfyh}{ix#yI z5{P7nEzqV!L{_W==t1%fO<0!^s2l_)l#i_q91i~$h&wL-sMG{JWO>#&4#an$0CQ>4VN3mXuTOV>i+lOfoE4K_Fh z4(U@<3!SKwDlsA~(UtzGLvzYfP|G1$r7`?;xut)mrVt#l)2AGjn_1Wf$C1g?m-)+IBrH8!sTUzTW3HpOy?gysvj9pj;vVl|n_ z1Ow4&C>-}DQh{6^%@*h8a%v|imym1h-(0&eYkPC$Kza07{_Mx8y}NS9-Yxb0Q1f*( z*%g0Qd(M_GoQSub`{>UvwVydLH(QpBID9ej@b=VmPnCVc)$zXQ#j}UL`fSgh_rBZv zRXFUc%w}V`V7V5=PNt)&zpUE+!SC-mw)4a9p88tprCn!Ue(vnk&!2zt`EyX~6Mqgo zx;^mdHVgdi|A+tjJs)&CloN<|@TPGG9nGW{bc$#Lgj5^89?cT+6V(P|01oRN-7k zuhqhY%~UCEJvAIHlRO)et3uH5JtMP$zvsqsxW_4;%Wqd(*|LcC`ivl*6T9@j7o~RR4`;@|1V9t1H1}DA zQxk_dOCMoW(m){_X38*$|FS_81ql?(a-SRd0*|H;^(K0W+d3(Nq@D=j=~Q%0@s?;n z61VU9=Ma3tVWI5Fl@o-`B}cDn2@qj0Uy;X~fPMK&isF!HS+B?P)zrK!833Ril)J}<7j$J-mfUP61w8u{eJmWJk0AUbW2&uuXQe-AI=PuLJ(-BE-zvo zmUnHOp~Hm+W~PWp#mUxAY!UTUxaG8tZvG@-P0=nUZD2SbKtBoPlhkrI*aiCk2 zZnYupQBeW)KrPlzh_OhW^my(ka=M1z{Vra{^od_kolwMkU12M zdHY$)@!{_8aSToH7SWjLkkOm)fj*gU-vhCS@Wf1;*x++~V& z94h;6_s`%1_~93Ou%ES*n!1Hl&P>G445$lDQPN-)7SJKuqAX_31_cc9OP0D_KjWn6 z$TA)_fHG`gY-kN>P+-iNWnFA(IB=TNwWSh>4b!C`puDV?n`H(7x+HS&;;g*6oltPwhqT}|GA zSWiv?{w6QtcI=juEXU-v-j^Y?M0YE^FX%auZUwU=!vOHAWLAzrE_b=LgJhD_>G8Em?C?V44q zRwAFdxx9kK+1d1^OSPRlA7}pyFYX5XH5v;q>NAjC#D!7Bk{sd4E!+&Fv@~KU#j>NWSO?*k$luf( zM3lhyv39(^vhd--%U@}S5He93(hDz01Jbc*#!;$D`e|}BxtTaOfi#FYDf1dNMxhhJ z`?6pW!ZpB%h*vu&PEwEA8=Rf^8lSbC)K18aAV$DxVxx)3{>+Zb4fMhgWERCaa;K1a zl_@UFw$+}TsJW7?4d?_o(u^FZW$nKpg>sH^EeQ%@BGyhUVJTFw6OEY*FwB?etu>;h zYHV&UR;tBgnNh|3%05@&$rW z6mc_E0wOp-msP5D@LzJ?lz>+wlW3+5r=snV zth^ft_BfsSQiL!x%|ge%ial_@_qAt0hsr#(5X>uitfQ>?>fO5|xZ6-Vsdq+9V^lDnhtDaF8Map4m^gWF}6frlW-F5hGKcv^}SWOqk7(|JMk6u%(+Q<=OUT-^w^h8AMj<$x|B%$BNx%?Ap&J6Be#cR z^SW|iCon5QLu;reDfdN0W-C4-*z}&=UDH1yB_@SD(Idj4*)@=#5Rr6uD|~JhaY+Hi6a_8evd;3KI&0IZi*0D1D^5^_~5m?ihO|!wDy2o7TOw7*% zfGX9Y3sq0&d@WxOxXNdL&V2Mv>djZ`?g?MO1^CT)So`LE6;(v?^`K9&CS3z;`xovoy2Yq@GY1F-?sYSb7YJeg^& zQS@hv)%wC4Sk(Rje?H&L@65jkAKcbxlxOGSwR&WBuITko|K>Np`R#9iyM6msdT2BV z-Ndns&UF4#C0B?{#QY-xf!g~Hd~@L7clFuA{CrN1&KGGpH(#sH))9EUk!sY%CDCa$ zGhGM`G&x9t8`5nA}{=aj0qa{Sj0Bw)YOBWJc(`$+pNi*#oDn|reH-yB?1dBPfWA+*n<*8RnxO% zsfhHHH_v1!KrEEq)6rH+P+1Hz?{mQYO?B$Q>N zgpBBx`%IW4aS{h7=HQY=eJ8!k>}Cv~@ZF0Fe$!L_t){C|V~^V>b+`FTVwT z!ETp}xW9loNL^r#SZWU0J@`_B-sl;w0Pl(XxGoMg zW)sCKCVPd&G!ZR<3us*~Ny{^;@-%Cg`)IHC{B*Q~qafE@*@+KeqxKWAT6iPfk`FKu zM#t>cWuNCLZU)0_^GklR7Opu9AHyQqkIb#YfrpkE&U#2BWd z?Fwb+koZCm+A}Vp&jqs+Jz{BSa3oR?+Jp{rOyo>KKXP`)SBA6b6RXRbQ{DLe2 zJv5$;J5oCz4?OXpE7Vr5`Zxtbm7ItqDGcab#eyF$8)Be--*M&w1Dr?=&@@?GZX#Cf z56pCX&YT|q^33>G7aV{;S^NWe4Ec^Q5p9{0m(+JrlfVgfuKjS7K0y*}G-`55QFaR0 z3Q&ZgTq{5jlJM$WNnTNeC_qjYhj!BFgMH!xL<%Z(yWWYy^vMS9$=rc-PV>f8^b28W z9HJ$#4=)hIGjI*Fhj1w6O>s6=oOTNleHhXD6a8ux!M1pD;A|u_V(vjXh7+kY=mZEA zN)N#&+eByU^j}ZdYQH?XxKQv|)HZz(EqD{17#`C^tuh}twdhw#~W zR=y_-pve|zh*TE%yZf%YrraaxQaDu%=PL1HH90$1?(6NCo*pX}vYnl+Cr%tqr(=MX zWGd3t-FE!=FDH&4nVK4#odwSc#2FbK80c=zP4sjgK6rS~2N(B!7k5t;tBLu!f`Y$~ zKl_kAX&jG-I@&Le4EGkIffHYU#-V2)dFaB?pQfiqQ&E5Cg)@EaXG@cPnNQv;_jiw9 zJbmKh4?g_2|K`N+e>1af)70km{v8iaZ`m-uey#h#Ew1gG+y8J!=O6E!*l_>Urgg`E z_m8xkY5%EG4a^EittOJ;?(X*ECw@74?5DADa(}ft)K%?lndt497#qpu5-ly~jvhJO z)_$QE@eOuU@rz^M?8P%4|J1f2kVu`&wJi|MJU^r%oT6oF0xABkqJdo(Z0BJ$0e|bh#qy zg;S0(hhrp{Pjqy&zy{1@bBVdxLbVdAx>_>7ypcYzJNCm%zSHkzQp2*2*oa`j(e!Ax zFhk6rnm*~@`C#;cwLJsh+jR|L_P;*OUqQZO-GS4+WFp%)4j{sX;A!*yLt+93$xe(G zu+`jyjqr4WBvEcE(n2=Tn*SOkp_1rSGw+_P%Wbdf9V8}eIwqvZ=ld0Danz2nhy%I- zQ3Qe+a8*4QiD_>Z@h3a2_DXb4Z}w*zEFyw2BTu5oL^H`*)*-T6EGus&VVcAxK`-V( zH%_tI5bns8b|-}xi->`gNL6GOX6=r5FI@{*mgq{$=BEA2k~=G!Wb9dZC&KrmpzdU9aavst9nOa7242!rjAuc|?!ihWr;VgFmWaU!sSy8x>lB z1EE}PZIc0zn)N4Og0rl20)hI;qe1!l!bK7iM^&Jmu2bEf);8ynwy8tJKK7H>J#jFv zp9Gdnjmn2TR<5wC9|E6+)AE42!Hxnh3BlxkJqp|DqK|ZIwO>l9fdPyq{vBTk~wAE)?Nxro5B;t5loQkyg+lZ5X}DX)VJ4?SInDTG(R)6gVMwS^Yxi zlOb7lQZ>;`x}^r4mG|LAvy=x;6wOg$3PYn2N4P~7ac80(AQH|6c@Qap4#Ym@1*QQi z!N2x{ROKeH&_&X4`o&%0&Fh9czd@}OmkbBapen*Q77dkZ?-+=A+2WhAXohweUAZMF zz^7$DjYf1ZTsl8>0^~OqWYE*&!E+ZKd(TaLdt`VID3He38&iN!xK#*c5%PqrKUEsI zz_5G(S3dY_X%o2YB*#Qr!5@?jG;>^ep#IGN^)C| zm2&bW7gB{Q^hje0beOmLwCHNl&>}h^cHtmQjTzA))IRfLoAc11@5DstoHKgy*vMa6 zmigKT$wOWkCd$o>%+4;{R0<*6czzseleIWt*=NE%Val{R5l0C#j{=|?_z2ZOe%~J3eD|!RP=|m}zuB10^ z+W6RGJ3id=-mSOZdhfmWOgksQE1NfOy!AGA+n5-`RSd1yz9>Pm!1RFefyvP#x85mRoOm=INcUz4pqjx85Ru-g5Kv&pkaiUz=^Dm#+N% z_~W79{qDLSe%#Nj=jSr1M10Na)sH^<@MDiZs^D*~Q4B|X_x$M|`nly6W_IK1)hkEG zhw{~2AQpUJ-Tmt~JdiI4l78dO*B*Ls+d~g+TNwA|o1fhI1o*G&?@fO9RK;<6t}v5M z4X5(*1*S-LG?|~q@Nk?$$s<=Ag6F5cem%BomG{NR7Y%HIFa~V0Y3Hva_144gg%?5F zqJ)XV1d~Kz0`~-?5Z10e3Vs?O*O>3@6Crg;Whv38HI`JQ@~DJ-VUn{*k^IsCN1)!r zun8dklzixDZgDY%qoaX^IM7t{;AotJlWH|(N1x1vU!sJya$ylI2?AiXru`6y02O+h zxSh!I^yW?UGGfyqI}tIOU=O_E?*yW$Xd7iSoe&DZ%Jw$bAUY)GSPx=egL*wDQ-#2& zZIMW?V%y_$6Tur*1d>mel7Y07lxIK6xihhzvLN+vz8vlIiiF34ZN+M20sL_S5l6)h z5pk@+Fi@hKZYvR|JW2Ti8)(TWKw663XNK)EMbqSI0wO`&4ho@8*V%Jp-?unq8Qdt_ zrFRmb>A6OvbYyR0)5c2s3FM2#z!=tmY1)$z6GrrwmFVe}dZNB~2h39PC3@))esB+R zWVPlW47B%njsZJnVx9KsE5QtIz$t7ictuLnkv1wAjNabNWO4b1fnOf!h!XunnIW)< z#qG5T3E2N6FOo0Qg{i5iT)#v95N)9GP)i`2n@$!3*~~;VI~J6e5?h?$jn!J*oyz~! zSJRP_t$YlDx@1XaQM^P7lnbU&S4U!ia!h~3+~0}=Xv{+Ix1)LN2ua zT-t_F7(%zv<5ERH2pqtw`5xp=L}LS%I0TNt^id5a!8Uo64HyF_>2$!0Kt0lf=-s?k z*d6Z#%Z6TgCi1|Vk)P!={QOBXPSjKEgjzYpz6T>mH3TC>fl>gAuz|$b11h!Vf;u9( z)VZnNi;e?8J)j2WiXn{zPMse6qILQpxZ&L7H=Xio%*(etT7+0&+rEc-gW#wPsM8Tc znLC`*72W}^1v;2d_gqmZGcPb70TdKMpAhoIK9MK!sOfnQdz4}B^l$yyL^w{LM_!MI z@L>s#=o8nU1*uw5A*gSmi9zjfEUFE+km-p z#RpfG7SJz$;-O3s?IT0vpo`zSU~HDOCkx+y7Td6{zx_)9V!^x@N$_7oz#Ke~ggB86 z%*J#p*Ng4uR|Ok2f`}rJbqx9!z~7yB-qF?9GUFR}2dAAOXQmKM7h@|{t@!P4f4gbp zhT|uG8Jip`)e7L1j*hk&&*a>E+2xzK@4kD%g7dX}BkF%->z3dA<~KWcJnV5##!}(k zyPxCFmX`CJ;`KWf{1u9+x88aE_Sxvu^;4*lhY=Tj|b8$oY(Pdixc)mL6< zWaIEzC?t37diIuEZlbZ{$NeAvFaPsL|L*_3{~!Ka+nu*gY`EY1$TrvZ&BuQG|2y&}&{R^^JBhTr|lGfy$@ zlRF;^hP{(hWB1;BFMonoXWWyaxPQlvhxyaxrd-bwr8Nau;IF5z{h>#;?|%NdVlhL{ zZEY8T!l%z3+p*)J?c28j{_6EC@;Q3^=V;hlswUgJ&w>Bmc4j)=`=~4T{Ai2x|ncVs&cJdve%+GLY((d;6RR ziL@AM_rxLJ(+|tV-*qnS-@^t zVhGHeL}2Z~;PH-Na=;buOyuR>2CF5yXqb1zC}aF0qHJjfA8#7EiI5eDO;4dVAY#`| z+@=5{^O`n?3Hvw^MoQuFh%%?YIXYJ=i*v7A|J$5qrWuc!Q*KrDL zJk;!GrxcI~+-=@_Pl{(~d(Xdy=%1lg?`Eu~2C~1~eKeSHg)*1lo`ZNnTum6PiKvhZ zl}IErCQ-$6gqTA_wKo7F!*DR|2&N=0PR9mj=i&?C4=jwt2~V2B$wov#PrS!m;9Iy) zoMuRY31e-l=6XFyt|dLtHQN(m`5dZUvcP{b78FVk(uwZu_g(1mU9|4A!9B1WY(;*} zb81y*PvVgWlRF-&1%@%-$?yedtW_6#EMml^1qxX$SH|eC@Px*!EC({FP)1%m$3R#W zS%(RZ1zUT4ZC&o8=n?>`D_(XVz$Ip49h5ap4GBzyFXC);qDR>P>d~Il!M+)DH!CSk zS3%Tnehu06iq5FL25oP0Rw6|W2QGTjiA*`o(8#J>jd;_EQdMRL4=@AeDyd*D7O=f? zrHRlWxlr#=L|IyCsdDXv65*doNmQMUfR^A24U$C3Tl7Fo!4g14pk5tXWnw2zH0b$? zn4$(|-=oA7IMlS$PNu9Jz^vg7XFxulco+L&l8h@$_vU4UMN=oxTP!<@ks!%RU0xK2 zZQ%B3XEbouXI=#Fd}mj5?ds8k@;(mm#MMv^(=>~n3x6UOU;%w%w^%jEZ(1DBoh~|P zNxT48nMmi<ARx)PR}cMH8ZduIlTb5MuGC`e~+OL|mpEmv12=Obwcru^~nx zseKRZ(ILOEiV^Bgh{=)+kT5-PltLLaiB-S=huA~t7z>`9ik$N$I!T23T!rQ#*u$J4 z=EY<&l3dA&`@j`MHYFU+ZSdPk<67XJ8^*jIUg^ z0w~tqEo*y~I>HpJ1Gq_NV{Z5Kz)<&t4{f{s)?4dS<8`0wk*%9=x%HN|_6zg#Md;M& zV>jM-!?)jk#VKz8I1uNZ_uhW*y?1ZE`R1R0{-Itk&dz3v)kN=LJBL2~@a^hIe|3DY ztK%Xg!cSv1TdW6j`IrU%pqC!o@xtH#`w#!^zgbE@{OQi5Z#r4ZCklytMQ+7wG@`=o zTsf79&CEE4$A|8@mnq)k_4?|m2;lF=>#uh@MzrS_UU=??8?HZc^p{Gberdk??KfY5 zT!Fds^M(1j#pE@A8T=hPee~|T?)3Plsw-#t5@c(mTgN8@gNwkDqRHGHm@o_pq|n{J%(08gv++49j7zx?jH z>kfYP@mw)oF8a_lrozw|NhUWj9y;rcwuCbS)O)x*o*qaKjt0;7_I&GkZbxk83VtW{ zzA@1LdDBOJ{|SWE5f$ymX%WVTr&C%GaIWSi7EMRnv=h!^I!LmqEA}wQbiv_E$~RyM zO+=4s4e&Pz>?8VVfKs9*r^w9`b$KZd=L&$EjU@Avft0+Qg%Rxm%0_Z;91LqGa3WGQ z57F~yJil-?Qvrk2U?%GUG0oKpdxvswI-#CWT&ss*)fz6AlkfR5immYi$t8kCL9sFD zy4dBC3X_lsoT6SG3!O7p2+wmmv6msNbN>m%5KTfLw=y+?ZK^npW!ev2n+S3FvL{vY z_nY@9gNcbwl%t3X<_S<16miA|BH3{^9MQhUY)rskzfZpHp_)Tgs%e$1{LaUa7ozDm z54+98I!S5tj^YW6dSkUe)kiaZpaF0VH#!(9A)nDLkc;vc@Gjvj-aFvC(B+mwe9(U~ zk{u?73a|*s^>|tMnT-_=enp*>-~VZ?A`kpx5LCwYtC>I$eaz5KSa7Wojpn`XqrHpXI zI&~>=@#$l7A%ezMEHjd`%uef1lws^?;e`}TN|UG_*Z#N2tdiibyAb&#dyjIR)i(9A8SO9056NlCc=Oz4HbpUt$vH& zjMiEcCBm%;(10YmwN5nGDdbI)2GSAoG$PvGw!GL^8av7kHVEH9&=*q602)-l1D^RK3#q>|hhII(*5Ys1yFkiiNpeF)G z&y0U544aI?91%G1%Mvxek|(^!v1DaW2_^}E_ytoStl_+4!Lt~lVPN5FAo(`i`pEIr(x7vek$WhX|bFft}hOaZy`xNXeb(rWPfdPez6(!W|0!0BT=-{psOf z4jnso1WFg<8ME>SYKbK%IdZc^?D=v&9r^R0UtF>BzCZr)k9Xa5=k?eB{?;3BtWONj zH%dDmdFZaY@0xH7%i{}knU;%ZZ@KyA&p!JYXr(KEfB3`Qi~{}&2EFX8)xwS0ToGj3N`8!R!)#$|ZlLg0oxT?_wb6`Qsn&K5*!J zZ^*HJTL&dS=Vf!LhC#k3RgTdyvvyx8Hsny#fB{IgtwJ^VGRq zyy17j#(nqQ8;u5x&Fz7*VzYfMF39O0f^ z!Ns0XX2{fIhr5UNO%rq0td6c;72doq@bG5u?nlQCztcIj{G0#&DoL$qTt-dE?o*^u zxedd-C$j0Rr6jp8-ldhNc`Z)!{U?&?8WPf(n(>r&eH$n{?JboA?U|3!(Lnu(Ut$zd zj$9+)X}N_r^-Vf=#k!b?W?1b|H>jnx4ZefZ@h9~*`*B8OuDDPMY3p4j%pJr@ZvYHE zL_UIu(pF=Omc|o)2_5uijcX1qT)xoY`OhPX7)*K4FE3dmbO0^farxdvvLG?@R}ze+ z%i&sGV$o#yBHHmKdI1uIdZHO(9}g~k9K{hHkhhzoh;lGfocUJ>0>q<%4De(b6Qst( zen1;Na#Z!oFA^ka$&GIEeCsJvAZba_6?3ozgi0_$ro?{KiA7FD+B)55JKbkGTvwoP z+LO*{purbPKE5Nm{(;(zTnvIkbb!IZt*V&>Lt}U&0fX`N!Wl!<&4V2y!CrS<-ac*l z13Uvm3xr)Z9#(u7y@N*Cbvw%rdqY%xT>_v}u|KTWh&k#CCei2|S zCr{Xr#xMp73pAq82kb?MLq>fxAj{_DMfp^O9wx3bM^nh32FiaE)lKM>dw>>);}^zs zwZO+4J>m3_crtZZcBEVl`!l(LP`=00((nBR zPC)$p7Rqi+6ro8CRmAsWCQ zW`?6-6)=wsA)Nxo25zRbpvLI;F28C%Vm=~5Z`K~{Rx~Bg;$05t6rX6EG8$njRz_=B zpyq&yu-rtb{8+^4AazTg5R7GuPQseSp+!VOxk=O*Hc}<#(!cft;wKc)Pooyf9r`l1 za;3ht0EJp(K@=)*2zu7faA8Q;KV}KH5|?aMt}`}hzvs^&Auv`&sZ!6bUbD(vpp*w! zFU_ZBXUmU0_UMf_-0<0+_ahh2Cfi${+_ud^X67-7yC$bb6#TW?z@Ogp$I(|_dFh55 zu7CG~cdNAmZGcwe<0BmU^7D^p^GU#8*TH?a-*U?vZ@kJ`AkKU~`Q*;W?cnc@JMS18 z=`;KwE&*yc+;GEl&piuFoST#Hk26`Q(U9kMUw!pe;OSRieHjRQQ>EhSHERKXp^!`y z)OGLOcSje%Ujeu&Yn(mp(zAfSeb-%g-NlwO^YT6ydEyEo7b?+-=^?=1`PSo+gy-2^ z&urSXp|$NC*lxl(=nGG8e{d_{uUO55LQX_?+pV|$@WbAjh{NR{U%O^C;BRie5;x#a zrP|2&V1w;gEHKxI*Tasp`}YF=_U-!?9_Hra(R?;ric0u0ld9JJg_?uPGgt6|{6I@6 z(bP^0HCuoG*Uoo$1s>fN+PWcf{~9bLy8iyL{cm-R{qts!Yi;URT#HPef2ptfVRSoW**Soc{Cfd2?eaGr|7oB$$zFZ3Nj7^HdJ{#-8+sAtpivgB?sp2fAIdn4$Y2;x*eA z_{diPUgx{qXS&?W>lNlnt^gfoG!<#poT@WYEDOOcBkJ~?xg`R-7tELJlWp^U83>Fu zChuCiK)MZN)5U61&Yer7%c*z)7%GT|Q7|%sJ}FWR+CwTB4h9ZWiSDbtk%D5=H3U zW4-R9oQ15|sT(9tEKE-UMgtd=`K3eyvy3X{i;fst%wS$#xdNZo6zs%)6^>>~CY8vK z!wh>YrOeJI0Ic91d`!>M*r8=c@{JcG>(&k*`_O*K5`wCL4)sq6p$+-v+qGKcz_SEg z^F}~_Qr=`FW}g{E%N$Y$;DlfVV?~fnG1KD@jRgC~gJ(Kte&~|t|9|l(<%KVWii=LV zTtA*3|I!g|mAcK`)&@W!Z9uYK9_!M0WCax9TDsssZn!-rB(9N`=Lz&^6EQpN+3+Ku z077(@U?uvyWGqv&HASn-%V`itISbncIw$fIL|eUI5Dv8&aZ^(W7J?^^22KIWsrSG- z{XX)aL^|yXUsj`%lG5Z7eS`%z4i};vEPz znjH6dn0GWSmC8?BXLWP$+UO{yb;s=*D#ikGfR6>qL|87UGxmw>;@ z{9Hn4KHUWVAU62(zCYX*X*pdR=!p#UtXsWmS@1VMUt9|Q-uv*qdZV=Gqjzq-?bcJL zkIi4I&drxC@Hf{eR7ZOUemZo=ZMW{&@kp&v;zY08ao>IS+QHwQciu5#z@Ld8+3IZl zjyvvn>ggx)h2*76RbX7Bk&rxMFdUF;|wV|3Lj_p3X*NB@R*!4Ro5 zM2oQ*@TXS9xL8!F>LKLXs|bs5BHY39M2wbZG`6DFQsNL8D^-{xtz+Jrpdo8RNz`pF z^0MDLM0^8#+3^$hPn5I%v=gqqxCA5DXCT~!(IG(FXz-kUMud7zmu%z3v;-%BRmeL8 z9Q@rC@1jGF_IZwl(sENHT#@Xo9)1lGhpn4xnrLZ&`jw>Nmx$qrv;bgSu@20pTuYW~ zI5lN(*d6b=8a`f@GUWw<&&@@M@bo_(JdXsZEmao)1{95C5CtKWK?VHHEIu$xBm$CK z3vYHJQxXSt+l(QQ-y8oty{62G(1pvd6fy7){f-1qYemAKjL1MB zFp?89Vgue9wk*gVW(RgejI@`m?3RyW8OS0%P`!B)-H5_#u7f}*7jsw%(8)dQ;i$qU z{k6!x980AE^B5;30VafeB+{AHN|*=Xfp`$3DoBZz?4+0jCnXCGUnbWRD0aJlZgU=J zoj!1C?6X*Q2yVeTEmM1sk9^$bJVca)878G>!@QWCfhocR=BNA3p$gnJ9GU`Wf} zGXN0;5k8z)mJEi&(iR&m>}(=j*e*A0gV8CvkkVANjj>Rc>|eac4tzEcCib_fw6 z8N3EXC^DOt_e99;M4)q~Okj1z#vI{xj7Rm0kU5KhR;$S^N^pf*aY@~<#Cs)O)-qmi z?rn{Lbde8;d|`hroP6r>#I`N<8L58lSqFiro4_ZB2q`!h4C|oPTEOruEeQxqz+YMW zzcin00)O+fiK=gA^8;&dxc>KVzxvWo2flmsk%w=-`R1kIuQ8jRtLK-3KYht_G8KMg z$HTYYdduio&s-&Gfxr2=@@yrM9`3t;#eFy4bmMEUzw*TwpR8Yh{|z@>zwFB2>|8uw zEo3T$zv(@Ut&IK63Qu$De%cw%cy8z@JVz zFirYT&CXqA<*)TDxUf=|cR|N<BUz`n=7Q~F`1(@>W$~dEN_Jd&F!AnpU?nh*z^y*{olFXk$28}79R)3FtF{>z!^#u z`^`=k(E$IlVriusOcevUaw1nw<|{&E3jDqQ$}Fj*cZS)+DXxdBUM(_1Vww6~VDqjb zkY!T?B|HTZ0BXK9Om>K8$0kGP&y0U*fdM7F+pOALAq@y@w-|5^yW^dt0A@N9>m;8} zhA&bdTK7j;L<8L*#1VGX8GXsVrW*lqc2X5g(gvv#G_29txb|f?GU-1V=PgSJpNTLd zvI$(lQl%Qnl+(3(ESB>IQ}QXuzd9npw#NWvXfiyauR1|f=4QN8{DND?L+4N#N+Agn zib=@X4|U=pw7vM+g^(+ES1m#wob!0jRC443>2o_LbQ~`FdL3fUW`4uJ-PF- zT5uGl%6_x5t{7`B5V!;q zu*_&GB3J#Q*^$Xe3nx+&%)~o&wZo!H)rT+@i_i>DV;cd=_XOo;h)5`x4P>+FV$>07 zp9ptP#pCHxvRaqfaUz{F3Z{%jqF`ANor@sM0slZWpGJ|$8IdYK*C6!G^g*%sHm3uC z&6XkG~(hA z!2&~~=S5Z*2&=Ggq!MT&^4t@V4fhY7{#f_u^zAXxA}oy&Ny%hl@Ds=bPeEeH?JCGX z||a(ae;-52F@k&u8DZDH;`(Z{;|ceuSYtW_NV&JO@4F1@m-r)?jkhv3o{G> zw6YtyMI4f+P-}9@9v+Z0&cdLKvh1CIxFHS9`!eOe3xhn4psc255DHRi+7Ic@N%K$_ z=41lsd4x}WWi6~iRM_YdwPNo`y|uoU8L|&JRyxSUs$3|w;Pv~_r2@H%^tb! z8nSxeknZXA93SzYAM~H04R$^pyf_r@9E-J%Mda<6xU$3y#oQ}Tt}Y`o*pfpx1^-uuTtFvLe6f3R==x0^Su*CF2j;N2}-H%~f7 zs+HVSJnKpp8?#mZ+_Gg8EN$AnVSGaFIILBP)l|zRU&!_FBM)(C^{SQMe)HAAAND=+ z$V0Ih)2w~^*+&mYyuNp+Jy{3^qBGCG@a(hC?#z`Db@k%K(<@i4V(67j z{J^(+KKkILS6=}9MUvi!cRcvm<2#C_^lUEnmp5K{_`$8=!3(13`NH5}FM#{lvBUIV zuZ0Swh&z=h-3Xkmhs#ADvc#&brYK}l*Tf;$hcCp|td4*7&X`{! zn_QhJd&mg$vr(*(9E4pF5D0PJcn{H7(=^6Yt%VB}xn~-?1^&`9Uvj(RJ;C$@+aNH! z&l*VLzg)f$cOZ_LOnrj#EMPAC;*X?tLh-T&53#>emD|W9o{*7kC6LvCj0rj<`)I6& zj*otNYV3=Pj(zs8n-GN<+MaaS18-KuTN?TZDTIBZz5OhUNL5T0mI#d21sp4JLtv6> zJ?KlxZT(0<6+~9D8eEOwghAP$HyoT?Xq=A(HlhbiHpHd!oJe2@&7b zSoJNGGqLVY_gSRCJPF4fl6&(P@gD{RVTd5M>HY7L%p4}@Fl$tR4OmeRYa@#j zdT?5lfZwWRJ*_c92m_$(4auktnEO?g5(zE&=8pkBuiS9^dgsw0} zs#|y?t)>f8NQ|hYx)2VfPBk|U&&O~8D-v~?d2v?saYYIe(YG*y8NzGd?ol z{dv$Q4}zQ={S?U%(*Y2`sinHGU6dDs8Co(lV{w#VRIGRa4fZw`VFSbz^$y)b905GB zfk>I4?u6*dkgSARJ0akmkqqUye5V^#aw5)4Dnce~YdVpZ?xX3Vyik)&O#O-tz#HzM z-ikR9qairKBoL7#025&_%kfZKEH@L*xU!{y+uZds5~P_UoNo^WQW-y_c&V<+%wj8@hrv4=Uid0g%~fKTRyq0ZN5Y9#4;dU(8d zVrsb7$mPoJQq5bf1_@0_saWx5YVs0tN;OPcmUEW7@+&3vT*V)l86D}Hoh!=CZ3cgX ziLEzc%w}EjHLEl4yf#<#le3u-mfz=DkQG`+p5##j%_VTtEna4MH^L-vA+9i!&4M#B zbMw{NxvX5^s|M>edAJpT0tpat560K6%O3c4zEP}Hv%#PzkqooH)+m(%o47t-;;knUB zRLg!rOM?H3<#LuonRtlPVX0V5u|c<$LNedeUUdw{a?^9Og>pWgOChV`>}+y=J`X?U z1HOgEti0#1QkAfoEV^rT*^g=%l(FKea4F z{#a%V6RMO0CG$~ZriN8;x`u`PqID5!vL$!1CdP^V;E#A5o~!HeecscNtfM|likT!_ z;E9}$X;FKSS=dAL20hS;_6A{x9HO)%&^$~f@65tj1kDWy98S|-M z3pqekw#P?4hPq}Bv#mRk51G`eg}@#_E8Sj}aDVMt^DktNlT1zTVkdW7L)&>^IDc|M zDSs2u32qA!9LNQvLgWLtP0g-B45|@z$ba4yS$GpFIRd;+<|2#bE6I92R;tD-wM4BU z5Ad0lj%%@sGzhAoFH8j-8A=bwa>TI|A;>O9#D$hsI~YkQGeq8*2wx!W{;R1-i&-YU z{34Z!ki0$(YWjc)f)1qz6#QwZg2=d-H6fMUMyCu+ID;W9Mn7|jiKCUNaEsWJt_jPV z>)nHao?ef<9CcLQwhCT6PBNfdQZ?qKoy#kZr+$j9Sdsnc?YZ*8OZF|o9}wuU|CF)> zd@Re?(B&oLuEcOCJ(MrI3zbBnA}BUna#j{^_)8TXn#BQscI&YSW|#t*8)u-sR1&t8 zHa&&(i5+N%Z0I_WUM&*OPxdO_QX;>Sm}lahhouFBs06dmeO$Gj5FH7DUuHTrv|+XFOFfG00EXoP)v~Y zEI||8A3VQQ4(c{o7`ciZkF*gQ^D?klZUI5{?9?`{xO^lLGN^X}OoX$;m|eB*pPdaC zD{iI()WiL78vp^#Jn?Qs=ZwkM6b8)F9cPV)&Ka9I24iAHV7S>Z5DGcKIXf{A29fB(B5 zyp_s@i6oPu3k=P?@K(;HPuPP=&>MyXI>+#s>}(@E+lb|h$t_zqZ`rmfUy4`F>y(vB z6&MiYbE9n1fWME()G+)T6LnuMbE30KQO`BZKx5Y1-_MW(jUK&dgC^o2v2 zqwki3eWr1!QVy}vs582h?n0$N=FL}2$A6xyNdNQmj1?=D!l7(7TBw$4nNmKIoESA;BFKOS-org!i19sQK_#;glT zPbTbv4FRAce`Xhhz$kQ8sRr;bQsC??PC-8@BmYFU;EBh^qtwPvrtWC%L`JPpG)co ze_1`e`4b-haxOi1r7w!=Yiz zF(>xD8C$v1@#QPzQ~Ie^{Guj9#j+<`oSBKXIl|{K5^?;7+>h>0kJlTLXGu~^-M>q2 zzit(qH%siKW*mex1aAlp31Dm-B68B3WaoO2@}8C&OKHZRc4Jo3X;!O&LYa_tg=@eD zF%av;)V0iBB>9Loa%giN0u5XE52esd0h#>)va69q*J#^V=$xL?6xbnvFY|5M2@why zi$F&_Z#wjAh;h*%Sq6bnQX(i5Gp`7e*CZ)=Ni^ts$R|%JaJpQpG&enyq|9aCcr@pT zX65FtN-cyj+XKbbXe@XZeuyC?4!FveQ>mg0E!*1=11$y3#M+q)X^8S$UiG43-6EoM zwdMyQ+IK3U)L3qGb}mBVhjnxhZlEtFMyDilU;#%N1CwG(u!TjUU4}qvm9`pLRN9f;kWnJ%G}%9^eI%m6gA%toj0*%~*H_hUvJ#Y2EK zSc54hj?f|51;hrfLUj0*OFV7i4)=cVF&qya@QV$_b7L@5u0{NrM7<#u8* zc(P2SEBj_*^2suWrbGk%z&ZG7IuVZ*vJvwn1ezi-SYQicQs~uuLa_~*!zT?0G?aZH z654~GK*^}4Ebq{n#*OK@$pGkiD$+I@JZCN$h^sI`ZDZC&Jme~0vJYVbwNW}svEmW( zr+=-AXvt1XH4uLi$2m8a8%IItmri{8BKWyjA~ykk!kp4Y2mRPiq#lyn!jOY@f(g~l zJt$ZUH3kNw(F&;|C2UXjn?3Z;badGaKx4@n@(&!Mu9*7E3mwiM75_C6!USVA?fjL* zxlB;FT?~#$V=B^$>PG_S9kEE8Cq;q*rVsg#6BEY*XNdyL1-Am3+4~`!VKe5w6Nv>@ z#fixwCFTww(>>Q96Z@8bLWs_(0trU;qfOvX2}v?KT_G;aBat63l;vw2z)%cBQMe^x zjEyofUlEl-%ubig)gzV??78E^{?N>I*ZuaDS6{4DvaWbfH0S+b&%6KlkN^18(>ue- zz;vuLn3+8M%c1M8yYA3|y+E!tYgWDe&Ks$0XvExCFcs|>4PKm#bc8Y^;ml~i+%+*Q z)>6kLKp0?@XajK2i02E5RjXD&Y|PK+=4MH03%CSLQKZTB&Do>{N(fD|W-oW|jW=I`y}Z1GNx`2Wp+d#C2xSu0>7LZ1k5u~3#q$ngIy_YC>m7~nU{c2T|%02M0{DE0J{>F1uQ#+`_? zQi~-Dv58m-7=(Ogkzr)KR`O*dj(pM~sKS(Cki~p1=SgQ4UM3*S%X=Gw{KCng|8&3S ze4o43efW#$y8BD+Ua8`26NgO7TzCTwi)^)Liz@Y`H}ciAA1xXEZxZ z`0aK}nj_AWsydxNm^Ap1OOa|79OfqtHKlxu7!Kd$EM)6R$U~VV(23A_ri|ew%$I60Y#OkivK-EJ z3Ji@sXi?fk;tS^1EVelp>tX}RkWH@U;7aXIL4o!?L<|!any)r2OGF#s4iaO-nlI;4 zDOqB?Mn6~rQ*PSXL``YJkPJsbi^*k6)5yo3vVT1(V?=U-CuxptYE*LxYX(Uo(r9*s z{DrgUDv4s%M`X6nU6$a1plX>MxuDvJPRB;Bh~%!rzy@sq(Lem-KB({V=iMx#N6J%h zL(_f;DU-dhAq>Ks=rNeD11OEfz=2$4Ge$5w8>a4O7}5hdo7{jwKv&olBxhpAQI7-vtSYp;xO2Zs#qY7 zQ5L!|^O6VC5UE}`MrEP&LYYDvIK-&nABYJ{oUVrq=995#&k%H8GwaHj6C7fV&R7R_ z!qADrgk824^_fd8@ok%fk8IX&ZeHmyKZDmnUDpm|%MyaZFu>gKMp(pz)F554PQnMZ z3h*wF9v+XzCu8YM$xFRUkuc;tj?f(83kcla8%$1_J1=z`GZR=ZA4L@90t>J-HteS? zOV}aJ>}G5y=8oL#lQnVb3Zqr(mWo0+q%ppa^J3)86w5cu74m*&?Wf0$B08$IEAApk z>DSn=_C->jO`A8~dh^Zq-1DbU*p(>wV)?-C7oU?G|GV4j zvzaOHus1?XNDTYWyAvasQX~*@O}j>uxxoB`$k|m*&cIbGceQTCZc?`MJ4DG8s;$$h()p zANw!OXD?l<(T|*!k;hl*aIP4v_OuuKyBf3db=^`f$kt*?eem zk2jPW8}Ro|N87!LuI%7XsY5SSQjTOX87{<`i94BbCUSCvPAoqe&->EZa4wg5=hfJQ z+k-RCP&N_F%ImAjReAo25rt~OQiZ~}pFk>^MjSyN>y{vIP++d$OJ_XVo}Cy5E`!@r z9y4W~d*F%fiS1jf;jvmJs2AmFPgm7Sfa$PDg8;wuKpvG)P?KgNAKR;s!8cU1nr@d8 z{)LrtE;el6-!k#Nhyt7nG zOvmIEZ1%=YL|vix6j@ZLMu&q}T(Bi;z&VG+O^m+49&+ncc4Qgw2NAyQxzHl?G!ttF z_aJ??DO-sb{N_t8bz?Pxcy3}Wc#&O=Qe|^KpFb+N`r1iEB$m51x2;hYR>G@A3xH2{pAd)p}0BAA7#v`}Nwj zYuI@F@kc`u&-{D|oR><6-+t$f2ku`hr>t7>{=09}35P&<#cFc*?p-U))1Ys>@#;%2 zzp$|Kcc}`t>mTUYwrz`^_0dP~mr9vS^OdrD>WNJoUVr12pAH{Gzk-u_l58_7;$ z$@mxMffqp5%C6E>q1s`GylXUKg-SA4Rzd~g2AZubKrZ}_47;pb;iSIg7;43?$dV$idKge%s>&---SW2o zqrf|56&(@uOqIS6vgltvFqrDsU~4C1S|T(=$2NOr&AmYXgi9p?-Ml9-`(G2vn5Mo{ zT_cH_jgnE*^6=LpSFD4S!3Gg;B6PuhShA=FWVwd}Tw@22TK?yo- zJPPB(6=5!#8zmyJQ-H!;tkiQRwqixuC3gg>baVrQCVzLk&N}3+t*0y_<}CWG*5yMK zSZ63Rk|_m4>0tmRfUj(B8lxFlt<&`joOHU5b-K^Ud#7i>e`h;fARBpPFPa_0P;f{> z#_Vj^`Y82MLPN+G^tr4-7-h(t2(8it>Env=Vme+-Asmn3-Q|~L#=>LHWU^3A*Ud-j zl&bZlE0s@|QkqS%OFTJ}8AjC19S`J0c9N}81nm(Qa-e)fMAa*w=eM3fw1^~xE|?2F zFfV7copU*nKkdz?qphL{^R)vAU7%Uj3xtsYafp@uUU|O;!lZ#UD8wn)x836T)vTa< zu0g0{G38WjcBNDufYhpf3<#Go9qB*O-TnVF^N%M3F+hQ{B(p#D@pY636` zCy}n#3v1f4t#_8%~}&x@q&qciw$#ZoV=&(tYP$cRv2aqw=6eB@Xa<{)Ju9 zbTC_p?%DI+4cA})?DJ25_x)E7Zrgg(%{QGrcXEEdx_|$7zx&;FZ@=^Ap~L%MdFAC7 zUwj^vrr__o>#p0laotBBeelvtyKlVl#tj?Rm*we%BIt1I)=h7``6{Qp@WS&n`|-#9 zoYiQQo_l^5e?IcaL!W&5(bjF7Z@THmMetV}9Ur*ihU>R%+4RE?d*6NcEjs-8<2~#z zM*XYqz2~~${&wx!)y(3}w_d;P_S^pW$3H}}fn>pjf8|RvOy8U638e>{>J7C4FoysX zMKcZGTq8*8wN|;5z(B>rdlQ>BlzWa>`p?Z}T$fC!Bx6ac2F8_qsX}xzmbYLZ1Xuw^ zWQq=Vtj*^=l{xx$y5)1z^8%S?pDz!@Ho=*V(usqN1z45NfnrcSP^`MEwSeXV>;e7> z@~(In^HL}V_z-^P^fLjy(e^J#F7D}aT)qxyC1WaQ95ep)2Zf?bo^CM+Psm(4;1?d~ z(_#z}5q8+1CHwis$BBnJ1@<#joibL6L#b7>ZS_zo`GLsTGcw2W`+L6df4sSS^m`1R zfHM_s^TvB9tubsSV%fGz*qJOu^O;IrGRypYVzyzvlQy^ThEydGb10YV2~_%nh4E;% zKUDT*vLGxk@TsO6MzbBc={isVDeln>n(<1c_Hx z2(lAX02BhO%T+(fnE6sV(w?)@1$mUy9q(i=CUnP&6)!R&8nI2*HsM+d^;BV!3?&nc zwUaS9YRwu3ASTG4%#;Aj21+L;SRw1zkP)xkOag~&Hyu^t5DXJQz#GVlJ-$?*Hm33? z`*S+`bydPTOG&cB;+0$y0T_VzFInR%V?oPCdkh1CK+GNMwU-e81Y&fxKwv05Q_s^U zIh6hjWw%^;n~i!CSA3Y*%;GXs9SwHWT4BHUbhrCVkLNh1$)Ac^rlV~rxPIk3 zU!b~wFt&0g#)ld|?NOSl`_)K8*8BTFt)SnnLZ8c{}L&$@8SpNyy+ zYRp0)x`74yl6|4f5Hmt(M5}&t3WiPE0OKNg-~!Rj9=YfZvbHVL@}$O`zOfZ6@7ulm z*+MDy-urLecH6Dq(DX~M?!No(yU2n+AN}Em8*ljjz}LkpnI@{>FPo3~0@JHjuYByW zhZBWhrWEl7r*FCSmRDYRsZz=9`S3kDX>C6*&*WaJ)f)oT6#U(B$L#|Ho%8dBY9;sf zo3H)mH^1p0?B=K-HuDHA6pIB`tX%QzuBX^`I7VP&-Mafz=B32(L}1(YEeie`bLB@L zedNwN?;IN&|FiywUOE@O>M^fhL)m?FMl ziGomINe04qEc5_18Vg_!6V29~<(fzEka_X`Y%Q31{pG~g&4vA6MmMiZ|9Mxn?}FMn z!I^Ub0aJ;5A{Vw`AE2rl?ytBmHd15p-tS}kUvU1k+vz{2RSMvYXbJQLy~VN=*kij!vWL$ZW_Y{rx5Qb)k`zzWy{p;#lsQ0K?) zy-&LiJl#EU#ruspYi8<9Y}Lw{FJ4P#Cn{xG<-WG_?>7gghzbJPTsW7}wGSmhs5a!cI7-Buq2ioQ6#}_3VM<=iIp{kD z?sr5w<9ToH%!&9$AobLgKN;TjqQp9l9IfD8F&o_jAl!6FSr^ zn~3<&pbUX7RCItbG7%DB7OJd&F8D*%nuhHbK+)jW3xD2YlaY(q85RZ~$X)RPmB&Z` zfOU2#&=$?go4YA2XbdrVs~?OHSyy~R@wIExUw**p%tRrxCLYw;<-!6kzgS<1+%Gka zS-}QP&cwQs1^Mh7uHuSyV8m?Gj5eHz#gL3~ZqNJ=y;I&qbA%i==$E$&;hZ=O zqwB1f&|%V~KiLOdu&YN2RvDKOt;|hEN5Sq?YAoDO`#`dv)2;SP$$*U0j+n=lDnQ|U zjvN4z&__KGEWsM=D<*5iV$oRed@wVJ_ga#%6Fd+xt;TRdGz3s`2%Qp@m@jdGKY^$VB)8nF-Lz)EFI8H zvO$`pTdY*@UwpbdP??H{sfDbb=@Z=%4y-+Y6JZ88JOZ(n_w3-$99kwAHIYMJyey|< zw?yQos7eo(crgPEg9hXh8tWl;>Mz2FuDC!WHyfP_WIB61mz{-{{Emk&hT`t0pWb=r z9k)kfo(CV?wrkf@=~8&_fvrR7zuGu;HE`@@>`&QhSNQUK+*h{sa5C6ar z-|hRFZK%J$>!Xj}fA-m@9((v9>FUWH>^y(|)J-?t^!B@NusuJYtJezez4f|+zf?NB zV#R%+y~iJa^y#OcgjTLv!6A=tGG9!sTD9`tyYCA1wl>Nk&fT~7Te$7&Zj}qu3!lVX zki%%;4Do?5tuX;}t<)BtlY>AHv=xTauqX?EYc5+xbhSYVx0gd>iu~jiCv$QSv91f!0QMB&@k^g(Sx!#JDeOIWO&*y3 z<)z>!+xz>!wsv;APEEFc2l#V;`!?t;m>Qgpc9v^$k(Yk3#$;gvv4BV>LRY-00E5(5 zl@V{5I6+cxCc`Ef6e}I4n)1k7Ar11o;xaKL>!9@zhd3p)XLDD_hiAvXJTmm5ysOW+ zq}~coZ$KP;`SOX?s4tVBh?guHj+BSOrLkBskjbe0m5NoLBix$HJK2dOQGGf$ohk;C zrSRNbqTGIxSkws0dnDkWVsg-XoRC5S()*Y-R4SD!-ln&KSoIY%C0!EUts9n*QrNut zoF0<-NxYSW1;|4z8S~X?w)K()ibHO(oII*efMRsc0-TAzyAG%Flh&O%{OX291U(R^ zj`%AHNg6aSNrb@5c2k3833XrwmLche0iDNCuI{wRXkUUJ^8Bks@70LuW4a^=auzjh z)6st>5jKnFwL7Q)Iba*aH$=gF&IHAC3cbnuK|JR=U7}ZNK0Q}Y=a-=w4#LJ1j8qpR!eNT4 zXm+IOrh7XfA6&>K?;{YbpurKCE6-?~mka|_h~xaSJr!-smF1RRP4M*3K=GVhens_o z1tx2cO}gK1nh2Aw1o=_On%do-IXrRsIzG)PH&ug5Y@1S5v_lb3OZK3?P6QdHu;JAHVnBd(x#)qUdM81^xyn`#A-SwQJYY&+dAf-(9<&`Rc3B zN~O&Fd}Z1>!k>5l;cnpF`|rKokXN;t2R>G=$mJ;)gMy;WN)X z_1tsMTI3Hp3zgie)vNCN!(GwV)0Mt+0{-?1`0MOi0DpM23IRDIULq=1jU%H4PrR#a zmfV!IZh`){S@)&cg=O+;!I%Bz``Fqw$z3}eQF(S%Y%DsSdiUx0n_J6mN9N?7vrsPK zOpKgQ?%y5%{E_6>PbT+0m-z0P*t_feUpzWI_#IU-=1RUHL6Y)e0IrBO_#IrKXnkn3 zSoSA#Q@Pk!{DJ$EdtT3_C)3&KLQ(J{mJd*f7sm6Ine^a~>7#FIx!&hFJ|P>&<@SK9 z+^8^l^7Y`y+sDtm)j7TJ5)kLRyP|8?%>1}#Wbr*jatlf$oGZD=!TbqVSm3a~xh$cU zHo>Hg(A4Yxxqb1iA{OD%I31N04i3+jY@te77F}jy9i7uZ`aj;%I(4AMu@C&m1}DP2 z1}KPJ!0E&g>s(?Q;X+=rWA0RDkGT0TyAzMRueR!S+y1} znQwkV)rk%Pf4(6K-~sQki;lfO&o0+bU^s-SI1JLpWIu!u5QQVs8p(`U5lqPn zN`IBecQ{40E^m}h1 zCnFu5t`nUud4!wb#aLixxfj)3CLq)M61{YuDmvWpzR7SuVF&;*7CZ+Y&6VU8!O@)D zfJH#Tmk3Wb^&A=Ww{*Erce;)_puj1`WJC>s z2+?66l@^otR{+Yvpl)NE~nG&_}8LWY@;!6mMVjITb3Wqmh z5rL>K7)U10pCWyjD^?14`NiA(~N%1 z!(R(`MX*yzp37Nem_DVYT)UxGmOFT=75Oexr7SOq#-kKWpi1Rg`(Z{5q_?jrHU&As zGX*FNlM-}g4wP?=s~b!Z!SKx3e^Jy z!DV%7!iPK|i%$kqg9t$u5gTFb4G7Lr%5+Z8mnC9?P3cDmg6gwAE$?JpS;Y*Fg*t}9 zlu9{^Nz_LU21lmPM;7k5|csd6pd zn9Wz~a(UNIQ`2Kl?tC1KIOCd7@b||*{lV*<)(3dM`Q{4%*~ybfU2X?xZ}sX`>2!>< z^s=vlzn-4<+itt{*=L`cn=jAL7a4c=?p+H0%9ZT>_pklapZ-XP)`&_v){1-n6zl6q zzw*LtJY)xd*oNX8EL@Wr0Rda0B$Gg~_?RaIbim6jL$avSdoHncbK=p5s;+*keWmWJ z1cx(UewcjgiTwFb@~vN`55F2b@=qLXz%&r*9QhJk#fq>5 zatZNSHE!2C3K|Kt_j}JcKYl5?de!9qcUt_%T7xHgqvwYrEhGLj&RF|YqIE2GX8PnC zf!0q6o46+>A5O=)YA{WthQ#miz<1vL&rBcvbI<6$-od@Whc<^F+&tJPmaGI1?pU|E z&t#z@!tnfw0s6PwlF5I5U$Vy)YdbUkWt;PmbqJzmGAB1s>WzSu^ySI|{v$3y8t!1g z|M6BLHrVm}#JA@rzGqe#6uJ`Hy6*8)1h2; zb~f(I#qid)H5thu?K5LC+1K{W#1pEche>37g&A4aBzXo?w&W(r8N$NCcOb}#4 z7Em?iH&LJGSh_HU`iT5g{>WAtMtX>ju*snO0_)KZ8}tJt!sN&!?1{|Gui?8laOwU#`37pRW7zP5t_0` zEhWsA83oK$IHr%vs63GdqljMWL0!;UN@|BqJ0bQ<;cBdx&WWPBHoR=(YmlXjWeKiw z<;&PjC@CxAT^PB|yp&^_ZgT@cBP7J~l5Gfy6 zh6j%Cdn>x`e%}j^J3MFQp&Jtc^*SK_FK^6ppGDtbEMNgvi{eo;ZD5JX&zV;bjs`D! zlMZ(hm@I{nv4a3d;g$xp1Whs`{a}$O7}Zj<&cu2~g6+g*7^C8G<+_wNjDU&Qb;%xU z+fJsXJbq#AnU1v88`1t?lDX3f@Ca|AgtZ#j$w+MB6}xs~C(y?dHJ}-b1kR!h4sjOD z!!zRID1H@45BSYZ8-OGf0ReWkfUDH~q#yD9GvA#3SZw#`?qEEoYOXQ!H`5_+eNc2a8ub;W)r+My3PGdp_Y7yJa6z=%!5T?6lNnK_S1Z)CY)Foh|wt>60qj$;d0yY*vgfe*I%B?iH$K| zUgCgFG1v7ev<{)XtX#H zFIwF)(+T+m%ff=twQ0&cuZ=p|oj+cf+$P@M-OV==^FC5aJX|Xx8*4 zlCuADJuUkwmaqX7;RuT(F9m#d;&dslt{(oNvC#Qq#XmhW0{puE`s*KhXq!Jg?MaM8 zbKW=Jeg(kvyWd@RuH$4p@9`vtEby1gh7+j(nCyldZut3^gOz%AzLp;w?;9T<0(*7$ zw|jh3^YfK@z4+eyvQRfYGpc~>_rLqyM<2bP&BvyuM;>@!?eBm8`%EtC@(B1_xpIZR zuI2NuKe_I@>lFN@QgUtgjyrB|?>Z0uYiT)q`)#)=_~YmoUwjIC@4WM7DH~(BXw=)@ ze&I6sTXA19IFotfmFhst_aA>~fxleYg=A0%o{M=S1cDN#LREkjVa5xdBJT)X2Km)S z+Y_5M#@Yq$fRb^L~)U`?KrO0q4NMCXK)h zggJQ}afjQzKfE+B@U=0RBU9lP z^=qil)6wT^H(BtCJ~19f?43L~b7)uS%N@bD9wp$_6Gz zJk&b1-~K%@2!1FmON(d^IaF(Y$~JjOW${iD0>U^}I{l;XFB`#p7bd^w_w2;NC26W+ z!GG?b!>J*}TP%AMxd{Nbo(mBN^jB4eI;=z4aypt%xl?J>%6?JSY!c)*I~%JvV(C(P zDp5>0`(mqB&Aj_0>kS0MyYrQDuVYuyYc$u9aMyNOP3gI*Ogx!(31$8I51_ zrn7}-3FMN|a_=x+q~-0cNz^k@`G|vFPWhK2liJ$BGqKz#+*)sDz%OQEgM+?hE#9G;i!9c@Rb!loL5*%@d-xiSWhgxRZhjOrStSY0;^I-eeB~g7n4I zbcnHzh1w%IZ!j|x%=o?X^!1TW`My3z+}i6oHyCVV&$ZKD6VYeB5?lm-vOb5(!7&&U z;EW<~IB>e(cLF$waT9BrPFGrlXba9vDaL&H6Bp&Eh}WzJ;YIn13k<#VUI&gc9Oz^$ zc%JzpAN&LZ0v!?*EaB)PJe~}cK~O|ALI8l3)7ei^h^0ajO)73egE!ILm^C2JeBy=NAOBc^L z7c>dO%zfB6FuHcfyO~AilXqjQR@NrlK~%c9D?rM52>aA`lQMdn^HBTDkC-$7RPT8p ze#w34=I!F3ZQPiy8s_~q7(b;2@zlDJk#U(U1OTPRg_D`sz)++#9=i;41rc;&@=Tc)d?Nl;=K%V=H=O#SjiCkdNch;Ypy4Z1s zJ@?&r@3ecwpP6vQ2j=E0?0NI8*FkTUdS-HZbmOKCH{Em-5D?&a`|Y>?bodb1>%%?o z-+c4Ux8HW_-FM%0>utBb^wJ9g$cm};>({MccmK9+TWJ5g-~A3qclf7+9BRxKUVixn zPPy&2TkpE-&h6W`KDqO;XLjx65Ont9N%{dMGRWGsYaV~%QAW&H7gibRoN+mN^G!F= z!>;F^VP~P3T)+N-2iD!6$;PVvEw#bk1Mj|l%gs0U^elXrHkvh`M4FFj7$mHzsX$mV z4RAWkeJ)cYTJ1U$-?A~jVO`d?>O1 z`N7U+gRuy8YZ$asf6Eu4P3wY>ZSN19y%0GK4Mf^Tg6DAuil}&gqLQ7A9NgVI@}0Kt zGf)4ZT(-MC#|8o&U9Kx)5ksJTV%=1K2cEY>lHXG-UU1JA&2EXs^ z`?jz9o4&5Eg*v}-4F1TkQb*gztry=LKK|a=FK>_j_}cKPzw~u|)7SHD&?l(Kiab!Y zB(IFILpM|a7#a)8^MAoF9&YRX_{i{{mZ>WqMo}U@kS|DcfF$CT#@bJzC`JqB7x;3STB@Ds7{E`KVysyn>NE^h_3j zh_~7^@s=P4J|l3^o=kyqNt#R+f7cnwiN-$pRotfg=^PtoP>rs7gNM1(L*5rl1VG~? z6cRC`6s_Lm5gCyf-SQ`4pNTgGE+tp26F!Nbuu2qas%({rB&0LuMQ=3LAs}IOHX6-I zqCq~eK@Uym{#B9;66=D)rv3jMLNWk!%n5FNwhQ`*F_LvmMHg0`lzQC9rlW)Y)J!1l znheYHi0WTWxLoEt7d1;K3nu~(7WU6Z{{_Gw#MtIOHi;>@lH4Ky{=<@p9UMj3szM;w zfKQgqL03b8^F7|yE`d$r{NxoT&o;Oa5#U;25v&{*F$hPbrDt@X>+NS_>+VlH@?h@c zck?}`Dy0RZVZsumioThcJZ?!n=S}or-`WO~B~MR;+9xA@z*96=D7&#XH4fOu zf{B>X>?qknwz0I~ztp{#xW{QuV&^)}y-sm@audhB7rCgo zNU|hby^hwm9I1;cbn?mhQAXATbtEEc=7Gw-~!02cGIP__&q7b2yj z0az#58xGTUu3bP|T2Akz3ue;K24oA<#A2uo<5pjjY&#L*D#~17kPs10LG!per^8(o zH&QjDMh1wgFiNh{Fh6+8xWvt`&%uzOLG(ybH2fS8hto8dVwAV^Zx^Y=2EjlH7Y*pc zjJtd}Cg)%v7?-6b$XOU4rjgi^B7aI{ir!(tH4_XG*GbcTH(5`#DGzb&CZSYJh$=rH(4%D+-O15J&b{)y`sh*j{QS)Fa#g+__Pna=@yESA7q6b}xN{R~l{YZIdNLJx z^5pT|+W|Et%Gx)Okg{y6$!C zTNU{Vvl0+{O5T2xuP1x2oJy@3_`oyC)Yq#wRaM_x{B+iY0?%(%GzOEf=6%688l!*$)}``5 zU>{SYJSIwGtjfvEX@(MYx+O#?3YbF{VF-vmui_P!354pBdyD(fs@DACQnJ#J;b3Q} z7NC*PWi=~_SXTO%!nmO1ww?dA;C)yW`fv5U92UWd8~rIBmW!nhtPt?>VyqOkS%#4#w2)QFEb(22E-M- zWq2|&G9GF@U`LKZI7F2+4(dSr#Ei_lhnU*3`C%wpKjOaOAH1A7c0~Mn+t%#SBg=)> zJx#)oD?T_CeHu=W=F2|Z7;1tKF!0MO$znAKo}wmCa%>_zfN_)F!MC6|_^nC{lsXh0 zB&D#7i58NM8)aFM*b$RYxSDN#$waVYXMAKnF%GWHL>|Wr-bmJGFVH4*vsjCI^bEei zxn6k+b(V{=tqRatE~L_?w+L}pu`61Rq7WKyy&^z6-(t!ZDpn%)Gg{_C@~>$heNbkU5@Z(4W*@C1jJ$7?RyY3wh(v}Irg5m zX#?p#B<%j|&(J<4eeR3>BA14|*T70TLjB+)*g^2KS4ErY1w=IyQ#?EYXwM!nD%=v4J=%- z-n6iDM3u_FUGPD>w(V+P-6Qa%Hbx{PZ?z5enja}?Uk>n1!nqhcMxt8CSynfd@He23 zHJ6KxrLMn_orSAs)Ti5!<>egps6(v}!mbd33}J!wLe14%_xAs}Bolkj zSF)y2Wvtq4QZqlZ%TZ301!WL6q<(po7|JMnpn4epQY}%Nd{Vi0eJL5L*IG{}oA!_@ z)&fyuDp&F;!l(AXR*IKS>zg*F_r23t809bL;!X9cdeb)ESdK2QyqLUKf?qV2^q^4` z7AQ}=#p-EiAvlyeeZcYb7X||R7m?XtC9?WAzX;hE2+vrLdu|0!9?>>zm~lylfPkWm zK4sMKvB&MY6}onGbfNX81)*APSfajZ(b^8&am;juemD{NXurPy9evjhecKixZM(O{ z_U(x8-xYsnTVnfWp?YiABB?E#qK9@HpC8Tr`d#SEm#zyZo!7r{-u>3w^V{shU;UFe zwE4dJ;&eSSGd+57X6z!rj;@~Vj;2;`VlpD^J{JRxs{>jd>- zNEM0#J?O0e_Gj(~Us~<7M0q-~87Flo2NX3yZ-6-tqNe3475O+@p`s;=dGmXKBAIeF zTS>R2z6{o)G2_=9&iJr1F&oQjfpeGXrsJBdJdfZGb|A$hmdyv2U}?anrS>+#iUhqI zLjJ<(2{Vk!eL%V_u@w+Dug)H+QuA9EOF^5iVg}8qF-3>od?`smeB^ zX%|!n(ZpIf7nB1TNL)!u)$D1H^E9N^eD_P9mR95s8Iz?Fo=~3lWXm2xHXB3`b<_+H zt#lFNB<{$vk*oKb2^Pdb@I)0@EhCoz(-4|OgNZM&Ny^jmdLvP;r_lr3M0WLLYU^BE ziu;!`AMg8{8Smc_IE=|qTP|O!%2)WOFmW>Pb9d zWYM`^Y%O+X3Ed=Uq7xjGI7NJC&z~l_`k#@%G5J*D4EX_G1pU&?FY&(`b!Y+Y7z_1G zM`=(ex^^c9uu)}&T7HgG7|s_>#}4GPT@JhvHzSCmomybnIR1&YVSVQPLn~$ZqCb|J z%+F3N4vq%p`48X*;xBVErm+^x@5y3b&_1u$y5CPT9I@VPsrA;nx>lj;=R{RN#cwvC ziP$~5(N?OI|Cq z9{_?$C}*ap@C^9wo8Z6_JS~=;D#!xSlDMO79KZ^|3`Zg>FRRW*%zJ$1Q;8^_%DDu1 zLGp($$<3XHtR2cJ6h;_XRl{8DG1|sOu``Go0?=4WmPFJ13!1>x6?DpVlLK&TwT+++ z%i%4-qLiIjf|*&@RYHaM0G(2E{*-Ah#e(t;v~C7>F*A)}tO8 z_TKXTbd1>3H}^-c>-?knKNRzWdqG*A`EHsl@O&yS`91X)tA3h_VW2=oyiAjRf}7#1 zc&}F$aGD1YImCV%1C3rt4&}-VBs{dA*cmqbQ}Hs%L+9MDeXa}6*n>!Be8hjtd{MFE zss9$-jziXiM{V-dcZ=pdod3hxLw^|pMwzkTuOe+q*an(ut-2S3ttz^YW?lxe*MlIv zd#!=Bjl$byBq%us2^cy@^RF%m2D8MHAt*SV{kbIsQ>3Z5wlaWPJpvk(PuppD+2aSUF12t;ed<{pojh8Xp{PhG*gyp6ks_Bv+_5bkz)`5*RQpeWLww z$T9TutZm^8yI>&>bB0Md&e-I|*xnuS!+XpAikzV&t6j&MD6yC;Vss z6*%>&|C^74U%iL0;s5qi|EW&`Uw;_>>`-d=Hlcd!*CqCBPaN7Ee{ZjB@7xkSu*;O4 z`r!k{u_Lh`Pq=QJdTBWrbL}^*k&wYJD9x`j3`QrQ595zO%5Z2ZV)!z}g`_@NzWj&r z-XTb{wsuW=_s;BBCyE`H;!khJ<{xANPwR2Va(ZDU>wjK~I3th!caFc7{2_P&m&Wjj zcQ61ngX-X0*aM>sCID{LMl4^E6m)4>D^`QerBozWX1J+0AT<`P3zJZEidm;;g3)PdBeIUFJ;pm#3EAvserLl|Lxi_mS9fwy;PN##}z2? zYhlZC*lIO`+cuZ;t#ZD~Es34A5HUH1ZAHrz0 zu^eEXVPM$omMSv`fv%BY?{H9F4>b9r3;Uxrv`jr)fNiPvVTgFL*%^=6nR$N`S*b+w zKYj%QR{HKp0W*igaK}QAp9Q)cu|Alnngrsg!a?j9fl^v)tumRQp>c2TBAaK&dP7rQYL)UJrjZ1kaNL!@5|^RYhK34CBZs72{Y z%~Ie(&7}me#qbfofq+s~9xL>v~`B&y@#evq-(eV(&Ci9WD$aN!#KZ#2*WhW5EH_PH;qR}L*veKDD< zdcn4}zgUs*!#I*Pp$!ZP9He1RbDd9gg5k*nxHfN9fuFHc={RRu_Z|LH?DhN|Q8$Yh zQbQ6rO;b_9&k}QI7a&N~e64q|M|m#4bjPwTyKqP?C!~@M_AKQB*?)be?bucxlkXA% z3yNkbAtbO9*hM&0twb`}U?k;h)T8y_VD|cFrO_*j+Xm~rJnP4T-hSetFIM#kkYEQe<@9fIFcd+Rlw{}uz zvE+{#Q&<|w4}G`mgzZAjNEULn`b*PJvd$4ka{9ph^c7_Qc2RzZt*SJP0u0m4gI~0D z>)dyKWDnNT=6&OiORkp7(dSO5_W)t1#L3RJ-Z@Ic^0Q7~XmTTdtAuAGF#s>P~WjL}V0NL40Q9h!B zi=j-x9MaAu`KqT;bjS1YSk_mq${n7SLa;h;UpxD4hY0CeJYrVy>~dVee=}gUw~*_7^qR> zD3)Ws4?%w3<}ymy2`yM&PS7x54QHpkI=4+Q30e!0;+IB(eoEWg99@87QE2^zRE$`Ekt}VJ#G}`MG#e$bruMs?&({ZE2Ci9 zF;K{GScQRkU5AeD# zoFu$?e*Mg1eoBaf(~Di^_QhfUP4F74cFBr*FFqec48U&DRmmJ3RLU>G0ALO1!=dzu zBlgHBd*~^hV$`r(v{Y%N=2DfZ*rdtu&Oi0ucqGfUTi?{;Qfsi|pXuZq1QVwK(*;8E{rliD=AX=L=*$n^FAm(# z58f*b-mgCEsg6FbjrA(2PxRI221Fc#NOkZ&jWIs?pg!@m;ht(nrbVJN&GcL>qSU z8W~qJ=UdA8mrJ4Nwa9bxi!HMMnG`A;+!6)sLfR4@Q66%Wv$^Zf)m!=e_Sa3dq<~ z4$r-R#Xo}8ZPGTbiyz$Wx^Qx0_}u)|4WIM=_}GQ<(eqQ|m)tYAW1h#!z+f>lS&PpV z7RRfat6B~zczOO@&;R~CBrM)@0iz{kfY@`f$6&i^GZc_ChHDW)-GbQi3?c!7L-ZG? z%bA}h<1by4wXd79bYHrZNaX_c+6#uAEx5*JE_-G>X2vdSuE(|UN0rX2`JYZ1Cyu7~ z@6~s1XK1vI>*1+M=;{8Qp%d@Jdaa(~&NwgX<m^Z^+z(}DzO*|5|vxi8{{jL@u!|8_j(7#9Fme==oAL7f%>XS| zG5+t%c&OW(ns6rugZg~7ya4UPix^{HM&9yMfu~RjpeRfMu}54Lh9M2~-P&o1D(Tl` z)NxMYC`u!0I^(@KFbY9G%Dj}A1m(qF`VPF>yW@!TuB@0bpFK z=0R<0R!02=j4Y-|N9g{7ynHb1O%B>KNHYPD7*CVfQ0Kl@uq#v-={}p>wBG;4dy4ao z20Gk{UI-c5!_NmiSJ>I>I{(1=yLAcG3~*m6F@r8NS{))E^=SkA(j>^Sat8_k(2Oh^ z!*5f0_kvy-kJUzl-4C5-hP>B%UFX0}e$D&N7s;FN&itTm`_9U{M-LQrev5ELA_S2D z?U8*Is)6O@6u)pOPNx7q1LB6P{CV=1|d zq3{%oom}i@gA>)VK5rLHMS^85x>5)(>kEzfXWFI>mC=XwoWD_#x0n7TU9K$FGv0>g z;diMNF6BIpw6~UU)>HGyWi_S8?lR*|TM{>@lBIYsva`>D@bpSgc*6$<0TZcG5R*lD})$rYXO1qne0%A#2y@ zTQ*5Ol-#&M+q@~gcXw^{kp*iA`q51kMQ{*B5tI4}O$KCHooY&x^LGDLZG8NAzcgylUOL6(s$7-uubF_^hJ3I_(oLd+Xw{L&bs z$}(Jq(IHo-NhU)61@wVeG+;_Td3Apz(CLUzd9~nNRAyCP z+Z{L@S0p~to|xed8uE=t1m)Kov8XZaNd?@R?$6{x*QV2i;B}mv{r*dNg2y)$ zNe{yz;0>m_dxryEc|w`3YbVVA?8#L zX!4ivOfedOt7OX_RBWFe{7VrJPfpE7Wwr5{=m@S=Yb3S2FO~N?Qsru+h13uxNDuhP zrPIZEx`2{NAJxPpLigKhwgk?UF1hdrXf%KMosRV2Q6{ANaZ3_qcG3lB>@n=bvJBWs z%$VZ3>MsJd#VphUdu>AfV1f0Qyf&oEnmC+=pP+C&xl{|$@}zu8Mb-kP7^o@)y*SS= zUW#K|*PcU>Y;7cU!cMH%PSXS)Sz$E}UET27gCdW2AsT_5QzsQ|RfpV*WDr0BK zHfc>{+C}Dx{}YH;0#$wO!Z8R20K%#|`K2+6|Bais%N4|&J*8`BNY2jnA4)gRHe9k6QZhGPs`^T` z0H7*9vdU0Vh@uE4+C+ot$v}EhD|%o>&{lTVYcX|4&(c!*=I8Uhr=}*)%-{WL;rc%! zr}t^c)@vWF)efyqZQG(jJ%xj=g`^5kU9%>+d1Gw<&c!497eCn-e|MX<9bUU8ad3<8 z+fU~1{ouX%xpwP#AT^@IlNeky@6)|$q;NpM3cn*#@T-4tDE`j2vB^seF~(^=c`WbF z6GRo@DB-9welT2auQw$*mxb$_iDsR@GCfA+DpJTAUg>EJNiRAHH$HPc)Kt!a`RV4H zv-b8Ninkf}zAjGQLTOl0=E-f}FURS1YSV_`@xy^9mzwpKl9h0|#*%#D4V2@eknGy( zBx|aeFV{28Mk1KeW+8q}fjBIjmN1U#g4_w=qHQ^0p*nCl>~4E)J%pu<;L2ZAp!t_wS#Pg9z{&iGpt~0k#k%3 z06C<#-y|@ea7MnINeiija8s=Mp$f2~h_Nue*gk7W-~%^kKc0eSfM`0-PNHP4ybv)a ziGXw}nRl2s`dV?80>DdN)~cI8)zgu`PPS1df!>`Q@#zcBWN13(@g!v_8D*uf3j3k& z#$!OU`_moYoVoKI1;fYQKb*pej3Q)zIx571{iK!Z-XD75mjcj7%okixcFAA$wz34*#qJ67^F%5> z{e78Fa?u%&d>HYbCo$rT4orl5w7fHsk1nK30vU}s$p@}WNpo2;X*LMAM%g3tG{O(=g2)s`y?7U8Akc_{Gk6BwArX-kyv+;`QyvSpo+QJ* z6-rW)qi9X7%wMCi`o!c}&vWm(V|qTF# z67uVF(Oe)=2F&w5>AiRmPW5joReEfp{yQ64;zL$D#%5CMPIHby``O38* z+$dg%18Zgt33N*{s3($BFNy2ZQfM$ zsdst=tY{dHOtGN(GNt{MIJAU-oaLH)loGM*jSXpuIg_VGAtsLu-U;d>YA%L|!y)!_ z34E$p3x*)dh53Bhuh<@>&BX8!I3LMO;I?e5$`M8oXDn5M)!L%<+H9N9Hb9TzV?asd zRI5}YX%bMT29%l!!S)kh6@t5>r<@4sL8u%6fw~c5+6r?BFiGTO=?@w}cNEkRzktE0 zF@^nr%mhT4Z%Xvb_f)($7)l0+F5_ruhRe}w3&fNNe3`2kQzyddgd2JGI!reOir+;0 z+GHZ!?MNumber:Length - - Number:Length - - Number:Length - - Number:Dimensionless - - Number:Length + + Number:Length + + + + Number:Dimensionless + + Number:Volume diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml index 64fc151652c48..fca3d4ee408a7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml @@ -16,23 +16,23 @@ - String - + DateTime + String - + String - + String - String - + DateTime + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java index fcf78ecf0dd95..d7dd532952e1c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java @@ -44,7 +44,7 @@ public class ChargeProfileTest { private final Logger logger = LoggerFactory.getLogger(VehicleHandler.class); - private final int PROFILE_CALLBACK_NUMBER = 13; + private static final int PROFILE_CALLBACK_NUMBER = 13; @Nullable ArgumentCaptor channelCaptor; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java index 73389cfd8c5ea..6e6a8917cf52e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java @@ -50,9 +50,9 @@ public class VehicleTests { private final Logger logger = LoggerFactory.getLogger(VehicleHandler.class); - private final int HYBRID_CALL_TIMES = 21; - private final int CONV_CALL_TIMES = 15; - private final int EV_CALL_TIMES = 16; + private static final int HYBRID_CALL_TIMES = 21; + private static final int CONV_CALL_TIMES = 15; + private static final int EV_CALL_TIMES = 16; @Nullable ArgumentCaptor channelCaptor; From 90da4a35c982daa9b80afab9c0bc5866d57d3ec3 Mon Sep 17 00:00:00 2001 From: Bernd Date: Fri, 11 Sep 2020 17:18:12 +0200 Subject: [PATCH 026/176] add service rule Signed-off-by: Bernd (cherry picked from commit 640b9c659c9b549596fec910092b88da87b454c3) Signed-off-by: Bernd --- .../README.md | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 875d57a009cbc..5457137ef91ae 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -539,9 +539,10 @@ You're now able to receive your Vehicle Data in openHAB. Continue the work and c ### Notification -Beginning with a small rule which is quite handy if you aren't the _permanent Driver_ of the Car but you're somehow responsible for the Vehicle of your Kids / Wife / Parents. -As soon as a check control message is raised you'll be notified e.g. via Android App and you can work on a solution. -Here the short rule, just insert your Mail Adress which you are using for openHAB Cloud Connector +A quite handy rule if you aren't the _permanent Driver_ of the Car but you're somehow responsible for it for e.g one of your family Members. +As soon as a check control message occurs a message notification is sent to the Android App. +Below the rule as an example. +just insert your Mail Address which you are using for openHAB Cloud Connector. ``` // App Notification if Check Control Message is active @@ -556,6 +557,27 @@ rule "CheckControl" end ``` +Besides the CheckControl the next upcoming Service can be monitored. +The below rule checks every Monday at 9:00 o'clock if the next Service is required in the next 30 days. +Time enough to schedule a date at your favorite Garage. + +``` +rule "Service" + when + System started or + Time cron "0 0 9 ? * MON *" + then + val DateTime dt = new DateTime(i3ServiceDate.state.toString) + val Number daysToService = (dt.getMillis - now.millis) / 1000 / 60 / 60 / 24 + if(daysToService < 30) { + logInfo("Service Date","Time to schedule Service") + sendNotification("YOUR_OPENHAB_CLOUD_EMAIL", i3ServiceName.state.toString + " Service required in " + daysToService + " days") + } else { + logInfo("Service Date","{} days to {} Service",daysToService,i3ServiceName.state.toString) + } +end +``` + ### OpenstreetMap Widget From e8f87464371b135ff3d39b9c73772917334c5532 Mon Sep 17 00:00:00 2001 From: Bernd Date: Fri, 11 Sep 2020 20:46:00 +0200 Subject: [PATCH 027/176] charge status Signed-off-by: Bernd (cherry picked from commit 2683748a88c682fa0f6541f859839224317d24b4) Signed-off-by: Bernd --- .../README.md | 10 ++++----- .../internal/ConnectedDriveConstants.java | 4 ++-- .../handler/VehicleChannelHandler.java | 2 +- .../internal/handler/VehicleHandler.java | 17 ++++++++++++++- .../internal/utils/Converter.java | 19 ----------------- .../ESH-INF/thing/charge-channel-groups.xml | 1 - .../ESH-INF/thing/charge-channel-types.xml | 4 ---- .../ESH-INF/thing/ev-vehicle-status-group.xml | 21 +++++++++++++++++++ .../resources/ESH-INF/thing/thing-bev.xml | 2 +- .../resources/ESH-INF/thing/thing-bev_rex.xml | 2 +- .../resources/ESH-INF/thing/thing-phev.xml | 2 +- .../thing/vehicle-status-channel-types.xml | 4 ++++ .../internal/util/LocaleTest.java | 14 ------------- 13 files changed, 52 insertions(+), 50 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-vehicle-status-group.xml diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 5457137ef91ae..c5f6c07459448 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -138,9 +138,10 @@ Available for all Vehicles. | Mileage till Next Service | status | service-mileage | Number:Length | Mileage till Upcoming Service | | Next Service Description | status | service-name | String | Description of Upcoming Service | | Check Control | status | check-control | String | Description of actual Check Control message, Ok if none is activated | +| Charging Status | status | charge | String | Only available for PHEV, BEV_REX and BEV | Last Status Update | status | last-update | DateTime | Date and Time of last status updateDescription of actual Check Control message, Ok if none is activated | -See [further details for DateTime](# Last Status Update Timestamp) in case of wrong timestamp values +See [further details for DateTime](#last-status-update-timestamp) in case of wrong timestamp values #### Channel Group _Range Data_ @@ -160,15 +161,14 @@ Hybrid Vehicles have both and in addition *Hybrid Range* | Electric Range Radius | range | range-radius-electric | Number:Length | | X | X | X | | Hybrid Range Radius | range | range-radius-hybrid | Number:Length | | X | X | | -See Description [Range vs. Range Radius](#Range vs. Range Radius) to get more information +See Description [Range vs. Range Radius](#range-vs.-range-radius) to get more information -#### Channel Group _Electric Charging_ +#### Channel Group _Charge Profile_ Valid for Electric and Hybrid Vehicles | Channel Label | Channel Group ID | Channel ID | Type | |------------------------------------|------------------|---------------------|--------| -| Charging Status | charge | status | String | | Air Conditioning at Departure Time | charge | profile-climate | Switch | | Charging Mode for Profile | charge | profile-mode | String | | Charging Window Start Time | charge | window-start | String | @@ -285,7 +285,7 @@ While Range is indicating the possible distance to be driven on roads the range The right picture shows the distance between Kassel and Frankfurt in Germany. While the Air-line Distance is ~ 145 Kilometer the Route Distance is ~ 192 Kilometer. So Range value is the normal remaining range. -See the Section [OpenStreetMap](#OpenstreetMap Widget) how the Range Radius is used to indicate the reachable Range on Map. +See the Section [OpenStreetMap](#openstreetMap-widget) how the Range Radius is used to indicate the reachable Range on Map. Please note this is just an indicator and the effective range, especially for Electric Vehicles, depends on many factors like driving style and electric consumers ### Last Status Update Timestamp diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index c23d889917212..180f0a636f0db 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -121,10 +121,10 @@ public String toString() { public static final String SERVICE_MILEAGE = "service-mileage"; public static final String SERVICE_NAME = "service-name"; public static final String CHECK_CONTROL = "check-control"; + public static final String CHARGE_STATUS = "charge"; public static final String LAST_UPDATE = "last-update"; - // Chraging - public static final String CHARGE_STATUS = "status"; + // Charge Profile public static final String CHARGE_PROFILE_CLIMATE = "profile-climate"; public static final String CHARGE_PROFILE_MODE = "profile-mode"; public static final String CHARGE_WINDOW_START = "window-start"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index e2f57f6a71806..090d8283ab155 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -120,6 +120,7 @@ public VehicleChannelHandler(Thing thing) { serviceMilage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, SERVICE_MILEAGE); serviceDescription = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, SERVICE_NAME); checkControl = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, CHECK_CONTROL); + chargingStatus = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, CHARGE_STATUS); lastUpdate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, LAST_UPDATE); // range Channels @@ -152,7 +153,6 @@ public VehicleChannelHandler(Thing thing) { heading = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, HEADING); // Charge Channels - chargingStatus = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_STATUS); chargeProfileClimate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_PROFILE_CLIMATE); chargeProfileChargeMode = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_PROFILE_MODE); chargeWindowStart = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_WINDOW_START); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 474c4af4d2bf6..2a51ba1ebc27a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -104,6 +104,9 @@ public class VehicleHandler extends VehicleChannelHandler { private Optional chargeProfileCache = Optional.empty(); private Optional rangeMapCache = Optional.empty(); private Optional destinationCache = Optional.empty(); + private Optional imageCache = Optional.empty(); + private int imageFailCounter = 0; + private final int imageFailConuterMax = 5; public VehicleHandler(Thing thing, HttpClient hc, String type, boolean imperial) { super(thing); @@ -133,6 +136,8 @@ public void handleCommand(ChannelUID channelUID, Command command) { vehicleStatusCallback.onResponse(vehicleStatusCache); } else if (CHANNEL_GROUP_CHARGE.equals(group)) { vehicleStatusCallback.onResponse(chargeProfileCache); + } else if (CHANNEL_GROUP_TROUBLESHOOT.equals(group)) { + imageCallback.onResponse(imageCache); } } else { // Executing Remote Services @@ -304,7 +309,7 @@ public void initialize() { switchRemoteServicesOff(); updateState(vehicleFingerPrint, OnOffType.OFF); - // get Vehicle Image one time at the beginning + // get Vehicle Image - if not successful 5 times retry is established proxy.get().requestImage(configuration.get(), imageCallback); // check imperial setting is different to AutoDetect @@ -342,6 +347,7 @@ private void startSchedule(int interval) { @Override public void dispose() { + logger.info("Dispose Thing {}", thing.getUID()); if (refreshJob.isPresent()) { refreshJob.get().cancel(true); } @@ -360,6 +366,10 @@ public void getData() { if (isElectric) { proxy.get().requestChargingProfile(configuration.get(), chargeProfileCallback); } + if (imageFailCounter <= imageFailConuterMax) { + // get Vehicle Image a few times - then refuse + proxy.get().requestImage(configuration.get(), imageCallback); + } } else { logger.warn("ConnectedDrive Proxy isn't present"); } @@ -532,9 +542,12 @@ public void onError(NetworkError error) { public class ImageCallback implements ByteResponseCallback { @Override public void onResponse(Optional content) { + imageCache = content; if (content.isPresent()) { String contentType = HttpUtil.guessContentTypeFromData(content.get()); updateState(imageChannel, new RawType(content.get(), contentType)); + } else { + imageFailCounter++; } } @@ -544,6 +557,7 @@ public void onResponse(Optional content) { @Override public void onError(NetworkError error) { logger.debug("{}", error.toString()); + imageFailCounter++; } } @@ -636,6 +650,7 @@ private void setThingStatus(ThingStatus status, ThingStatusDetail detail, String @Override public void onResponse(Optional content) { + logger.info("Update Thing {}", thing.getUID()); if (content.isPresent()) { setThingStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE, Constants.EMPTY); vehicleStatusCache = content; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java index e382339af84a5..2e6e285732a19 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java @@ -12,8 +12,6 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.utils; -import static org.openhab.binding.bmwconnecteddrive.internal.utils.Constants.UTC_APPENDIX; - import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; @@ -50,13 +48,6 @@ public static double round(double value) { return Math.round(value * scale) / scale; } - public static String serviceDateToUTC(@Nullable String input) { - LocalDateTime ldt = LocalDateTime.parse(input + UTC_APPENDIX); - ZonedDateTime zdtUTC = ldt.atZone(ZoneId.of("UTC")); - ZonedDateTime zdtLZ = zdtUTC.withZoneSameInstant(ZoneId.systemDefault()); - return zdtLZ.toString(); - } - public static String getLocalDateTime(@Nullable String input) { if (input == null) { return Constants.NULL_DATE; @@ -73,16 +64,6 @@ public static String getLocalDateTime(@Nullable String input) { return zdtLZ.format(Converter.DATE_INPUT_PATTERN); } - public static String getZonedDateTime(@Nullable String input) { - if (input == null) { - return Converter.toTitleCase(Constants.UNKNOWN); - } - - ZonedDateTime zdt = ZonedDateTime.parse(input, Converter.DATE_TIMEZONE_INPUT_PATTERN); - ZonedDateTime zdtLZ = zdt.withZoneSameInstant(ZoneId.systemDefault()); - return zdtLZ.format(Converter.DATE_OUTPUT_PATTERN); - } - public static String toTitleCase(@Nullable String input) { if (input == null) { return Converter.toTitleCase(Constants.UNKNOWN); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-groups.xml index fad8209665efb..11f659525b53c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-groups.xml @@ -7,7 +7,6 @@ Charge Status and Charge Profiles of Vehicle - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-types.xml index d1ca4372c5a25..cf261f7fa2136 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-types.xml @@ -3,10 +3,6 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - - String - - Switch diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-vehicle-status-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-vehicle-status-group.xml new file mode 100644 index 0000000000000..7ab36e7a95096 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-vehicle-status-group.xml @@ -0,0 +1,21 @@ + + + + + Provides Status of Doors, Windows, Lock State, Service and Check Control Messages + + + + + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml index 152bb3cefcfa8..3dfdb5ff5d98c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml @@ -13,7 +13,7 @@ Battery Electric Vehicle (BEV) - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml index eca702c6a4d29..a39d35606ebac 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml @@ -13,7 +13,7 @@ Battery Electric Vehicle with Range Extender (BEV_REX) - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml index f4463e3deddb1..d207379963e70 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml @@ -13,7 +13,7 @@ Conventional Fuel Vehicle with supporting Electric Engine (PHEV) - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml index fca3d4ee408a7..5c8e1f57336ee 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml @@ -31,6 +31,10 @@ String + + String + + DateTime diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java index a102d4390aa4e..b9d9eca63034c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java @@ -14,7 +14,6 @@ import static org.junit.Assert.*; -import java.time.LocalTime; import java.util.Locale; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -65,17 +64,4 @@ public void testTimeUTCToLocaleTime() { assertEquals("Output DateTime", "2020-08-24T17:55:32", localeTime); assertEquals("DateTimeType Value", "2020-08-24T17:55:32", dateTimeType); } - - @Test - public void testTimeZoneDateTime() { - String pattern = "2018-07-16T21:47:46+0000"; - assertEquals("ZonedDateTime", "16.07.2018 23:47", Converter.getZonedDateTime(pattern)); - } - - @Test - public void testLocalTime() { - String time = "05:23"; - LocalTime t = LocalTime.parse(time); - assertEquals("Time", "05:23", t.toString()); - } } From 68986ef15a040dcf2ee632811764d6a43970ced7 Mon Sep 17 00:00:00 2001 From: Bernd Date: Sun, 13 Sep 2020 19:53:09 +0200 Subject: [PATCH 028/176] image channels added Signed-off-by: Bernd (cherry picked from commit b922b8fb3b1ca24c02e3855f80f63b8119155161) Signed-off-by: Bernd --- .../README.md | 115 ++++++-- .../doc/AwayImage.png | Bin 0 -> 215730 bytes .../doc/ChargingImage.png | Bin 0 -> 192764 bytes .../doc/CheckControlImage.png | Bin 0 -> 345125 bytes .../doc/UnlockedImage.png | Bin 0 -> 353189 bytes .../pom.xml | 2 +- .../internal/ConnectedDriveConstants.java | 4 +- .../internal/dto/status/VehicleStatus.java | 8 - .../internal/handler/ConnectedDriveProxy.java | 22 +- .../handler/RemoteServiceHandler.java | 13 +- .../handler/VehicleChannelHandler.java | 17 +- .../internal/handler/VehicleHandler.java | 279 ++++++++++-------- .../internal/utils/Constants.java | 2 - .../internal/utils/Converter.java | 4 +- .../internal/utils/ImageProperties.java | 53 ++++ .../i18n/bmwconnecteddrive_be.properties | 4 +- .../ESH-INF/thing/image-channel-group.xml | 4 +- .../ESH-INF/thing/image-channel-types.xml | 8 + .../thing/troubleshoot-channel-group.xml | 2 +- .../internal/util/LocaleTest.java | 9 + 20 files changed, 350 insertions(+), 196 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/doc/AwayImage.png create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/doc/ChargingImage.png create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/doc/CheckControlImage.png create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/doc/UnlockedImage.png create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ImageProperties.java diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index c5f6c07459448..42372b3bef8ee 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -16,7 +16,7 @@ Different Channel Groups are available so you are able to cross-check which grou Please note **this isn't a _real-time_ Binding**. If you open the Door the state isn't transmitted immediately and shown in your GUI. -This isn't a flaw in the Binding itself because the state in BMWs own ConnectedDrive App is also updated with delay. +This isn't a flaw in the Binding itself because the state in BMWs own ConnectedDrive App is also updated with some delay. ## Supported Things @@ -56,7 +56,7 @@ Also _LastDestinations_ is mentioned in _Supported Services_ so it's valid to co Basically 3 Types of Information are registered as Properties * Informations regarding your Dealer with Address and Phone Number -* Which services are available or not available +* Which services are available / not available * Vehicle Properties like Color, Model Type, Drive Train and Construction Year ## Discovery @@ -114,20 +114,23 @@ Possible values are There are many Channels available for each Vehicle. For better overview they are clustered in different Channel Groups. -The Channel Groups are different for the Vehicle Types but also depends on the build in Sensors of your Vehicle. -This means also the Construction Year is relevant if some Channels are supported or not. +The Channel Groups are different for the Vehicle Types, on the build in Sensors of your Vehicle and the activated Services. ### Bridge Channels +If your Vehicle isn't found in the Discovery force a log of Fingerprint Data which helps analyzing the problem. +Please check [TroubleShooting Section](#TroubleShooting) for further advice. + | Channel Label | Channel ID | Type | Description | |-----------------------|-----------------------|--------|---------------------------------------------------| -| Door Status | discovery-fingerprint | Switch | Forcing a log entry to analyze Discovery Problems | +| Discovery Fingerprint | discovery-fingerprint | Switch | Forcing a log entry to analyze Discovery Problems | ### Thing Channel Groups #### Channel Group _Vehicle Status_ -Available for all Vehicles. +Reflects Status of your Vehicle. +Available for all Vehicles, Read-only. | Channel Label | Channel Group ID | Channel ID | Type | Description | |---------------------------|------------------|---------------------|---------------|----------------------------------------------------------------------| @@ -148,6 +151,7 @@ See [further details for DateTime](#last-status-update-timestamp) in case of wro Based on Vehicle Type (Thing Type ID) some Channels are presented or not. For Conventional Fuel Vehicles the *Electric Range* isn't presented while for Battery Electric Vehicles *Range Fuel* isn't valid. Hybrid Vehicles have both and in addition *Hybrid Range* +These are Read-only values. | Channel Label | Channel Group ID | Channel ID | Type | CONV | PHEV | BEV_REX | BEV | |-----------------------|------------------|-----------------------|----------------------|------|------|---------|-----| @@ -166,6 +170,7 @@ See Description [Range vs. Range Radius](#range-vs.-range-radius) to get more in #### Channel Group _Charge Profile_ Valid for Electric and Hybrid Vehicles +These are Read-only values. | Channel Label | Channel Group ID | Channel ID | Type | |------------------------------------|------------------|---------------------|--------| @@ -187,6 +192,7 @@ Valid for Electric and Hybrid Vehicles #### Channel Group _Location_ Available for all Vehicles. +These are Read-only values. | Channel Label | Channel Group ID | Channel ID | Type | |----------------|------------------|---------------------|--------------| @@ -194,12 +200,10 @@ Available for all Vehicles. | Longitude | location | longitude | Number | | Heading | location | heading | Number:Angle | -#### Channel Group _Cha_ - - #### Channel Group _Last Trip_ Check in your Vehicle Thing Properties if *Statistics* is present in *Services Supported* +These are Read-only values. | Channel Label | Channel Group ID | Channel ID | Type | Description | |-----------------------------|------------------|-------------------------|---------------|---------------------------------------------------| @@ -212,6 +216,7 @@ Check in your Vehicle Thing Properties if *Statistics* is present in *Services S #### Channel Group _Lifetime Statistics_ Check in your Vehicle Thing Properties if *Statistics* is present in *Services Supported* +These are Read-only values. | Channel Label | Channel Group ID | Channel ID | Type | Description | |------------------------------------|------------------|--------------------------|---------------|---------------------------------------------------| @@ -242,6 +247,7 @@ State *Executed* is the final State when Execution is finished. #### Channel Group _Destinations_ Check in your Vehicle Thing Properties if *LastDestinations* is present in *Services Supported* +These are Read-only values. | Channel Label | Channel Group ID | Channel ID | Type | |--------------------------------------|------------------|---------------------|---------| @@ -259,15 +265,21 @@ Check in your Vehicle Thing Properties if *LastDestinations* is present in *Serv #### Channel Group _Image_ Available for all Vehicles. +Picture can be modified regarding *Viewport* and *Size*. +See [Things Section](#Things) for Viewport possibilities and [Status Image](#status-image) for possible Use Cases. | Channel Label | Channel Group ID | Channel ID | Type | |-------------------------------|------------------|---------------------|--------| | Rendered Image of your Vehicle| image | png | Image | +| Image Viewport | image | view | String | +| Image Picture Size | image | size | Number | + #### Channel Group _Troubleshooting_ -Available for all Vehicles - really! -Please check [TroubleShooting Section](#TroubleShooting) for further advice +Available for all Vehicles! +Switch will log a *Vehicle Data Fingerprint* into the openHAB log. +Please check [TroubleShooting Section](#TroubleShooting) for further advice. | Channel Label | Channel Group ID | Channel ID | Type | Description | |-------------------------------------|------------------|---------------------|--------|---------------------------------------------------| @@ -361,7 +373,7 @@ Exchange the 3 configuration parameters in the Things section * YOUR_PASSWORD - with your ConnectedDrive Password Credentials * VEHICLE_VIN - the Vehicle Identification Number -and you're ready to go! +In addition search for all occurences of *i3* and replace it with your Vehilce Identification like *x3* or *535d* and you're ready to go! ### Things @@ -390,12 +402,13 @@ DateTime i3ServiceDate "Service Date [%1$tb %1$tY]" String i3ServiceMileage "Service Mileage [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#service-mileage" } String i3ServiceName "Service Name [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#service-name" } String i3CheckControl "Check Control [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#check-control" } +String i3ChargingStatus "Charging [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#charge" } DateTime i3LastUpdate "Update [%1$tA, %1$td.%1$tm. %1$tH:%1$tM]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#last-update"} -Number:Length i3TripDistance "Distance [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance" } -Number:Length i3TripDistanceSinceCharge "Distance since last Charge [%d %unit%]" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance-since-charging" } -Number:Energy i3AvgTripConsumption "Average Consumption [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-consumption" } -Number:Energy i3AvgTripRecuperation "Average Recuperation [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-recuperation" } +Number:Length i3TripDistance "Distance [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance" } +Number:Length i3TripDistanceSinceCharge "Distance since last Charge [%d %unit%]" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance-since-charging" } +Number:Energy i3AvgTripConsumption "Average Consumption [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-consumption" } +Number:Energy i3AvgTripRecuperation "Average Recuperation [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-recuperation" } Number:Length i3CumulatedElectric "Electric Distance Driven [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#cumulated-driven-distance" } Number:Length i3LongestEVTrip "Longest Electric Trip [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#single-longest-distance" } @@ -424,9 +437,8 @@ String i3Dest3Name "Destination 3 [%s]" Number i3Dest3Lat "Longitude [%.4f]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lat-3" } Number i3Dest3Lon "Latitude [%.4f]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lon-3" } -String i3ChargingStatus "Charging [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:charge#status" } Switch i3ChargeProfileClimate "Charge Profile Climatization" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:charge#profile-climate" } -String i3ChargeProfileMode "Charge Profile Mode [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:charge#profile-mode" } +String i3ChargeProfileMode "Charge Profile Mode [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:charge#profile-mode" } String i3ChargeWindowStart "Charge Window Start [%s]" z)5F9)LFnV;U&>nfrM5ivOH(8WVF;T|>?!ab<_!4&lnFZ{ zJb})s@u2-q&{(Q*OG1Oe%!Bh=Zk5bExD$T{a1zC*FVVUYwil!>#P)%1Mg6iz09&{x3Xd!cW6b)ZM39U`OP^X;w8d>;iPGLm>FTmM z+O40VA$^ea$*De?-A~(lH>4x^39A^oe;8d>9#op^hCBX5?^~QCDf#xXGAr6l=-8#1 zd@D2eblnKu>!*D>P#Cf0M?7(4w$KepzKC|=sQQ#8w|GS+AR4r)H9Zb^9FZUuQuJ$1 zTiaIljY)ouds%_L!4(gxu2M43?spQHQ)gt*x3z_SkLWnFhd`3SrS41C!;jIyf3NL76&k>(YHSi5d$4QNcCn4HmIN`4}j;EyT95!|R+Otq_P){9p*>?K;} zUW%zC@!MrVV)fh?etxhj_lRb9T}D&MGrvpm7D{)g>Q(O2Y5^g4YrBb2wp$KU5kVK| z9Kmsr{n|lxM%|#2x_rpjnvBveP+p*}{n`f}Q-nI6E+?1Cz~Lzqq>+!`MT~r9`~89< zrt)+fzbYzYskPivV|Nc7iVcdY?_8ep<&Tq#g#`4L2eF&Ju*(q4V)wpyk#DfodvaRf zxN*oWZg@U~G}f3&IW!%yKrSl8u)X!Ci?(Ip33KF#T#HMw7i7{mJa+yd+2K***q<9F5 zi?v5Q>C=pn&y*)DTwr5Nyro}wP>yvL(!A;$_aZHsfOBt7`w6u=TS|1b`{?c(Fps$o zLJzep4jd0H_!q;2yq&zhVO~`g^J&j9v;`Cx>Vj+H;j--vV@mQgRn0qqj3{y zu5^990hg#V=eW*br=H%kucO&D0pDkJ<6M~TZ@b~>98RxSp8rx8J#bN9-x<=^gtoTb|e`6j0Xb58V_+G{YfV#qj)@v>sFX&bMS+>!hk3 zA5*dJufE-uHoiYP(Bn7_67w~Mxi%ZNzEbVLdWXv-M|#^+xbjl~owGda+MA2g7Td1L zGQN`bV%*|iG6=~xs-cv?hM;vwl$d@*R-f(|NNB9Qo$ObOw0RwbpvD%Jx9KTQwfL6dPu!iW zmCFU<`V+3kLc32CQjE*OBv#(@Bq<0xaA=XGG!GvthM*FZsYFH%tx6OM7vuOQ3?qbN zv(qPiT!;)_5H%ksA7jpXi!pO^UY{@V{lKU!#2b+-udEpE{R=Jz9x*?UDr!GXv8I{u zXK&;0J2>@LdM-!1){E7w-|r>1a#|u<@;g<0iMI~MG+0@@R~Oc64ma!Cu!$p9k=efE z{3%Q%DwdCUKC?-@Imd}X7EY&}%qQ4jQ}<#I`5+K>9N_Ot$Dl-!+mh~7Ovgu!-)$JN zg-2(|U^gPIBbM~LUF%I9rvh@9+Bm$PWtZJAg>k@@>wyDW+_Q^rF00t?z?ri1bzD}b%%D>c)zt6fX>9VwbWP{o$e&`t|;WOGm*#W8EW0it@Xrn>KXlA6#B_iuV_u!Bx|^U@&!N4}6K#I>}= zdZ$dwnh^Tp(*hMA{B`Wn5Y3&W75M8RavVd94AepMcgQmKMNb!gI)OX9S;TRehdwst z!M%W-Zn#vps#w_kDYjA04frsOjt^I{n-$Kq6A(40<0C1_m1b{kO-@7E8yQ11bkbB- zU)W%!@~tIikKLaM?y+eG+WB#wFtFJh;>=0;w@O2-9IdbF<2}%G*HaT6!t4mpD!H2Ffm7azBRkz z=)f_0%t-PUdL%h+?>zB~#jCXl%3|Bd@my=wV$?GbMPY{8vCtGEcr5Tc)!9BTw zPd0N4=WJ}qyIVK&CB!H>mj?s%c3)CSJy#HJXi+r&kY;5QWr!MBmc{tY?D;ZX(O@zq zQ)*08(ICIo!3Se;s8U@wn=}Xy)P>XUIK2-L-tw~{1aHB**GI9 z)pDxQ=KWgT61HeP$+%KC!E!53B3NFl{;}CBWT51G;u^DH`q=IDXunf;_2!c~LV>xU zi_$2Hfmg#)I2ulOyxE}7?`raU70#cFRj3O+)pJdFbgQVu#i*qiF2Qu@dZNvqOdn=u z4qn#z%A^PV{7Tu{GW-@(E`>f(nWRpt3FNH(wP~o7`i7hj5sA%C6yC7~8rjT>jsf>y zE^u37JBbLJJMUf2 zpo!qrd0C!uSj_PJCX^v7*p`rMn#}Rih7Wa#+LFE{u^+hcoPqTY8TQCfzoY0e?Le&d zvigq3<9~T&cey^A4P>+N`6^c=_sr_gg*i9x{?e@Q8YsS~(>1wOOQo`|L?keq*|;Bl zT2ac5PPxx{%LBI!SM^BP*Dl~DHS-?5u+q<6w*iUXi11LAd3G7x?k@F2<8U2ROY0Jl}kb+6wr3+f?<1iXdrlzSA{jx$$W_NHIKJ*6MiCti$8~U?N0{^61|p4yBjYRUdl+KlrVYcrmEU2 zIVNP2Z>>-}BjF<3_0e#h#E~x%(xtd?+5ISj!H{Pt!U?@6G@R7qukncOv$AUwx+gw~ zv{iezN%K_XDwTEXiBmN%W5 z$CeD&Qmt*&7g~UQGU=15RWcbdM)cTb^akiemtHtyWcGfgWA53TV_I=diTRDGx=!9A zY_f|EPFvb>ex#A2>fJq%YRA?qfp)8bQU zY5K4Paz`&NEk0fPmFd!KsPQVg#toM*--Yn`5JOY`Ejk*sE1V{eq<;B2{Tc^;a6_Fp zgW=-G@F((0v)psH!4zJKD!zL7lk^3-!iXbW`1jbQz$v%s<@;=G2s+{=}HuAN} z;?8P^7LTgAYOMv$+Y%5wFR#LpGa|}<=;g^|kb3#)d~$dQDxDNrG8(s_9F!4WN^Q>` z4RJkLyfNlvi-MKK#t@14Z|#VL-SP@d09I1QcBj)TYIj#Suh3&N1;$Yl46#=soyt7+ z{od(rI95~s6=K1O0b%9l+Uea*m|?QV%Jfu;r%ZJU|3Wxludt)uGV7kecbSyb+;rSH|% zdUUS-MoDnw8-kZ?oWwQ}yu%FIQc^#JUJ3nBz?NMh*@H2?9xG&}YrDUr+ulJT@0{P1 z@bEgWBN;SAfe4Sw+}^b97?xEJM%#YyV)CK~E@tPHbSC@l{d?iO)hR5!&-95R71S<2 zjMvwm(PLJ!(K!uo*<5i;mUWdTWJwF|alMUT*XNQ>6RwgccMA_X`0;(iX{nyEKA7!< zLKQb7AfoARjmKN!WL5>dKb6Slk~dzG=3I;%=MiPn1TGvy&RDd{7)}*~tu3 zh_!an66!FdRr!T07erc2HK(z|*?1Z%T0t7d%iA^Qi7%_LnrQ>k(hQQ*cBJpX67Ibc zmCD&TKOOa?-?w&J>V-wstdop*c6UIN%Of1LLpyWr4LWm=y$q-`!Xxy)mOiyCnJoS2 z!?a!nm*W0)+F_l9j3kcd;<-bD9Wd|>3}XX5mLnukua5NV?QUwl8hvUb$;KBYulFwK zQJJ`TeH^f_DHlC))qr0K+TE29#o6ME6|jVtqG?+Y1nrjhMH;bwRM+i(Rk7D3U4jjI zeVMAa7=dJyDLaml*`6_Izq3Mh)1PWdqalVPt3)j!ttmXIOO}q&>lMz=jYE}=DCMm9 z_ak1!0?w5jx}6c_q467z_Z>W@4t-^JZBP){D)-?!2)*ZLTemkbFh5fnFA642k8^ z>`Ue`9eAAfTm|ClQnJXT5teoKDA?iccuM2(>^x{Y_ab5t{Yv6Z)sl8GHi$5& zC(G_3(!X?~gXhuDR z=M&vkoHBF_J`HyZLt%7_i?zNMxVR3)9m)C%@Q)al+e-Bo=j^1hN0!Xmh_1Vy)GNe0 zaq7}We|d;^vc*Xwt~z;=ll(<}GZV}$P~C0V7S;bYF7<01a6O4e|60;(;gk)J@yOFhTli-J~5$I^1Huyc{#kFlI0kn0CE-PGP)IWcC+Vk1y3MiE7MY>4zuQJ-fX)9Z_LkRbCg z9W+EjfpP=ux4EnzNNc{VY`W~lgILO)@m-Od4q8$z@Gv;G< zwVO%j(aDCs`at!c_PyVvc*=Ln5dOBndD+qC74~CNy*z!eGZ~yKCE}mno;FL} zyiwDxH=E`?bz%Ad`H7sB^!um&AbqE++>=(lwlYX`nOEA0SX=JIsaf4#dog^RQna2q zoN6bNGD;~e<9%DkKBa@ww0Gfl{epJ!M{s^;bZUBG&lPjPJLLjGP_s1tCGF8XbP<|d zdLlE`UH<7MI^O$3&SD{9LWru1mW=Wa5L{uh>2m>M zzoxz4opJWk&^4`OxS-H=u54k`QMWE2f=*#x|?dw)8}&42~LdJPHMU-O@F4p{Ci-$!c7n{B&873)3gBOa&G(85QXV; zT5Fv-j!p^0?<;N@_r}NLwlf^hrzs75qaemiBMu05W$yYj=rX4`8Tg{pO7aEiye! zk@xzo_>t0FB+VV(SWuOr)H^OlSU?flm7Iv%=JKWO|XY04{ zZ;=Gchv%b)d^59)!ORDkBl2l5chtNWZtTz`M&HTQc=izq(Xp8vK5Fi%59Vvq4#|rV6Kwc^mg2z1@pK-|o;qxn>K$_BD&c{%!*Lk0@1clQ<7~+i zyA!PW&xIYxi2g+N(sb%%oI;!1W4ppl0tv*lJC!UO zimW-~;vj2M?4ITdIH;Ax?$s#HZRo|3T*!)4P7tW;*w5c{dA7OkRR#akRPRju@AD)s58hV z&5WjMuKL1VzpQwLM7N*bHCD9&nojmD70%vK%GCk_Lg@_{mlW~y#8y2=bv9e4lH&4TO_4}JUO_>l4H|->5lxdiJhi12fw<~#b5^g;iUhI zrmqZZt8Kb1(Bf{v-L=J`NO6ba6oM3YcXxL$Zb1ta4-Un>xNC5S;`*h}drp4m%C&cH znKiT4tO?2frr(5IW(&@j`?Q8ch>(VwPPlM>evgWc6FvC-cDe$o!WtP8gQ+jJdY@{q z(0Oif0ND9 z0+wAe`?;Iopl0sy-yVlL{2g|Ir$XgKgiktj5RqYa8HPr5>tFxEI_B;ynxjE8_~TbD z)2`>yLH(WswP0p!f`0t^FGh@ba1P10HI0&d!;MsRa-|#6Jijg*yA|msgNSv(MCUPA zR}TLC9^VG~o3%cZWlyay25I0hEn&Bfu)Vo;4uJt~&vJ#{)r-N@=W*;<8ckHOTr+S~ z;WStT6gUJKfg9Oqcfni_|DGlEKZp?q#sOa(JXXe!sG2Y1kA6u#36Qmjiz4HCrL z^kV$9dIwEYRp9nl9B2ubung4+8$WG0D9&1ktSlzI9-Q|ttU2kdE{=KDnrblvTEg!Z zh427~>DPoOv0VAnUC{54_ym#aM2i&bC!ol4Cdog`7Fp8FbhkIp{h?7~(xTnUYyw!O&ExM{M z;s@|7&jb<>#aKcPM8yPyTmKX--w*qk0obzHJJPV?`zF}k$i>gyUx*S+TxBn}_VhNe z#}-`!rsMI|w>-zU{k937lCinWoSl3%YXIRS?iTo+9`f+`h&ohqXS0wkewGAnlc|sB zlnd8NR;r2c7N~CJ39FGwf<`-X{(Zx5%Ms%|GAU#Mq~Smx$z%CjXM1OuG-nEC+st?yLK(a{kip_V!nHyZfu=8m&>%VjIDiEq_L*fkFtFHoBM{5E`~ zny1!#pRM-E zrund|mOZ8~u6vF~R0?R|MKS%Zii7Bs1EZMO7->&qv8R7YNMy+}%EH3e%K3h}qHjz! z2C3u41Oh!)Wy&#akE6!FNfk+yj?1=RR^KOZeGixIP=!Ty$VI>0xq|_ zifvT@f0ouar^Gk94(_p3X)t!0*lxGF)7U*-5NdecfC2S6&|xB{t!`TbH6z(Y>Ma_8 ztC4M9Y-3v45Y>#!q@36UDpol_wCoCLp*F*#JzEIwx2HcOUR27gYLvxT@JT|u@LJa? zadMFw1$|{m+2d;ey)w3Hu}6fwKwqfX>L^Bf!VI%uoCdL~)@5`sipmYkEqplzx?)e` zSECqEki0^id^xW2qPVN%3q_1bg3Mx8Y%G6wRROY{Vnq_T8_bu0;m7a3VUQC3r1+I< zd6mqdm50aP(>1H<3QDAPb}^OuW;<@1dP6Cf3{s0juEzh!f{LvnA-OI}mzo)}lyKZoQh+y~6Edxm zYQTE)J33yzl}G77cK^S;Rtu{%&uz7N?Yv<6sq z9C!x4;@d~fQf6$ZO{3$cRKXqn0CFb5H$$4wwOi?-0Q5VSTe{>+4PLtW93{{`8O#0v zJHFifHHh4kJs{!nfR)4DmHMgG|$NNC)LxY-vDP$wwOCZH=k;X%)0a0F-2$Bg6 z%~cExt}IqtUlG#L&BBr^h$(@i3sV`h13_}1s&KaDWFoxHR{8L-aA*7$(k|8P>?10V zq$sNa;ox+*GuHE```|m@65w>N0H&a!=|H3M5vcL*QTOJ_b(4yKZ5k~Nw=?{#i6+Ye zPYYE&ekrGK4;2$u<6~`w47YbZ{4-mhqkI!m0N%(t^xO%NuMT$NweRi(#cU8%ztgv2 z%As3WgXO3cz&ioqmE-Pu9mfDo6dId#zK-00jK9)6jnjp3DZztiOfjd&zVkX;u%LY` z*TBW(Ns!lL(oE@7XH*3CE}T)OB_gs9D~SQvetHP@(GqUw;-rg$3QR8-f;%YL5;3)g zG4JYnG_d|OeGnGBFUfW`fLnE5mebwN``AGoFJ)pR?Hmj-v8|N522lxu zTHDjpU^uw@PMPnUP3|sZIt@;fX@DF;{&zj)^ND6VWv&d^m=tcl`5vs1-^LGJ8Gmws zjntJvYQl;XIHni<(RDKQ@BXDq@ZMg)_Z-w z_^YqWr~7+^N;{m>ozegV`tN0#D>)DWes8hF{50>TwgF%d9;&ZnwOFNdF$1tFQgPNC z^jk!sU?s}4B?pYtGz?#uLG~b*(;-Z%Q>vlM@0M(JK08eAYHDgwTQ_-YYo6p`(|W$1 z7hhl89?EYrGZFKA5|%V&C5MVwgqjS))BSy762+#pw#d4A96|F)|8Tsd`rD;Ll^tWE zLf^99c&pQhO5uv?v1R~$_RA`l4Wk4mh zhSstIN(X2O4X9B=csy@FNKo}hQQax+mJCI5=>6xN3(jVg@hExibwmG;v*PY+RCkCD zqNhJF+7{b4W_Lxkf?bF*_CXF6ga*NAI0C2%@GMqXw-H#s#{yPM6s zsRw^1B)hsmbD(Cb)k?Aw6vW7t0yAXtBqBlJS>CpR0_qKmsW^!G*~<-tLG3MCj(K8dJF<( zmaHQxTfchv{NvbeV&&iG;n}DDWi;33*n)zv$w7U{oLFXmnb3!H5$*nSIf81YQ6vVu z{v+4^GW+DpjZ9FnGZS&`#6R6Y&AaqWO~~&UgQ{~TTbcp6qzEvfEceq*QiZ+6kZCLRmz(+g`k!%O9S;T5zUdE z7dVU`10lj59tLZwfYk<7xN>Dw@U9v@MF-rG4488xYzs6(n`OFc*i)5~BNtYtmRioz z?u73fl?jtxG-TyuN???jX!VHcuZx|dntv-G6P96}ArNlEUqiN?deW!GqSrInmAu;p z>{hZ>`W7ifY|JII#a87Q51080=yN!sL4OkAF73{LyP(ED%`*Im<~x4sGmP8dk1v72exK2mmr)})`mtMUk>KNp~lageAhJd?C#PJpt3YH@X1@HF>)x7#lIKJOH zd89D;QZm_UVDIZIjgnEcG z&mfkHtMW)*6P0Q}XWW1LgO+U=h1(A@5Gh7Qg>7p^tJG}3uFsx2JeA~78&Qc)zsCyn zoLjd&hLMur$+)D*xUJSo{Wv@(CJP!9V;7|qs|bG*4Fgv=OgRh}HI$bR*IW}35nZ^; ziUA!9v3+%QLQZXHa+yN^rA<$eZ8l(|-TC~@Hg{0zSB3zWT1R@BG1x34C^8QDO?%kI zO)YKHRK^0#;#46#-C6X|^9_AkU^2~P#N8IqBUlyxJU&OKFK>i@#!T83)noPF#mTGG zUH)|Q8$u)=vnVF4>{?TnS<(z+;kigF4`2?7kQtR*#%)rOllmjD<(EKN9dQJ}0FZ@T zUtc@CXljXryP)QyoMvMdP$Jr*Ou6qy{|qH4EBhC3Xvg*^Z`W3iVfA!|3T)=@-m_Xc ziog8&xGdfi9qRIj*&vle$-rnkxhIBy53j8TUs~XDyf{$v^F9rfaKgYr%;~W&ouvC+~j1}frFO*@C zZqGxjx90t(Cs=`Me`*O{*+4s(;SnEY-WwNU0$IxP#QO+?O7gh4E|F7uOe?<^7Bx`d z|N5$THv)(bQH8UdWlH^}Wd)NZLo;)j!qacp&=nR|LZ=(hBzds6SCW=yCMH}=M9gSw zWn*Qd`N?LxSK7SHi4{8Lg%m9s7Cg~FK$!7?s{gAP8KhM6 zE2sDM~&a1*0E`Vt-fdzfLjQMMM|z zR|jnL-LU=S2spAB0E{FA7JVs}Niq||?Opn6nE$CvDiu=;mGbOiYed(^W^CUX0)bRj zRn3$t58m|?O5o=F7!|FSfX+IRmXeD2TKUzmPpW*hJ21g=<5FD*!_SKZc0n6ztVtsT zD=SM33@NFrHbTNW3-Ln`DJsl&foA5(t>Du->T%6=&6{*n?2dJn9?u7v%>FZ+fZET$50jH+Ew6IE8x0bPd5 zi!rdWe>yg8znNfMH0G;56q!M%{W%7)FRr!vjfAAa3`g4g*!-;O@XhbaD}*}A6!eHD zfl)dg?V&SaDx9l>H%JX4tJ~AUsQ!TJ8*W9k=zfJHv)~m3EQPU!V4A(3Xv>ym{5_f0 zoTKC%dA7}}Stk$7jdWKCv$$0XkOiK8p@m3f@Ip@=`}-d^d?= zQ42n7yULUrI(1S!iHWO2I<@Njs+I!CZvyIjqm>P_puSonv6w_AL5-bLkJJM zC)=@haPaW(u*vo`b@2$9X3^#&-lN1 zmJOctQAV#WF86>1;9o%(Xim6uVrw;FVSjaa*mcCOLmaBX$t1at{F-=Cb^b6Ue&?$r z`-H;9Iqlg<_b+|JwGaJ)`x`S0^&iU2nSkSE2$GR5LTxXuQd`~zRkbr!pg!`-PLhz4 z3VB|c^zd*7eknEfmPwk3SLQdLAR#dbL$*06SNSfn>g>|5t+ta`!9X8Qp^7F1t8Ckc zfV*6vOGTN7N1v8VmCKA?E#kMZSiC}}qpNf2=s1#`We(;!-fMCa~ zsI>I1Z#Wq`3Q1hN7w#$|oMAf&?yUtmGG^IWQQI2~ikucjj}YO0S^AgIPGH`Z!uNEN8ZY{qCV3UWk}i-}-z;O|^O*!U8` zs>)3Ij3`e3@wrSn=y!(*E|TuKFH6n|jwOx~f_wD3@RTvQ`8Zfg&#g5JXQFfpr87|d zYBgr{$8~YKpsBvOCz4hQ&zCP?(}?U^w_>tCVcs{ydW#2xB+Nl2dPxW)9z zhf#G@vvr~0T3XH~pdN<}jZIDN4a!;bb3#?b=V@bUduAs=im`_3srGN^CX|Yb7UBJz zF)r_dEJD`^t%r^y=!{AWjv9*WQIW7qY1y0nF(lIVqQ1M>G&DEA{V51;b30vXvEJ_q z4p++M`^3dD(xCP$OQAS##gfQ7`i1Le9}308yhopeU;iwK$dfVVr3?%Xbhq!^t~=<) zut!0fIKtm&AO&tu>x*HEH0PG9T0?9mbVa=X0S+6e-{^r8>Ye=OU@7SgXOW$sg=VfZZIK@ z-PWeqjdk}u=&A8Veko2yol}%aVihlJ5@Yo(W2<7Ivz3DjXIO~D+*(xr)aWpXHDE|b z{;6(VM^Se9({~YN-I)aPZ7~rIaO$BhIE7L(K#r0oN2#$HLZs9?Xxs2o?1(&En&B6{ zFF`)B>m&gdq=rolcF+o=dFb1sPiBI_wAzeWMiU9DNN~=L1e*V*&?~U&{6;s7DMyv} z2|B!z-*_N~zuuf(`FnsFUnbOEjbhlA+qUgHz0;rRNeGc&PD#T}2R~>;ZN*t27|FW*s3BjSB_)sCa6#bj z&mnfod#g#0?>O}K=WW`NtH8}|74d)DXX|zII|_u_h9q1PE7Ht(VEA@)9JUHb?9?sY z#>GudsgQiAP%&^)#3(nLY@p0Ul&t6b{11eRnwtCBS3nKBz2Cs;n8r^CRy<^t7p^7Q3}osiPofG#N! z(eyc_$x5D;Mx0C(y)%XDQ-x_hqKg+hYO4YlCnN1ORebliaY6c=NF2+uwfXt5_|Nw1 zs}IkUIl=W%GyJ9b`5@M^o{!UcDz=k}|oH%Xk#prpvhMVZ+T#FDdnLC}dbFh(3D zGqWzCBr8XX2^tt2*OJBw1+pr`n*_%jZ$T*$_VQcLNAus&RSLAnV$9LW1g^(8Cxvci z)pVO}iAhK}cq*~tiZBc&5IZy^DlyzRlJ;^2z8 zO*t~$xn$WiL2A2hOK_u->V@q#gFH=RJsu9Z>}=)J!MPM*bXPzK?`pT8bNdz$#V)8V z?8rBiEhmD0MqA74xDt*N2zhdPMe)DTY5Kc#s;EJ-K^1onm)HEPHvGU&bM~{1Rf zGdBK3E}{FJHFW^8Cjgw)mC3U&uE8o=onONc&h)vSy9XFNKvz zY!;#WvF)=>It~IjP(owPetm~Cm-JYN!gFQ5PT`}E{Yfd|(w-EERZt@!vEd*)vYP|>cHd|kzn?DN6R?brLovDg-@~)q_0?5% zmStv*7(+K@UM)%iO40=+c(I+&=C<#hEaDSnu^g#rIwCN8p(O%GDt(>Uub|AI*my#3 z3VjX-2M5|6R&!B!qx<7opRM;4)~Z(KN4RN}^0{5Vq-tK_7HeOSmwlt0oa)JtNaZNa zN0;*|)``U=9vtN4OYHUXv+*!d_wS|d4KW5TAFXlm+e)Q@A}^i)&V#KCe2lDH0-h15 zUs|?B$$xb*QEXfju{72@eF1j=;Tonv$P>rl=9=Z@;o{*wrYa4UC+Xm8jir&ipolv5 zua~qH=HRHa{F_EC9cQ!AdHev#6>+$rkn74FREc=PiTxKL;~>_AX*iJ|M=4*7Ah|Q^ z$M&YzM<4KE}R;^&WESdhtY-i z3o_Famgh5f2)W0Wj-o!2kn}f#^-sAHt{>86*xVmqy!aDg0>l;2sqtIx2TeL3^vL}# zI+YWVWZ47sS6;9RFz-0}XyHkG6T4a;TP0X>6=G(rj(t3qQwpNpiT7rdT2Zwu~UEFDJM9 zZ=9QmD#GE>9JTL)H@fB>vPzIowdcs-h3({i=c9RIdm3wupTerVk^S@hre^pw+ZyC}44IwdjQ>>8 z@BZztt9#er9d|FSTkfr}r$1R5v{KX3Fl{OQC_P?Rs%1Y)B_|@IzDgy*VqV1hyY)HmCUnv0dxse4gh%)VhR#2>z!? zVqmUZ>S}(~wf(op>aU@reUa^^usu5qA(?=>78`&6w<+Vn+tZaUkZvM)?Wl~Si7HU*27ap* zPwCTdcmW!BUD&VfGM)MG-#u)I2-yk#xbLnR)B-YJE?qtY-hMUM6JKftd&{0EuHDpv z*Ny@pSufcn8w)>kChg7{Rt^TMRsjrhRM9e;#c;b!W_$$5Wumsi=W>ET`GY@f0fAeN zF2U``0xA;dpe96tOEB>c7Kcz!n3AUUK(B7Q$JEot-8ygArP(S6O+|?Y#`VXf6lBk6 zco4;pNdU#wc@Uc1#()Hj;yLbp1yv_rC>CgNU;u-J?_v=GHBfy<2}dWVlXV451nlRR z<+8$3HtQHPT3*V;h{zL`m>~rPB{(_^&vkw3qptO#(VtF>8S|N*VVUdqq-ab7TWpo3 z1M`!={j|jJL#O8F>T)U^3(wT0cti>>0=0PV{roYS#@1$aiibOq!%6&`(@bEc-u-Q% z>-A}-V z@vBlvDpn|Gqo+$#$A|p`5IM$}zMnSww{YrV>OgE1ND|FG09gtPbLt?=t2o*|_{tqb z=b{xRJur0slYpdn6yqZ@a?=($-m%S{!E#hFj$`_}DGsu44HjGUBCoZ)U5Bw%wpC86 z6*O8n5*ToWNHQ~J>djdq*lwql;_)ie}iNsXa*&8o`fm#2rIm75sr6;hJg%M22!PCcp%Rz1H*U?q%q zMBYn|y6iEe!)_QOaB@QRPN(5IS5cl)($9{?drbm%Hhu5!0t3+#ew& z+|{NbpUUY6I+~mkwp!)&ROjaA+O9N@1LNDcN~(ju{eo2$(PHq~w?1Qe@WwrxE(VcyK!d8;^uuGE!yRiKwBL~Ovh z`nUP+f-Q%LZSg*qUiECjNs1ChD_{mAbe3kA@tgd7>Wfz*t*Dd)gX=eY?{jJL*GKb@ zNEGEUIwdvJVdIwC=66YJ7mkd#jHr(6*lg+UP!^4p^b}07lmCuV!gVOL2wTG3YQ#hU zC3H%rkNo?)Bn+Wp5x$Cilfp!-?~CkbG7QpnyNGLSSdm=LxnCoFC9nkPx390KJbW_b zIdGZqs3l*18zHJrQ?DCWX@04uClZLK7a})94RpvSFOs?FjvVGyB~eY*4=1>(qeaHXPv~SGm!O+?!RLd{ zj;D*w#4*o?g7WgtS~7S1)6piDO3j`z)fU46ray_FtZ|uVBx#miXM`|zgVq){Jyk>U zzit}hQiHS^vDrE9Xe{WK4HgzMb-DBwslyeV*ZqGI@!tyl5JbsscbQV4|5;eIDBmCC zhrHQJK{hAx-jM}5BDtphDyq3-m(_Zq+Sa0M(##nFgS7qa6`}KKjr?S(IX;T(lLpLt zivKoD#8Vu`^K{Y1v!J;JE`<%^?dSsBcKZDK@jByc1vHVjGPGWnKoS$ju72r*?2Hj@ zGkvk{g(mVpHsDwY*^*mQki_`z6?#U1<&V^DYqyV2<~@q9RM|SIETqdC_pAP_rh_G$ zQmU?()*HFt+cb+O)N0fOeX=7~JI|))KKCf<7d3}|gIZnzXVK@qHsk083F1uJq^Kfs z(6};Q?z56-*_+L6;Xz&HHt#BaP9uZP!WS|n&xiY-ZO8_TjW<>?AB}AZFZu z3uD9;Es}Q?@1KBHH(dh%YPYi}l%AZS^O*qQDF!^Gi}%Ij9dDYi%! zd8kpRZq}~E>P&_$;Lzj(S`G8xM7JMhdeYTf;kHco^GB<^oYbi*EROcN>1f5P6XC?)o?s1e)Hrn#i7GxW0VG`!!ZqE+aB29we%`-PG4k8XRv?bKS z!y3={C>4>e7$ia6oSKPWifc_*5J2~J&rS{6ad;zK?p&!%De|=*G*~mRZmre14t$(E z0=a>Sw}$Xy`{4Nx7YW9#ziLM@yvz#%uoI0U(cz*nyE#J;J6mz5e}Xzi4JgC)_0p?* zRSu3$fQ?SOE9j_sZED3qk>a?R$yBM;g~JS{^y z56`@PwZehpeh&&U0AgsUd}NN+V6C7}#w{P>CnYT1(#$Ae>T+QGJoy3~->vWjpN@ew zCZ^9~`PV3PReBjJIuf$py?eWsl@L|$+$-s86DF*(zBXaqiot(9tcU7xtNL$_rou}4 z^tx~joO=%)Q67Hx8n6n!Rz)c$pTv%5q(67tL&a)H9CT_A2d~fRZ_>5r+EpFHE9X@L zolxD9Z2K`zsTvr#d@FWV=}$I%>^8>;cGCAhYc}EpcsOySMjw+iL(KuicsLt#_{Tdg z&-zw`zqUzAg^u*^`w^UG@V~zqyGwa`Y?LTy&w;!Z$pv$;hE0( z?wD3#t2293Ztz?R#Hhg2I zWhjd0zOG4?sk_WQpGY#&9nacKG@A@lIaZi5jZ;E}U-BXHLDroLbVa0aQqngNF`DV= zX%6@G_RwfRqpMqkYtsTR?<_ZWG4T=h&7p_CP=%OAR6Cj z3dnNw0vLx5yZ3R(oLUgu{-yXxkma~sS0FrKGrWn@i~)&z1`kKdUtN}5xmDq+TR0Vt zsJs&bI$S&%0bq3>|CmREtSb+q)vg{(d$ z)QSl+7GrXo64@ZlYLo^HX^ZK9i8$PG`u)G%IHcMu9bEr<*0qFlKF-~!{7jYzI?+VYvLAuKc zA!MtKBNgd%-{@RlUr$Thvz#dz&*3y*4|*t9f82>oZit^lhi++a{%tlL-|-2wNsie2 znVo#dJ<$nmllvJ54MHXIP>E3tvksjyYwOaaDV=5zT*bDI?1u%y2o0!MLOTQdwgJZj zkqhW~q|fU(mlaID^c0uMBj_fz`dG4q)-08^oWj@I{Ohn>XZ0RUB-v+yU0Ti3oDJhP z4gK6GEUM&q7FB^wz9uRLO)~zpa(iUGWPY}zi`bxjKs_#HP#UT#Pg5e<{%JPa+#n{{ zWSDw|asFu-=XPM9P2TUIx#)Bn`0%6lYPdJ?6(`X}h>eneYOiUrf;g&;r*A;I;&vcS zA1|v-9WUu{@#q*0q_8IACaB8fDOn-aW+s)ym~E_u>a@Ce?O7iGsvn~|NkSe;vW_>r z?{ds}8m7a!m-^W}t+`8^4c}^oU-YT{uXy4SMnQ`L4JQ%fPGN0`j^`~EE5ELMnnj=< zyK;{&_n_A43HMqEd9wlO@~{Kg5R%TBn^q@d_^tp9M}sAqkar$DGA%1HEg#9Q?KszI zd(3^*o*C(&av;qbn!RWg6%hHQUgkvojtHlWty@PL#FH5eJ0$H5VnYrA`xqbtK@M(% zCwM)Ev@_)zm0De=X}Z;IudRoi<|#NjigWf`mjs#K+%(3DNDW=I`=h-ZS|4*yW-{;B)*DLY&2K zr-E5t9E@%D^ZmjY+D)WH)LBugQI^KX$m;wLzGIt)$=3AW1vkaYGuTs*b^Og#ahU@Y zzVr251s)R}se0WstfihrX_Fgv8YLBA(NswInzcfaZ7>2x4xb~eqQLSBU@Q-M!)!ke zJZ=?y_bOuR_RD@{d1CA5Lv}P^|0k^WH94O*VUlF09W&#IQ8@C{t8x6~FlkvsvVr`~ z4XPMO*OG@}Yt&E=wk~KV-1AU}9imTFtql;~ljO@PQLDi+&~^2RPv;Tzqg#b`Rznur z^>{x@jD!Nn=c~%_fKk}){@A?f9+q!S&*pDxuRS$syuvD8N3Xxb=piVYl36;JC`B{- zsZGKL16wHS5hd$?nW61N2`u~d{RqN&Z_9ZAeGjlqe`%NQdNVDQ!Ek0UuDv~*PBW+C zXRCnoHjb?t#(4H>P(!!yboq5L-Zi{-2iOIWjdfjoJuE+$c#M|@RP{uIylj@Uw@XT) z5>)+Xdv~A9A;+3%-8^=m*EY%@tUzJbnfRZaR+ET-rx*zc_u|bwFVChl#UKWr=GbuQwoFXMKg%bwvxsy)k_G~k5k0bq}dZhbX&T9Fi9E{N_q`+$k8}$O2WLu-a5h%6CgZ%e8j8N z^1lccafc4+m^Qv87YHy2YU9ZzTwun&_S^Jbl*?}XK0F3LKu0IjzV&jT?YtFdKMAJrlMzZU%#R_fQIC)= zIT!;R{+=$_CyyWKfjZfcB=()bfkCLW!(up{*T(0fK$^_^IWm2rhMbVBM>)I8p=X4< zGL6Ncf>!^bdTrf+l*0cAKZ8Ev6bkzG-v zHc@bcKB_JP^r$~>Sa(@>pw9gXpDLkC56Z`!3%3>#T+gSo(==1H^+`cDUZHeTAqy$DN&|%UI zK*@q^T48d6o&tgtFoY2Ghi!VzalEV*X=A#N{Lt{Fj*mve-P57I zFw4Ykw`tJUyMfsT5If6gO7s^&liUcUI8FFP&^{BQO06?nRPV&OBDs*XEZkh3d9 z%(i)n2MImU3U^0F5XgJA;ZToBqsET^8lc0*ls)plG_{AxMIj8+-(q9`33k zj4Y1=w57-5RX@xW1@SA@u+In#hKQFw<&=V&iOg&Vya(1?elc z=;xYwSijXjC+9scj^Ht)lLau)@!-5Muvl98^ zAe#DxETIpPn+#9oeD<7o!ru`wqS!Y;)4k>^e^6b^)T+hXkRe_A?sG_TxPObuuDPjFXZ>U2z8yCsp&clTiI~k&$9PCPTCz^URk*j zXlM;9fllVVj6!)qa6ED>Zof!l%|KY#fSi)AkX@zZWs#%=@kh?od8(i5JTc6f zN+oK;t;OpCJzHtYB+3_4lM%xbW(r+@Xw`F!Rv`jNp~hV9=|`UDAiMunvc2bD;?JK2rn<8L*sCp% z^`*Z(srx!Sz_@Yov8Drqx;i>_KNPI3D;L=jysgWEbdxJ+fQdvv6xso8CUD;lI7RL< zL?}dk79u?s3Ct#L6E58rC~q2SjF9+jPG|onbA|KPbLYHS(R@*4pMs#wWCyN&V1|Yv z=F~}i|BJiYu_4^m?J2n3baH?Q=W`)X?{%NdX#UR-GHb&M!1Td0dPW28>%K z_FR|2<ssOptmhENO!rb zN>HHKg(G%2^|wrMEp5}|z&mKWrClh*2LRf^_VuM73ZO0ClJgT`B|(hfeSaV2{wlfG` zTd@!f2p*fnuLwU2Mi@ZovtTm&`$M51A)-Gs6S^--csov6?JsjyF3x7reYoal*+PvR z-vVDAfN{>mtN{-V8SSq|DqUH)hz}!AN4(#w6T%S?&Mp$Em4#o%pvbJ*cBS?^WS}(H z@3AMG?C}-D@BZcd#c+Q@k7UX7?|xN>)v2PrPw%p;*0}D+uBs|lz3|UEEujk$NEQ|r z5luOte8bLE=3A?)t~9mWcSSO_DyaB>x!}uh=11{|Vr0oJY1C#fj$qfgGOjTI5kwUJ863<6hNqH73B0s3rEi^TR_=%a>7-st+i8>^cn&<41F@H#bm{i;R?1 zBd?NVy8hanU85OwKNj<@aBIS#^Y+i#c%+GwjY~sOy|af$2ItQseJk&M7Fs&liZZVh zuZkdMWCz-n9&iQ%pn@YB6)?$~_-?55{g{c>l(>Y(a2Sg2a|Q3P@V_1Qp{zGjb03O4? zYSsO@VUV}l)xB+N=Z}*6F6rGIxq+(wgT`%Ta2ua|*+o!{0e@%q5nuHFgmITXM~>kp z%}yMmXRU|&J@8SQe%$DvP0S(>C{fcozCa4Rv+gJM7xEDVi4!g1Vh)gPTC)It#f0TX1iHCmPoEr=W_3e4o8Z4?bxqA5i zsHEb}gs=b@F0PU(-70cCh&svuAzD$yct#$^PjtDHqqQ~{6&c_D{1%PRmcj45SBpar zj{x8A`wgnnflAvd!&i8Op;pPz$`lcN`to|qXowiyoTzGfqH#v|yM=@syv?*fQIx=7 z>kvLETEU6&6UUMlAWkZ&$)w!wbYcgz{oB*A7spUxlWr!Gw{!Fsc19DUe_S~SKi$LV zG^_D1Knt;rH^nQyn(p48)`a_Tz7xz`wC3SE%VJKYQ&Qhyt)r_YujcG6 zE#1+#N(LMPJ9Lx(1L_++`|cxN~nnqNa5O6lbVm5iE1Zct%&0T%?R zzsj(j0*cbszn7xEWSiI&_gQ90(Y0l>n@SHDyIOjMoh>wpSCK(r2sys&m|2ji#PB^B zHBV#PN|PiWRU8c*c{UiU>4{sb`HK5ylBnmK9(?QVE&6f!$)#|LHk=S|QLLOT$IjMP zuios2w0Wb+?KG8SDOR`1=kok@D-@7d8inq_=O?}@AN60^Uk$@2a%}nKN?y{_41kxe zW8QqX*Y+}K)Q=_$E@nmIuNMU1eO-Z~NTa>Gck*GQ4NGHw+r94J3zJa_{$CgS6}|r_ z5AzJS+VMy9bG#^oHfE?d%0t%^WV(k`%`r8vTwd9|;xnP%gK*(A+7Zcq3xxqR=-zPB3%f_lIQygZjUOJ)EACw%8*>bLU%aaJEFJQm=~pDSpCAA74`R)6tCxNG>2=FZ zNd-wm&NboNx=Ese#d3Uw=Cte0wn7t_WSkEdiIKVis_O1$RDmzB^ZBkqeHfS&R?>+c z6(%~Wo37&_0X=v{UJ*|^+e~>~>UACUkdiFB_NQAYP!wo7U99yy-h7{f* zNF%1s)YQ~`tI)=WW(^z6qYdgL9rw?D!jQ{i)r1s+e>DuomG(g+1j<3Mc zxD+@1d^u~d!Hhi|N=5df-{|h%Or(}Bii(rS(kA)C+2Av#gpXieAG_u3~y2ed{!N{=oFpJ&11H@@+GuYhbsP16th@zclXuGq_6D{ zXR{?H~EVGbgLD1Yp zOX%%M<3puQ;hFZOizn8+_tZpukVk#`C*pE#2jjmFSJ4y;_cZbLm(Q;lVp^6A9Z}&E zRaXx!_|Nj>+puF<$VWF#v}pJc7{bns9Lx^maf0NS*xr%VLpk6X~8JACn*&p6;b{X+_!D0FkZRy&f3s>I_+G225*=gHfbJ1Oy~RqeG|l znZk9Z(vx2jL?mcE3SV^NOiaj=d-9;?(Eo5tLc$zPxo2s=j`wItnwH)Tg;8OXMJVkk z0q^}kuK>yV-W4q0TYScu#%Z&X#;~w8#HzVRcV)Iga`q3dXERY5Nfej zHVO4bKDb0#VNOOxIhUKAJ)pM9ZQ5{O)%~9jY=AreAKl21wLy+ebuPT2PUppy7X$BN zZ1CcuY=n8MD5n%BDxXiQ`*@1Kh!-4+sM(G+KvgI&_a#gi!(V6ZhQYWx!T=%n*+&Lg zf#$JsnWaXXy~yLoNA4pf?A?A&*$mNLdsnoUq9t2fbnBmWBQI=j`uF1R$pM)3m^4bx-4G_fkckaP^%5I67ADx9GTjq1l5U=xe6;lz@NwFr zAz4-tYy*ZER5MO>Yo2xDOHKuAP6<>FNYM$N(ZGx%3OVZ&9$m?*V20ZvT)u-R6$6|0 zN`3WBk67UuGwz~L-22;R^1}P)h94$%)e?oSW&XQKt%tB&XvPD1=~-jZkr|!s(*T8S=1U%m2wtHxjBW8?;aYPjK512HIxFJD6?0TXvc($ZMPX>9iZp^3k9D-G zxGm*?&6q!Ojjk@bPPd8oZ#}{3gy{|EYt_JUzdINm9T61~9le{sRI9tvohw{CIG!^* zg{H^cS<e~q9NET zq1W96GS)naRL z<&!d0cF8pxk|$5H4dyjq%hJ^MX1GG;c5r7wYUcVc9|oX^V=Di%>H{-$ty7DHJs5?IH2^yR}qOcdH7dmeA3GF zL;&`OyfV$jX>71XLMhXp6{js$-e)8Spd!$mM?cvzbHQOB$I9n6*_R`;a<$Fow5UQS zDzod9cz(d7L5JA~u3bu>`Kzve5)wo;>`1)2En{m$>TkSI7lMjif((7csuWS?Wj9l* zx|m8?_9EkH0Z$R02q z#S8a#?>L#kuCTG;ZgVMduC??tiL3Y1&Uc=QBzoau&tVu@E!M|9x(mV9Z;)SD){dUT z7%@56Tnw)_1L=;jJ&IcVFy3=B*c@8IXQQ4^PfIU$aS?`J(AoSK%9~cF^x6D+H=dT% z>nL{8`|bP=vdZOTdjGuf4Dp1x`)X+5iMHQQzqs!GH+RDswE88N5S1x=3S$Jr=NI=# zxRtf4?_Ukoce2VL7ZU2KYr%n|u~tg5g-LERL)G+Iy^1KLzXZLq0vj`UR#4>=ZiR84mN>t@Xv#zqM@5YzqLK8SLs}=&~l;s$Utp za=nb1+<(9ou^OA`nJkKr#kE{B0<;djHUP6OlDX3qN&|)h>t7G;vYg2%^5@TadqX6Q zq#}%Z(+95HlL3758{Jtooli|A94nk>@`H^*34eB4xG`TaykVNK2JfNn82k`!=c5fy zxH)_HQNODwL1Bhg$5ByqldV$PW)*~7%F~#c4LGr^p!wi z-*caHE;Xrs@_d{wHcCYC^Fj07nZ*N%}S^0xe5Fz^?i&^Wdu8^fRm(c;n z^atye29wpOvsTyh4e*cmZAz(cH#bTqZpQ5K(}vAyD?Sn!YDu2Zc1w6#IOdxy-WMd9 z7lGp_19UbPw%v_H#6*;E#VXG?BbO){+MoscW|dRhD*nwh#Y9z-uW%hzqJk(Q2sSet z^M0JV1!cDFuGqFo=c@tdWuR?NcA4-NNvGe_h-#-Qjse46uZ8lcw)`70m2%=nd#6F$ zZV@0|OXLQf&pXxT{K=EE`n1naNY2m3P@}xOe5Mm=%QG8ARskn`JZHBPQ?rUfuc?z> zuCGtYe0+SH&k(Tp%P#2|1X9G@OE5u14zY@mJMx~awiG*|_i?Z%FU{)TAj9d)rE9{K zji^?&4`q?P{LrKg6Vz8z7b6X}Vjp$Bk!%F@Q^Ia7!rWv29BZQ}h*(9lSfd)>Ho}Y4Sx#8kfV(iT+(UO8x3e@&?H?e1!o8s{FeRK53pf z{H>0s-7-~b7M#UXKjXX`U(+>>xonu-rXZ>gnWh$h%~kFn5yNqwV#>c65!}~O$qxgz z$`9Jk+DW~SPP4b`dQ)M!K;m_K#u<|qz8qpTo%AvY`{}vyvNDSU2m;3$I~8B!MPV%i zn(*)zsrpW5ZDx6Go9$$)c=v3^8`N@$Qe#|(7?Gm>g8iD}uR)Z^R(vZD`;(q}@^49Qb2ZS?R^MKz7Tr@{ z-xzCd(SKYJ(``4-{gaJlbgG~Bgq89`v)yI~ZMK)=z&`@6b^G|DV+2I(*^0%auP73- zmOkIdSQEZBORI;`KOOl=&=ZPblQcd_*kM7fQ zMt-2^^U*LHYGBRLQj3&s#_z>QRzLb3c317c5zy<)Gc!v{(aF(+A1}R{a?y_Z955*U64wvfv#PB2KnHNrEb&n~^nqX-bswN@cMc zcNdb>@3B5ZR$|^?&UK2Czika9l`FixbT%}WTXg;F?i70V*&SBffsyPzRZc^h z*blqMpw+lWpAc0ZKK+(+=BrixKlLH+OFi?$+3$=MpPi69u8RB5zJ|m#`cm0?e!&LY z4*7OR23p#m63wQlEYIgYyoe(-EN`jZAyG>s2O&UUx=Mx$IV3obD^VpYKWMAnk)u+58SWz}ySSUAF@Y+p8F5uYa!> zEG#TsP*Ct?bg-1<0}Y6k5Fhl9^yvKfoM+ne>ZsZX4vloh(|&Veosa8$?dj?OWwP^T zr zX2ra^Q?B!>LRU2G;Uv&$To(P-=jBl36sfSQ3r)rQ{SQ~a)E+SO|C}^)ij0f|yu?5L zkTA82lxTw4seZo(6AOoZl41Io68KlN{5T{RY+{4fw3tm8T5sBCGM9E~$J`d9{ z14Mi=6%dYmi^{Lg=2YHii)&Y-J@f?dsU$QC;?=+I=G~4vw5oBfOo7sC>zsdh{w)|`=k=Ai z$})(y@@D_5djD_|Th+B8{T{lM$M7qhCT?27YQ(=Cz%nZs{9_zkTubmeuOd^&L9?9{ zc;P4_PZW`>L?*F471CeZI*(5`w&Tev7hF?Eb#*~!>Bsv9im3VvW@ckx>Ll!yle+u9 z`ooCYbcm~+&;6b@kCC`~o=ZIHAKfiUK7|BOg``=(6URUy<_!Q+L0oC2avciHh|`h2 zlKZ`_Bdz~P4DvO6y_i)yfl1BjB@(L-kJHL5k2*neGAr}150z0AqC0z<`;ID3Y5aWEjB@}nhe*ri3{p!hqcLqP>Tn3d!$`qE!-_ z5mZ>0QFlp?Y==9l+wO{>v!F^GS9!zB;Ke(5m8LW%7^uNcKJYK3+IbWEyU+)_(dCb1dbM5lx< zxOa7JYH4LoGq}*zvv;ejYZwbSu_evD;E&~%#)3c{?$-zF?t^EIo30E@kHEk5ePNZ? zZ9kp?Xwq0e-T`|;gWUGU2B6;o0svi{3&->RY$G!#kVk7jcHP$@8B1eT6}I`G-~9dK ze}40y{YOc04@}*%wX$V2e=6z5kR?Mf;|v3z2K22TFU|*&SHjLGP@0)v7TLBX556dP z9c{vb_ia6R@8^X$JW=r2HXn1{OkC8}27^Wi(J;fmrK_x`X`E&nygF5Y32mwLvRm%K z&|GuUUB&j_s;xcia!sCIMI` zo8<}4U7LhfIOM9FEC1-Zo%sE(T2Z&RQMjkH4QF*EXjhI3lH<~*Ny0q_VOxm2zD??N z?ON@PRh1eDJSuuj_XQGmK9#89d^t-b55l5FjuR)N=;FpSiojwr!y6!Z+IMOOqVihd z>X7BDJT^+&zXn}UP6Ge2@oJ<1OjBwSwwoRs`49X4KO_*iN9~ze^yv$hXiV|Gevtq}`cU!W>&{^?nxwu8AadHRe{#8oUJa+k3XqJuao96i~c&Z zS1s3`<{swQS5MEbdOjS*0s`XBitTcT&1}PX0H3SvX0sXIBdy29)3<-? zjrUuA{$(0fad|#;R!F_b`ZtbO+&>fXr?pq+8(*Kp$``C`WYoBD;jEgH>T-I7W5$i) zp5aW#QgVr0Rb&h{an#gZE#%Q>WqeB+wG66IB4WcP)AA+>iY*IgFiT~j^5ut=#}+al z9dA>uELd8dpeRv(^RB?BPIO-yE_I#uek7q`ubf3C<%z45o6Hih>VA3D<-b8gzPr0M z9yr@Z6GHuOb|Z=h2c9le$62Up6eV0+c{6GfUX*jfJNzV7RYzGPOQ{N~}|4Al<+^7W&@JXhHe=a{A~6hx@HGL0)RL^|r)%T!-Wz-OFn> z_PwpT3vEWp`f2@w4YQAboflH)dy(o;GRYe~Y_n~wmte!KmT7EhdtvU|4kQ^cLO%MK zm9DPf*kr3WYc=Suv~t|{3x%m>wL6tUN_9>Wt4&XgJynkT<`eaZUE4Hy+lm`9DPIRi zTe*zTn~js-z=7PVp>AUkgQY6R^1 zh7HA;=O^|bqpKYIE-attbJtyaI)!)fI=M_JB`60^#jx#5h1tatVkko7cYwe?fKOzs zs4&XUzu5YOc5~0H-EKR1fS1u+kVwLYF#Z5FTqWN87yjP=1);m&sB1Z_c(#I=cu~)D zd{FQu7GTbt@qw*Zt5K@J*4A@v8xie=qV3pUuPwq);=RiFwjT&9Z&!Zp1?I&y6#rV$Zor)%3oz~>v@{~oHX>F{KJpMcD$P|>9Pb`9y8 zj9L`u_tgoZ_nqNCt9s7U;NX?*KhxKjo_xJd{Z&M3|3*YWe0F@sWB)J}q(GGI16dx- z_Hle2K-T&us-(J^2@7D~77gSusZDe9%5}mL; zUn@+k7akWX{nsR_-V6$)doGRpgti^TfR?YlNDrHrV(|x!hzHQ9tk^F{4BJh>yI5x3 zjJF_#@)p6k%H++3IsJ_*d3h_SAf%q{bs#)}PCy#k;B2Wd2kLe-E%$m6z68oK-!JV( zplPifaE#eJ>@K#3&7E3xWz^`BgW>9>mNeeKG~NdG{R^CKUJ*z3WpBKFTza^m@(hLx zpA-V<=UgjGge7)8_kk*Mop9j2j!TU|sSeyx3pF)ioV67V+|f~?!c45=pwP_FMgdYj zcXL@jyvwcZ*PnYwS@`@oO6@ncIgNF1v1oX?PgF7mLQztt;;PhK7zF z9+s9Kn)s2J!sSff+`9c1`TWFm`@gGfd@YP@|3!v#d)Dox zdwe%e|GhSCfcLpt_tcB((n>Dn_nQ)Ed+$o4;ZgYf7E#u^chQh1>@aZ#D?c`)L0csj zawO5MO|0PRt>>Zb>1m|r4aB&+{ow*NvlDhbnR=Let8VUq3|_PHH;ob|{+up1A^18! z3$iHLsLMSCY2AD-zggSG)8axe&N7~^Qrf)BBu$S3_HQOdaRB?y)KlB`;9u&s>39~K z)kMa!Q%h?R2PgZ|ULI%F4UC0_N@NSVLIp?J)JLqt7=jAwW5Q?#tgwOS+@X!E6 zMBsgB(`YEjPl2<-B_-bpZ@-pWAwB}M^CA3QC6`ay7i*~&0gcojo&c#(s-byrbXP9% zj+E%7_)g-Aid&bK$CIV$-C$Ib0mdH>dq0OvFVWUkyD9*A_vM1w=jg0)ZDwhy>F4f& z&}*&GW|ITuRmH0@bH!ymA0X(D;{NZ!etGT{OVRTAF+*nf%ifu(u2{QtlWfNP2GRMH ze=V$whi(uZysBAVkiSSMmOnS*$GZ$fyI-d>phdqJ^da`;D4ZQwesYMGL$;5wRipa; z+Uv3d`OhrW%$<(!4Yz-~v*-Fh z7LWCLxKKz_Mzv5WB&2ThDl^r8PEJ>pK&FskWUj%Kp^|7kE?B?M2IvK4GRSIP{I4yTOH2~%O$OE!sRO&E?iu>AZpO{qurDjf zAMjPF)R~f;iCFY4*wy>cPzGW#+KHIJl`y^dQJnLO90j*Whugiu1n>>Vc0I;fk>*QH zwzXwHRdnGbzFQy4eP>gOMEM(qu)Bx~;~$Pplnt{Lp&%998+yQ`(3fm=Mp}gUwJoHG z+4#CJchIQt`)-yuu-SU>6#a0b z`Bpr0!=km_chLanV10?rtbJPUMNnwnyr^#GGL8xO&zD=xCR9rx0yW@^^;rX@!aNL{ahE$0MCBD9w8gv6L@pc1A!laO+g)h`HU1aJd%#v>f z4UXjrrN1%qb^+G=e<&_~d$fOh*l=rs1f34y+TWB6!~=c~rx=GQOBoHv4E-sqnlxnv z!~_74mLdF-6)aJZ@&YbSrFtC;<;^)QChz-ad%qTda!%%Q=XgavwNV>diM`r6ldO_ybfO#`%7x;r?bx#x)Z!s zUm#Bfza}M`41LIGVj&O0K|T^9q{Kky7#=_Mw>*xZX>L>_2JF_=6C9P* zuRlpY&!&iUn-l7#46E~+L!o62X8fuTd+YiVCINTxGaMW$F;9)n;N9Uu=Sv@(qQKo8 zmLmW4&1gC&h{x6Whj~s;g|WH3M_veIfa*7NiQPKYPZIlnI8I-7lz*|k!F;VPEv@w# z|Cq|%OSnrMe|j(K8{WEzE8luV2f8;LY|peOevM92iehrVvd}|M75!d>`PSdLX3H}* z?3`hX5niO?0$*em6&dNGm@V0S`{mYs+~0Loj44~lO^(3jkV-=K4B#M;EtAV#TuYc`Gu5rK*DjC8$1^n0i+LhBkP;3R$v zO1JfT_uN=rSZVMEC?b5|o!gbx<+`=9`VA;cZW5;|mu^-c`;rKw!p%Ge{i+ywq}OnH znUYe!Uq)u%***tN{{HYdR+#tt5UKh4t1^V_DB~%Ii}j)shMRhnqp-q|P!m%>Un%bK;`P%<2ZoEIb+Cxj4BmSN z7#o7MCx>&lb2ILeyK5KEIx`wg=pj{}T?Z3!f<7+~)kcHr<(kVYGoo-wiYFr4RZCOe zy*ImckfVNthCpqd(fQFY=s!%}40)v`xI0La!x_%i<9-{@(-yTj?n#^yt%p#8GQS(G z)G=Y_j~CkQCo^dC8GHr_`B0>fGHJD$1ESMxtJ%%{{r&CjG+C7;=#d=xunhekdo8eR z;cWGdRc$B+_gmsne=oISDBCI@7{MXYk|wav#(-i`u`}^wf%`}n?mi-pnFJzV?RE=# zmG!VJU1}7AV|5IEn`{WfM?|r;*T^w#0W5e#=$dBWQ``#*FA`6O- ze}3}U@JprttB#Yn@%icGj;`QyU*JSQ8C2VbYE5(d+0$vI=i)ke@+hma0@@YAy*!%_ zu3aWZeayH^cQid8IngjzPGAUI)Sj~acXe>ObT@3w8nPHb7<6-XJ4FRuJ|QJ zgO+}U$cLVaX>i(UcFoJrLboH&)ktH+{e9lxxCjfZSrgXtAZ);}JfbDMNg0~U#BUkS z(Ip9H-5n`Y+$wpxD1&3hQhzZUB}{hU(MbwuJ)yrHw+E(7Lv($_iquYbA**f8PDDh6^Q%@g?5fmp5@D*17vu`HA+v_@Dn`K7n*pFM)FVD6H2a!Ohz)u zg~|Z_yElUB>&4cAV<}m-vW<3v{0=e;luKD}!>u&Dk_9RslCn6ao2nA)-)?7Yw!)b} z3?wvUWNlG5CI6O~(K-3;&Wc&~2V95sb!M_!#y;=cCiwj=t~z$TcF0Ng`*Ll>JDgZ@fQ9%bMrc}hsC*%QPOqE3Y5?VAz1rfkTZF>g@iG%mWZ>gIJ5aIO z09k4Ee9!d0HtkGbJwS+PZ{IGApdg+|q;8x)K zFvwykY9ySSX!_UMb#kL!-uYqBt@EMd6&hO8Z}P<`g3<^H*rYVXkN@vBwfRzAyqzqCvj9+{5yxCIAVca&?O?K$08Qq3~n;#pamE0HEDsiLlH#s0hyg!0C+9x0#YZi_gN8bQ3L#rmT_kP)xHnB%3U zE3Da&o+%q^HBv%6B6?*MeomLhKhQiXl~>~XT1-s7ySiv3l}7BPxqUO@G`>VTbbelZ z2Y#%w-$6G_@ALi&S!KO3;iu@NyZJM!RQad@bvBKFWj0@Xi)L)Pl7uv4#KcjcxS`3a zCeU}qm>sJ`v6!$c_Nrmwv~-HXnUk1qHypJ3iY|1Q31d8o_n-^)rnYnl7j- zBEGs%7M=e;u6XgX#C zs77+k6~(Q2p%!@mxfEc!+V@|x-S$X@%zpQGeV#(@ZGNZN<<0EhAi9M@3Z+byrb!8y zj-;|iMiIc@QgJ}3+!OhJz=&nyI3Ya2{1M0W&&Yp835NsTPam6y>YbC`kTbnO-I7u8 z*04CAgdEm#{NCRFgMy2+uddvmR@j;2laktf4K}s5MyAW)x$xh7sYDZU-YhPWlMv5E zH>0rBT2r$(qM5_2mHb-lr7>OpXSsMvBU7b8ksMtf{c1M<`#AP|844DF&U0&e)UE6g ziKg$NsR9qj`ChNSn@Zl_5Z~qBT>{HdQp%y{f~4lrnw)ifhFOt#CSc% ztP67quv`Wa*tIZBbXWa7Zi4x-T!2J6jBH(*>=o@t|7oDh9IsooRh6ELmFkiHAP4{vWHdt^6iL((lslp+*Kz4 z%Bk-EH7Ty!J%_scvHW^8iZ)pLX)}lvYX$XDCF3IkmswOx+N(!Ne){imPqIN`gCoZC z4!ps|Qz)B`>FDN8LY$JqgDJh}?-a<^ztH8J{y!M0s4g_GqHdUam435%cMp(hA`$R# ze!SZ6ykY39u^x`A&}kew74QLRkc|c^b8=OtgRUG|_HHaoBJC1tURC$UwPgrM2{rrj zvB(3YL_6jgSuj*)gU2mGHzYpCD+o}KNI{7OPDt{R(WXs_l6$0Rd`cMjL>t9gD|GvZ z{BYu_Q(HLhrLst$E{JInAi`Zm!R{RYZ$OE2ZNyLa;$QfxkxmMPLcUilCC zuGw93AQBp00UU(NuWN3b@`p#%6AcZ*>VRBGz zE+*EJ+wmRjYm8LKwGeqY5Wb8!Wh^Tmeml(DoF&04{gM2JK-7b7@S7ozECrneP4X5H zG6qT&7{|wf(}>M%EM+57k-ws>tgJRazpy?~J@=ym10Bt)^XGzgj`Ed7rz3i=W2K=u z3Mr@AA_V}M*m{s=Wjdb5!^!DWQ*1Un5J|*k^RmV46(g@}g9=tuoQ#hadK{aboZ80w zqItn~?sbT=XwYbM2zh^_^{sIq#bu(6DHl{Z=BmLL_!0<}Z2STgnTIxUcl^iaQ>(5S z>-(D1sBithrUbWiA3nAXOnBABN&Dn|pGtDbDb{@nTo|6?3xIBQYWVf1pUhZ^90uaW z6bzOZET(p3O+}6cr8f8?@<2-5Ue32VD@QMr|Ikgqf`_qlMf6L zxL>RF7*EUO6Zd}gZmCKZv$ZQBiz3=CrB@9QwEP4WH*TY_Sa{~DETSUXFBXjY_)nMG z*@ar*_>z7YbKuvdTSk%nBNe&QQ9SyqDvrD`*@(8}X?w4WXL3y9$k7oILNx|6&)23W!en6Kti)SY)X>2+*WCM?#}Rf%P>rpw>9p3Lxn@j<6K+!xF%)M~RSlvHx1J?!4B%Ubd!kge@+>p}lA)@T3RbKkc`-N` zo3e$5u$JpJOLSUVP=7CsH*#WmWcMRh@Qf$?--aoP-tPrjMpFDGeBQGyNGWnI`2cKo zB5GnH>JA`qaU!Lqr|Ude*?wC*75w3*)LK;qe!e3H>?ophz?0x`GJA1mrsv-r0NdO2 zzTe)h)U1Yr0n98}9w#LzL|iX3RWCFD0ay$~KcecK+@hC2Sy8png(AbOV~pi_g_ zC;t{jAw!+#j3PWf^5%fb1}th1x#a_WzValIj*59 znFgbNoAG3pUOJcES(f0dz`6S*(Z)qkuT)f9o6l=(zLb4^UpWKYt=P>aPny1{Z{bjv zFedp_KV~qT9YLN3y5+OZsr!WgN@b{-Y)GGcOsz;C!tqE8%AcG@H%|!)c=BxZyb$G8-#99*Z!YC(^k_tutS`&o^o%E1-L zoXMX$O-34GAs*e{P~Q-zRiq0R7gut&HbzFG$9)_j-%C*_aF`6itTUz=9w>IMfqU7luAK&}>36+?)&F;M8GJbP#;Ysli)S zrx$SAHgBYGI2|xHww*y*&-1|T7d_zy4?TF<0BMK`%B8O7k-pCx2iWq2o)++Qxskho zS^*Qb6Ky;k0G0;S!;n}O$I#&-yveakAb*@Av$#%R(NO=lm84lFs>ck|=YS$hpr(6o z(Zm!u`!`~l9qoU8GeGc~rzx&z2SHbJ$g^-4Z+cEVDalhobwBRX`T2HdB&XezW#ahj zf0=%}Q@NgP`QR`1)A9|i7??=kWq;708s}rPm^CQR1435#2LS)`Y^-Y z4(JZ*86lp6?bxg)GDOqEp%MkCkUP5D2*QSr5nuDJ(JkoIrKm=QXe<$-i($R(<*h;PhMTh-P|00@%^D1P@hNz?YFwJ1Uvyv zpxI?rJ>-p_zvqRWm6vm2b=Gs|!9hFNXLfeB)$`sK_44L;7Kk-|SO;ExS?!*czz5al zeoc5n)CP7?x;tO>-P-aSa|_z&EhHit9!s6QOi9<#frEqnmcj3bUN0^o!%=zjzloif z174+eBly%K+ia_FmpsPlxqqNO#S$I=Ue)u^oYbHf<$u*>azG&%LmYH~Rp< zjY>81t|G3jk=X8z1kz%;zW2>h>>!CR<~^>`3qppfZXAGNdwYAUzO2^eOddC0oBTBd z0)cvng7|}@MCizUVBaDCP*G5~&-3^X$kZE_VQ_h;#O$w>G}qVFEz1B+tF=uWULYPm z^@6WC)fQE}&qkc^6<>k%jg_a>)%jZvLOT;ih?nd(7$s9$-AbgAtV66ak?`lpgE|a_?kOufn{=T6qo!YOp;Eur zbicH@){KjbBb~=pLe%$i0S9UnI5 zu|pJH&BG|#x^?{T9LY?6c^>$cL;KIiM4zT3Zxw88h z^?iSvj>S+qI=tBcyv19)`qg(~5=eL)930d8N3`5W0<@kNSr&rq0R)PTOo;;;S$t-; zo;uIlV!^{0IqZASm=T-k_q4?SsZaOT(+uB+gGFX)w1QUp2NG5D*_N%MszN{mH2j7O zza^TYtwTJuwgAc_^{jnisB_6yN6%#$m*_UeRjZf{U6!J&4=QtGoP$l%kaD93oH z2qI@fn8a5enJzZFCozKe@R<>uUB0iW? zhOQo3a4n56OORUcuoer1ae?Zcr6F+wGhvzJ2+d@9={T<^92xM4z|KZR{2bf&8%YYL z$jZ}r!Blb3I<*Q6xwBoeqM&#M+jRPd+cj{JU0j*TYX}@ly8&sVq*i>Dfth5f`C_7- zlb$Fag2(ILm5i_!|ZUTU#_zG|yTGi_7 zJkqf{%Qz49L4@!gHl|KNZb@Ojr+T##h?u~TFcPe>_@-e5u+w2>xk)HMGLtG@wEs#Ajpa*^-YhX!F5hJC^$Cpt3#>aCuD)H0WzuH)D zZRQ77(h(qRUCyZ}67x6)Fw`ZMsWa&{U`OL7YcRR+ClO3$@H^Dh);ir;w-5ggn-shU zwZoWsKiyaa5OLY&VX^dzZnWx;UNX!93kd{{t#~LkSp1i)NZP)4H=$Rw=|f;3|Cpep z(Mz!=#o5l1*6Bx;m5pDlpzZf^x%wt7>$yW0{) zL49SFEhkx?5Upy%{>WI4mRjY{Fbz9C2= zzbX0G9WFnN{DBOE=@n(MkF7+xVxLER3pq_9-3CTAuvhc1eM0Egah$(=*hKb*{cNO0 zxz_B`+>uS$mmiO=>jHUR4E2taSwqV5-(&YzeG~aH5Nna$yavuMDWzC-1BS*m8gr>{$U`j0PRH%z_gVx5E5wy`L+t}2xfm83u@iqe z>dAr)=R|H%9=hq6GSLIDM_y_KamS&UK51qN>^HVVc&wI0LOVSd$ z8xv6tG&8p@ciq*tmNpjFww5zvg!?Np?RlQsTu!>azNAe#&xP1}hSPZx3>uaHPG(jk zEXdM;rIpzX-*#M-UfF)9O%aSr?D29*3*dQ<*IQi=uVI1)fYWi_twEL;@UB7_`ui`} zJH4SX_Qb?fKE%^ih{{Y9)`IU06$*OxPc%M-@o}na7{c{rp2$65IpgD2fP`8jzNk|wR`~Sz z8e-Um#8$P7;QFJmMjry@4lA7~{Ft*4uVv!eU?EJ1^nn%~0QQlf7(Xags0*Ct+wd8^ z+8_Op=iV+*v7C4%9b;h(BhujAw!~V#)Js^?_o;S9zmk_XQfudnF&3gYU+&)8a&47P zqwR4X_3rL6aKc|!V+@%8hzA)|em_eb5^20bKeg};_aBmQA6xLg4Yg|IK$WPIKRx|0 zWOqPFU77v&UudIpE;gew!0Gkwr@nWFPEMZMjnk#yW91RBANV<9ksNc$f(lUU!>B!3 zVBSy8sN3&X_N;1VywO5a&J3i?$o^{h&MnSw-|j#-k1!fl_0k}@8l;Q!#lzJat%VBe z9ZZSVQw?atOad7>e9q=9AOmc&8G(Gy`BF9Koq&y;TnCAR#*W(xX5Yur&F77KpNC#j z!K)#l9R`#ecr4}b54`e80ogTxiQ%gBn})HWI7=H+3 z;a-)DJc{gE9jpE7+l&1 zK9wTIXN~%{kMj2VxHS2;v)I35QT=dLhOhe}Wd@ zbb^`_`@(cSkNy~h$QGh;S1tj;xto7e$`OMtMwvctzhZ(XT`U0H>6 ztrgN{1b7-sRMT9I6Wlt|=8P=4-a}|Q`nINjt>!1bTQZ3RE*H!z$2eJvB+_VzDznCJ z0f?I#ui-d|g2;*-a!-8q6(h@VsEe#>5D`><2UVeYh$sE9aw@E|{A> z?Sex5OM@z8tbSNMet?|m-nB{vwX6s*m~rk!3vFLmA57IIUN6KnrUR3vqBiJd>gZ|0 zI!B_G3UoQ^3%cZ##6osvyuP=i?T6gp$mwrU*+qEZrZXi8#-hW7Cv|KIOCAy5)>B(8 z%)Pi77jW=@(jcu{>*^0i2Z{hMs%s*sznVH+?4O08Kp-_prnB4PiWHt>;36o>FkAs2 zsiZ`6f2k>XR-eyx9wT!*Aie@urB?T^&F4Xi;!MNVjm)tviYOWn9g=lB$Cg%Vut5O# zu|nHx6lJ7;PZVFI*f>y&@P;y&o#Wnh{&uXw3Dk0?L*aRylg!_oQ^Lc- zkO+93AJ0@f88ojX_4F#fD{EMLl8?xGI*w>k4#$=w=9V6{x0(KAicoUMibYp!k6a*Yi^clW4m8{f6Hb_=w69 zPMsPPlO5?wQO-4ixiZbw4PW(TU1HK>NCb;1^C-$`On}&ptIL#>@NaIN&SrMmdwR(xA#iwY%phPW!r^A3L0DMnl#>0z#c$*V82ZYPD{!&jt{) z6A__Rr}tla)-gQ*^NLI<=L-ScUhpM-Z4TO#3Lz;HD3fCa#sKw+nL#`imajPvpP;!! zM!_H#9~&1BhsEZCf4v5ODFN?#rpzG@X0HpwHExdFFTWmze>rX$Z;{@# zy$F@vceTiZK;UpDp_;)ejIwhMClHPFglgZ;7J!aWwz6&CsQmj9J$)Pqx%wOt{yMI; zHT?Pm1eJU)zS+jcPSy2xy4`G>kHsIJ0DC{gEi6QXQJL_cK0tU7Jpj>k|74w&wzsE0 z{f@+EwvZ+yau&i!#HT74p?Oe#P5Rw_Xo+fP+HR3N@BDW~=88qCom)L*5o&cJ7}ls_b)5gd_?c!&{{kK|c`SLsg)% zR6IVmcg6D3g8Q(C^K>*pEFLnN;_J{dVXE0(TYF!8O9#|$zp}XE**uFOZC}peoH}tf>!89NpyEmHzDSn>aZ! zlP=P@61R19Y~Y7eBg5A!uTog(!cPYhQj^RE$HF9`gLg;nnF(v z@t-GsAF**yKRUs789oTg3fA9iIU1NF{2V+*ziP+L)65z{@w5YkQkl!kSSuE^U1Fri zMx~^r?vk1|ruXMj?tUktdU2A&&o(ruUL=cq0L30WBBH@UNzHtM9(f+PR(5$b(#JiT zYR{m^RG-Z;|2q<;y&H8u zXCDV4Bx?0YhHKO!_+hKKh&;*nPSFd=GY7E0fMvLk5gi!*K+yKDnRsGh zAPZ6qUoE=xPxu37@r4w?lmWLgIo|&?`slr#Tr3|KpD^%u(E$+Dn0;GxDqlUEa8j%S zhMg!^5hf^eYDS1{Ixx>}P>lag1rmIMN^b-c+-@t1MBoU;%naxxsd*`FTlZGQ>G6pB zuPRfvqLAlO$PI;{hRlhg1x1re^U~d60|8Di*v>3qv_!*38Z>L^~!ZYTp4$(=ni3W!e z7esTnIgn)s!97udZ5O*BbR`w63)?pKv*Y=sNG<6R3Q+}^r_ACZdZJG+Z?+*}S^h4wJO;LTkq&TqEZf2}xuP60bFbeN<47c5uLt=H+Ui%grM7@SRIIr`=}jp;E5 zZYUnR>DG`iF%?*PFK;DR))Vf1XH}~3pYF~61^zb9&dWE-IE47p{@p7B1Eg=B_V)0p z=ifLmjw33stxyDje%Y?$pU0=CBw3_a4uh$VcMd2Z@_Hk{LZKs2vvbmeOy0|$x+WU02%PY!9MCub(ATF7h zq*%NNFk@JAZP;|en8jQtwOyAF-F-y_Q4c3g&;;i(!nUu` zy05qIYliai;&DIZ8TMb~?$lGB5tf~!l{sg}8$}<%vz8AX2{?(Nt-#+l($^o+MdR|o znS9|i&($7Fy8qE6&RCpTL==e)`kly?Elya#g-pNjWFp2Q0`q;;N;wuJkB^T4s4XUp z5fh7u7_X8&CAkTTuNn;4A*gMMKMaRa2C{#vIRgZ@%=^Hze?4FTzPn>pzf6raE-s`P z?HvU=<=%JBd+yIY@xJf3;|18Q9`0w>2|jtCUJWjDwzsiuhdO{MdgP1e|AMS%<^DKW zsietJ-M6B{%Pubw6yg3Vw&Q#XYsbn<%lY~nV?QmImhT7h`=!KHn1@^U_GFtPJ)J;I z1or&&i2b)btA53u+B1DO7O8^XOoRsMfn+Op_UwbO@Sb+9Hla+RH`^n@t8< z)(jL+ehGV3pB_!b*|--Q%w~xkb&Zje81GIUCuJ(gb5(5-N=Y~I3m)iPQq1~!>P`9D_UPnR*a2D==s=22kKcHT^@B`fV~wZ(-Yr5q82t$ zR#?KH%$=PqWOomQ%$>-!@)K8MWoF_qFS0dZ%s!KJR8+i>C0kXM=~?R6m|BH_B`NMJ z;1OusePe%NqTr>8lxUxTTZww!cVoVdAQe zOF{p?<+3$7I-p#}u-(V?AA@}{7XyWsct2qHq@?O*citd^9t6pro5>?VAV^BVKDBi1 zqICAkq7prC@qW%w7_L`-ctF9YA_-vR-^V?0g6A_H)egMewp#x#E>>m2U_;WiU~JMx z!JHC9=*dUrUKp8!tw8ErmM=@WseruN)GbQ}qNLx_wjWjZTuhe8WBq-6{5Wf%Cd*WC zBV&#EGKEG`Izkbn=uoj^NW~gETpKZKN=%qSOqt^4Z&X4uyf#9)lcgXg5ptO5)@dUh!TU*gxF~N{ROm+MN zh^^7}9aI-B?bvL|MsePOH5~>qQ%wqCaoP3w^Cdot`kIGCqRR37rj0E|DTV6!b8}6L zfjZS?y}kRlLoI&|4GOj#yEvVFjtwdIn|_^Ipn*X|-(8y?e^pb=!w$+P|Ejo5jLNUL zgzIbFH!j4YucF`Rtic)yx;Q1NKT{fCB^5W1dz;2(Kbg(#LcsoccK{5td3bm*>o&uX zchnaAt4MBuCTPfNuOKHI>oM&D6$z=5&RJ@G@K)z9Btr23Fp?-t`em;R#`WKGmm2Gn zqT-65m93@@SyHX>S>0?XWR{)GO^o-PQ(1k{dA&tb&;oi0S`D~msJ?XV1#%SXa*#XK zjZ=ACeJaZ1$M=sT7JQn<+G~J%*U^J{I!DO&CWn_}vq%yiz>2u7pRRP-t(CG@R~EMw z@(FPlE^>+SI3#h&yt)je%UWa3E+xgsy-awFdz65_c=y}*ZjHNu6pHEU(^OgB+Fv|u zZ~)MlysJsDgl|%fZ zH@XUfaC6Rm)bD5dECUHyCKDp4G#b~K*@YF`se}~jtNY*Toxk$5IUyQl_{M1kmTD~5 zoVAy z%8(x~Ei&fLvfS^%_`zf~zeA7WVe`=GP;d)>c=!=C=1V ztF(-K|7y0oRB6=$;hg}tGdrN3&FxQg2P7+aeE;E!!Glr52p9_puN{C^*1n{MJ^jzv$1K@U2#qa2#dndf@Z%sTjIW$Y!6GR$e$q zIyAJafwlylRBPZryF7(H74l*sF`8tj^7w~JT8?!ZY3Eg2AkFF36O&ozS5=SZ&FWuV zAh+Ydklcg(BI&mU9q=4N(Wk9%ws|>9cPAItRjj=Y+|J4YY>WwxkKfD73pyOi7MjH3 z{+JICiD6>`RPElj)Lua!Y4VMAPz#5AJO!EMLFf9(vcfR6UZ49f=s}Xgi(QKn0cg+| zwPsO_l8ebvhL&haD2Bzwb3WJhQYnUSL|QJ^jA>aglHC`RRRzrw5G0%tEl`7pRJ-`G z7YYj)ri_+mv0DOEiu1ViIK{NfBQTF;o~UsKbZT@w_#dQ>5&V$pO7gTK6eDQSgd4w< zjE&2PWqA(!&(W*BI{}=?g9NgT%@-dgmE?rk_*vXMqYro%_ z-1x9j*JctuT1t~;!`BbPv-h+cFLWO}rv@=#z!=n>_BAMmig!BrkAzw1=3pfHru{nC z?R5HW!CYC$`O9NXf~@D~ProX01}W^2@I(1NdF<$>UkjEM%TX3+r|o4rKFumTOfL^) z)-fd)+1k7JPC|EqsoDlB8!1uNUdRNzcaO7yg$;LOy-$6}*E{FFj|w4}XYs;;9>CKw z{o0Bq3(PYW^nLY@#?DB`8R%+b&sk(;4nMs93mrTO3;Rq<>)wfiBi)O%Dkg-nB_kv1 zOd_hhmXa=ukLyJ>2gHIExr~hDoLyMcne6ZWpA-4hx!ma#igR}bVY7BWR6ef8iIW2z z2bNe>d*wX{k~Q8jC35L-pPbqdonz2t-vZ>6Nt5+S`J?R?88sziOlhiMLS0@%iSzrQ)3>TPYdYu#R6{ugG1OZZ#N z(&FbbUpXBc^}-239RM9}G+Ed6+(+Rqm9dv3h$nCArV;743}epUkioqYgl{9ob>Jx|K3RX`b0;HY^Yug%-bSMRLg~)(P+h5YU&eDUPfYwhJ6kJ) zuPXWK3h^+3-DTLIlKoBU@oZhkNqG(!UW_LY9JSn?pJyRVWI`n5b3cy>lSl6y7bE=?P@UZs?jhRmHA6a%{o z>wDzp_QEg}wW2GaX4yD@NcQh#cA~DMB-ALdM6|VhF_})nwnQL8b4g0``d=~qdkJO! zeMhuxY+A-Nz zKb%;~j2UNZXV2J_B5;6=`Ua$hyj)vVX}V1uH~N*0GP(VrEo`!#A2GA_w!>k{vh)#H za=SkQaAIRGPjN%Te*kdQ_r7y0^m?RznCSw`e%ZZZ$kG2>;8i{Tz0_mp{g;z(AW_)T zt2uzWY$qp-^)MafpyaF&M8s|WBzk|`bI#VFq+JU*;Kb;Tt)n9@KC!rB6+h{QWN5n)-ho$RlzbME;%D+#ah1?4ueI#bKb%9tOTNPx=+Gtrt?K2B`Q}iI&|2b z2$J~`V{ZFE z$a)#AanZaZbfsqNxwg*Msk~EwBj zs@9;x^=Ld1omv^~Txn)zXLB=)Fq(345$@ssK0O`V%6g2Qz3F{DXkSR{B zla)W0kzJ){RI4bDFC#w{IU?oenzWjrS1K(ldq++DA|Wdq$vHHL2gUZWkpV%uE{Ytx zLkVG0_gY#VO}4PYT&V}SO$Gv~5b^YEA7bLIP{CDzpw+YymD0R=X68f`i1-?fF;E&T zveO!^ACM`88{f1fZa0e=_^JXUG>L@3j5I-GU*IBy_F8B6626Xu-@jZt4mVBN+9_xy zPz!ZqXF_93DWcWb28gky@?9TqbT^TXiDp zu|usQ)QkzGxZW0oV2d~+%bU{1+9*-%Yyb9;L_t=|9ZbIsVl zr@6Vgtjt4*7a19Wl6R429%p)!uOf`trsK_Zs{uTr!EKD1iXw9T(ckk+lbIoT%* z;)|}fksVWHNFF?c@Jv@V7!{JF;{@N3=z2?$-IM4bd#U$K!qk`Dn>ir`B>QN=`lE;z zPy~YZ(Kl6BG!hpRiYk2^x3VWPB<*7&DpvG@3=0ASZjx#zdZd`L?^b8Bf!Ivx>oWUO z>r=nZmKG{3em)jwPdhuRL>VR~tGeoxvJ%bWGVH@uT-==HIA%sdS^0-CAp_*`LBu2K zo5I@2z+FxnhAM}>6}9f=)z+K-)L~>}{!O?0)Q;(>=FrSM_V9y4@^#VzKX?`E40tSM zZ@79IaEO_url#t(iMu<(kr5Mfh~5{W*4$i6u<7ALx8!8ErKQNs%-77!Pzf{AOoNPU z@+O&4BT*|WDlUHguExc*%uF3!;5QLFGWzh4?%;8kDIRbisf_ZHW`|(m=Y=E2!{b#F zWE!0F<$V#Hdyjlz2O=K3cc^N_q21HHD=$KV?WLhfe|&6M(La3r9g#(U1G2%vMOM~P zDb6=uos^A%he4$2h3bIhG3LKgn#K3Y%F83Nlj8f;1 z{xG_AO|D@a05|Q@P}#B&DBN;7sF|DGYFB#@DvQ ztxj22U9XB3-g0#Uf@M)JC;toNYInT?At?_VrLW)d`Qi!-R9%9sinlJ8c`)*bQ!sL> z!_ze1s!=F9s=4i5g{NH$t;4Mmji~}!jgvF9%V(;KTKxPun7Nq~E$WoITpcqL+6qYW z35f$zQ6Y#$=xAsP(tZN5G~a7DK zMiGg^3}8VOMfPjq(skEh0s%-_l&R^pThbZWWX*1In(=#rA ztR*RkbQ=(+*p=j#y-h7G{q^(=YJC{{6GWv^a7p@0!Qv8A^*4LlZjYv-;UCJB^3R2y zCS6@y%N=ef$1|r+m8WNBC1ybH+X-yxct&BtT1f*6nHt)0@^cwuN9@wmlhM)5?_MSs z)inM5Xt6T#m~t{{b8;E8avAe-88fr#6)EISPvp=d8!Z~mObcC23+-$xyi5zNJUeIw zdlq)%iDZ?TP3A~?X=(NeF3blA_Qzi$m3_L4i`NR^Dp- z_nwuH9^K2)tZjV8w(k!&(Pc=e93rxew4Zg1*-575!4C0v zZ7i_;(^*XM3x-z|c{8A4VydmG0#wO+&9>;I%=QdhGxPKF=SyX+F+bAG;j8=iHY+S_ zYV=4w1s2{8Ho>0uW)AUhL4`WcON)(v^xt~BbJ`k{+PZW4np5)AwDy?~;*XC9Q!!aQ zGiU^TSGnRRV`6^ij2{8}|?kg%v3i;B&s;sP7I7ARm`VPriQ#d6bQ3z=i$bQHOGvev` z=)H-MeExg1$rF?$l6GIw`SzGnOXRQg_XM2OWGKYte=8FE+PComG+Krfhb}i19i+3)1S7{WoAk+EG@+1|TWxWWvIIMMaHueNIDRh?lE1hgYV;;f2y)wKdwr zbRCym*B5+uqe+g%C0kc03{2BQAW~Ot8n%2a{Gcf!vXCSaM|A2VQv!;3smotj++}e(QBbms4p?!?gI~P)AlQ*cd(f!>S;J7KbS*P zBV~loj~`k_MxT$u6#{zG;bz&G;&jD09Pc7z8tHMO<1 zwL`k7c&Q->18C>#Gy-&UsE$9!tD$x&ck)(%Kubn|fD8->wd47=%gy?wMaK2!%W599 zr}{A#CiY&Zhq9mF?CXP}^=zK>=Huk#aY>1ry!@%Q7SphqHXA$hm|6PbQrCoq)sv-_ z(%E#G+t%NJC5Vo;K+JzCT1GozI!dCVy5B7?pQZ=zU+JCPb9vlnu8l}+?zthdP}vd0Do&(_z6r(In?ga3?Y{WGDnF9zj+_8`Jpl( z^q0GP%M#=g&%sYYgIIOi{qZ+4V^^>;INKq#wR$c=cKYPdfP&?{X~n?$RB;toO?8s9 z(QJ{3MQwo(h?K;-*)%* z;9$|m2iP~WJNDk$sX$h+Tu8m1c^h)2-8$N#sgN$Nm^`KdgP2c3+5kCbd-4`dwTl3j z)tQ`cf|qNyU}*9>`;>F1G?Cj7vvgTnOq4W(pt-v3`ubZqm%!NE0Pg3}+A6(M;@}%N zecSh?T43#5+K%kue6PIcZt069WTI$6gE?B9#oO3fweiu!b zFXD%ZD2Tzp>7+hA@Gl~nZ`6RkW5@dK1Ztipp*5>$1J-)WB^sQ#t zKtP-}%I2kp%v7jOiflpC)?^g|MPaPFC zS8fcq2J(g6ZVpNu@3<2v$OPh1o0@=RIqNb@Yxc!xC#=6&9C7YWYTps(qmN$pU8S^S zw{C*oX4fYN4W0*T#hK5dF|@sRzu@K-t@=&aJSj7;lquez8CTL>I9@zW0!>1=3ytGONQL*l_9B(LE@y=4Nh?LT%+M9qOMlvlF^h}2-t%a zb5;mgq;ic9^88e7B;v`N5E2p^%@UJ3K0B8E6IEL^PGY_RgK$^}ay>$Fy7uUvR+zI* zfCACW&b~ClZ>Nl#w`0@HvtTUK}3YAk05x1QtH$&U6c z;h6A%cdA-T-^4$MT@j-h+e!@-wl*%NH9O2KX;<2cj8-rY+xBm52|Y5PV2N_RsQ1(@ zp$&Rjaxt*F$?v8q(dcZ15!A70bVW()i}z}xqMsihVr&%&Yn6-4`3una>kx48@Kck` zPW9627H*^{C zLW%7a-+H^swd9($qGRRuNhx4Iuo+>QvB?NXk zxzo$bY1ZpWb=BE*wYXH(*t84;v~+m%R9Msu1PpX|a`NY*+s%s$OsWe=jMN%cR0kU3 zBTs+yvt_ikx1aTT-!jtD>bAthqMFDiK$%+>48S)|dz06HnW)q-Nzf3dq(CXUKw(?| zlox-J!U(jiNpxw|;*pKOG_vtdG)3E5xzsdAPjf^guha+YILH_PG)h8}G;Dix|Gf#xuh#ENv+!j| z11`Hnl|kRe*PUQWdkViBZR+$5%|<7ho-zFU(J%?wxygW-Rj*qqF&kN<#dx(eVehJb z{NtO=-ux~w$l!Z$RFSx#ddL`%r%L`EM4X=3m%1IwXFGUs3os2H5Bj+N@M2>v3to#~ zfAU8%iCxTrPPVm;Y;N9YZjO9?6*}o(R0Fmwin+O-nwq?rn7YTuna9TsNl7}kwojK1_+7f=EUYl$0D?WX4Hk;wWqJrE0Zv(sDb^h}!ak^jIjwP8 zz}jLjV(CfE8e{eG@gcC8;8E%XHA~(OGF*&y_PYk2BTi~ip0$cZNAX+aVjcULe)F_n zq3@1bt}&r`-C0pO!Dv!F*YSuj#kWbN@|9^_*k2%t=$@*o4c*M-Ts%BL_cqjmjFpv@ ziwEQp9q!@c_VyBJ44hwgxOU)!VKpW#CUtlF9Eu8ek0Iq@vi+rm)0N89ume{&Bq3xF zX&uj?M5(t~ujM6Sw9(Ru(Pmjgi-h=ab$h7hS6x#m<_)h48LXx&(8nIvlU>T?tsqbN zq^GYsL31mEu&$rZo;5yJ^rvi2L>VH%H!55@pX>i%w`puu>PUMZMLOB95JYm5` z6#s5$G-%umhog_r$d99`lG$`lDb<{lYBHh@5V+dW@?G0C4wQzz8)pHN}$8e z)g6~ePc|Kx{ci(Hd~aTsSc@Ex2-12-KR+Q)Co25x+zG1F)28oB9+*KFHe_d(m_eAO z?k=jbR#Kz;^CY0c46Cd3QN(B+-%<>zkQI6=+Y>(!4zx?96>vSgJNGZT%}Os zIC5keg0OsEXT?Zxf!9j)H~!t%4`96GKXL_RzCd*>s|Ar412#R3nKaw3cGLm-K$yk( zemN7@8!rMJB0&Ss5_Pl0n4dB`XUXF2Hwr$$!o% z1=3$k_PYrPtIEp4gBN%C(SG4wfyaRTtKptvQbPA1BxT~z%SF!pWHDM2%eSA97m+Oe z@0WHu4wk$&fPLZlZHAg6xK9Jd3)?VNUOwM=o|(_e(uzONh#viD2SckFj`@wArblpm zu?j>v#k^*}KG(rsMb}eTQquA}Cs!@w_?$8YPxIW&95t^-Q#r#Xy21lI92~s6V2l;dFImW78f8Oc@3_`xppT`diKde&Ri0f>|; zO0JK%mPk0WGgSmS3RCoxRh4wGKJRaD9KH%D7BRn&kHf8d)b7N|)BB$XBZD#SaBZ9! zVJOc2_j;RwPONlco{a9U!)nOl6pv{~rrv2B^=D!UXf!CKC|Gl&3u zCJA)Be+RN)=Ijm+V~7!mzR29k z`XqSYm2J;0=b&CiA{N_10&1v>B<(p(A5nL6atsjVTwH8n{Yy;d^Xd50u~XC1QnfWwQd3W( zh3r#3A!?P&Q*8-*H8`9@%xeoh;r~SSf1~YxX~Jn#q0?!2vjK5m_(d~BJzSw>BNdz( zotRktj94u@KVDlsj+v@iJr2>!FeD%SR{J<($Su)F#T|rC-sbRdGj$sGT8rFnaE?9@ zoA@60Z$+9=fk_orvML&e0{gA{s(K_;@m&galQtj28&^v-(3Ahe~PiP8R`U)(b`R22TqSpc0I=&Bqc))v6=Gt z_dVh22nsbF>SmwN1aWp|W{{<*si_WQx1l8pbxYE;B^Ue^l?2U>>bA~OHXHwlQP zW@nGRF_CqmEX|R~BeKet$;!*iJ1RLUDib$msU<&t82WlI_<~q|r{&%$F(%h;F24JP}W+m@{J{K|Z0K9BxAT^ndzM7iYJVKHdL>I^NPi-qv(j^rSpI>PjAV;KP0-n^a zc9;I6S62)dNhc@AmX_AZqz*uF=I)V{y0l{nnh{Zh?XrB;%1s6I@xMfa<&M;N`WR%OihECC1-J1mIFY$435S>1-IHZHQcP^S4xl zab_>?#1Kj#?<|cGw5G_&O^xD-vX$h5j-Gz#`%c5mRn@-a*wXWsQ(p^J_hHr8_$30$ z=0=#zD+p>)FucyUqG(J)VoL2_*B88?ZtGeh0W^@cjjqGt{u3^C=Eo*FXt!z!5<8mp zX}$IJ?d{DPIyzT|PkHu!?-b9=L2D_EzrhroTj2b0#f}U3AVWw|7?xl8$0Eq&j&W0p zip=8XKLFaOX&1Nz=lC{ubaLioj1#geD5z)us7T;6jpP&5xWv2JaWeCX9vk?}$~kTAjUp1g&>@JZQLL#+s?tQt z!Q5}OJ$-C)cBJ`3caTagH2G+P(0kI_laC2^fim!&Dm$wUTd5dasj{(N9vxxOM*YnZ z&kX3ZwmGPwSxnf;4`XQMpg4kD|EJq|9?GfbASu^OBr#xvF)I!lBV!6`s3GY$K}Cc+ z2&VRuWP857>-$!}gMXM)Su?mXw3?k9i0}DLX+bBGt5Kf?bq0?O1+gV?oy0SBC4yZy zOC6GX>TGDu-j%!q#Lw;Bp>24PT`5m!X~%ct0#d*Ao99_!c&pRi?#6~}p6cc8?O1*{ z7p9u;aZSGg*Zv1lAT-g>{dB+cbU41oUw_oGp+CGy<1S6)7vVLXttClO!sw&7@)`d|V$nDF!C#-qQi zuCAa`HZ{`!X{po3qi(79pXf)zLO=cC?#=*o_&b*gh=&fkCU=n!CVoPpBdgnJa;~+fjT{zx+h!agJO;bRV8Wo%-f;-|&U4O*D zJ0NJyle5uw0>jd=0-DQBqxd0;- zL*dB42+p2=Kc8t|1ffQFfXeBYmPoQkvFCGO#M4s#r@N%&2rxvvy0ZhkKw+b!QdW4r z68bPI-ZnPnK;-I>8JSgdwJ)KKp^olGhq*T(9}n?w<_h*6sZwnHBcgY@;7; zcrVI(Q6L7FNT>C97;^-o>9xC|L5$ACE#qI>eH1-ey7rRdST8#9c1kgEow-+SyeG+5 z7&UmZco5Bn;&H#FVHCeuIb6?IPnc1y&hLhLX{nY2wFsBs_Wfve(bS+>tJUR}mX_w| z=7K$ffVRe6?kB#;-$eRxUnH^-f}o7$S>Tj-9riGxGviKQG*NN5+Tuy){~ znYZ>yqyS3>XQb5B7gdEP;HhFoCF7*QYbZ~o>qx`iQgI9bHE;w8G@!4W&}_jJ;&D~1 z1~06cR2d8@PgmTq>#2CLu(SmBQD^}FWRBhe7SeqN64=z~`c#?iZgUpsnkQHeDwn08 zpg@r<`{ISphIBN*BU1gm%@!n$C(G!iBu7NglDiBPH*9cM(5{qX;@LM$M3(i9R8`kH zW&5_F${&)f1rcMJq{0SVGp1vI<*b8o!3R@)v!_dRGpqVOl6mxCKNswy-%;&_i1-~i zkD9(H=L#(ev)F(^zAP1kmeB;6;K3;cVzrmdw#B_k~vozlV2-j=jIXj{#>UA6S3#Jtzx}lM+mB$E$DUb=GJ})*cJorJMl+@QcnA z9bvrvn{ehlbuz!}hU-C@XdpE6R_Fq>&SF{-a9QfUKs3}kS?cy&Fi>C*sLvd)e>2op ztFB`9gojp@i!3;cV&F&r)`Lh3vDI4qfeZ2*@6@!1lu`sSO$;_qd7gqde}9|5?387C z7PT}{Z)uxbPy8W%JR6r)Y|fNnC<(sAdb>p=>NmhS#`y^bxXK$4<2YBxVyW1aCdiicMIhPxLHNK5*wbVyD5gq(8yfaj?GyDx zbd&-O4G&HeJ?kag50{+hw1x-%ksO+g?AE0vd3?ScPOh~=C6|Ho&vPAw3(s~XwfTS z$n0Ov&jIXgJ9M|4We0&jvACIJB|9#otbipoQ@D7#PmLi|NWs`Kw25>u;(`$Y1gw59 zd9xw7DFV@AIE2niZ1o2eE*P&i12QutT!=tRIXl?_6pFNgQnS`YZ z<|lbmm>*WuE7r(KlxdqWYa|VJPAz0r$?qie?L=cq&sOgECWnGH0%}lKCW9b!3{Pm$ zjRy<7jDZIRnTBNj9?{SPc|R<1$p)Q=Iln2)@0Fo`qtYdqdnqEvD?(?3?EHKh)onUv z)$CDvQ_VOW4Rhjc1xtvyljwL|t(0!mPoH*kf$}5*?DAl|`fEdD`k0uQZI@$}e^>PZ zt8oXH2OT21ReCADru(h-f974^p$Bgou4=R#DJraxSBuw%n!ot|8n@hS$aG7M{9qc5u)E0Rh z#LbI;2|-8Aeck7`KIk+p^cN(k0=B$tN<{A5{@lsr6ld)YYRaji7S%HzoRp+x8f7NK zqEHYi=~#FR1q|E#Eh_X(!Eh_*#__BeSSxPw4#XL%tIzl6U+ilJX%DA7QIL^&v!GB4 zoj*a)!W4)jR)^f^g3K3e zxF!Sro#{+Z|4e$k-lgX?uV1~}!kOHGSSt$s@hRBde|zIql1PQm9uWyU6}2{fnR`@T zX_90l>sISTf`NLN8xp0Cf2KAB4JY`KwJxf6Y@E)Ca}fQ6rR9A1+>TVFD`!UEd_&z_ zK(3uH=D6L)gT%7v?1YrVNi^6stzC_0~IRg|qgn9vXNdEKA) zH4UD2Zl`-5cVk}u^}Ig^L;X<5+m)7No_vnF?2Brx{tE*GqxHOSJkQp|=H&DbVnSn2 zDCl%CLf+x@U;|iTFc)_n1ud^zwO_7mS-iO9z#}USX77e2(pXur2K``wvwwtBczQWNyeEUX~L24Df5VH~{7Asu4hfq-QO{qUO_HjjR zFiTcO#+xK>GP2xrxO=dS*V;rpJ?XBwIXDJfoi09FVnkeqpv&X^oif=d_0ti^%<_~b z3%Uw)%{cj0q-cp29h_r+!q!zAXuzaPmhJ5)2kTxqSY4CjVZiUdGJ!t0anf>-DGW*K zbUFi05j7XzmYMfE_fGtncWGj6;&fb}nVVw=WcQne1@~2q!CStn7#%%=?ur zTHqgz@{QQl5mks!7?#UfdudRb^lDk<#J}hx$C8i1fnD$%PzZ7MUmFpNw#gldHCat; z(b$_CP#vCDWqx$N+_8Kf*OR8SEc0vC=Dk4#RhOpZ~@PZwN&K@o4mM=MgHRImP zNKb!sb>R;)?+Y7Vp>ao(g5s=x6c*9e277xv%+4zJuuRmVNLHD{kH8!oI{*?UQgx`~ zb)m*Miv=7EYLqa<2$^Ej>G$Q+?-ib(5ksgqK$r#H8^1$|u*Yf5=X9hHTi zzdyw6oKS25j^3L$s?^t7%qjBBYjpjqoyaQXkZEO3ApT0uAd?v#-G@q-QZUF`Fu=EIW9TXFSYDB8ype7b_k^1N+(U_0=y~EMzUt zKJ;rPDm&F-IWg97xT|Z^o;6(G#00(aMd16u$Ia2t9{-E=Cvnn>LIeoBeyf9nodGG> zXSm9$sxg_nZMHH^5s?51iKlUUdTpKC|nT4U0S4d+TAwPD5nW!^zcuJi51nx9C9);V#-HHzd~v!m{cGVEP`m_ zM@L7$1vE<$HB#*Dv*WUu@ruhA{6KPxTY*I%TmqqtO3i*kIp!uX(f;#(bRUEcKK;lM zs^iL%ew;)In>FarS#!tt)Z=#_$?0@2iJPRgq`T6##I=#PVm7S-dwixl;6bFOXw>l~ z+}l!OMB2~a=!{%5X}F`)^r^eM+XWlIP}uEEm-9IdyBHb%zAc9=K$YZ_ASQ&`=DqUl z<>LN8Lj;)-U_xY;b7Ggvl)B|#BwaLC7=0d)t_q@bi0jb@w$pzHM+@uA%3$C3Vqy^a zcvt(3prB1SQ7p-ILeclk$=FiCbj;c%MP#8ua766|GTR=XqNjS1@HD9Yda$6CH;^~XiqF;3a-y$}wQdPm)66-V14!yRx`Jl9Y)nygRL@-M z3uNh9tivn9qR=ij4e68D361Dabba4YS7Gi1+Y`)NW@88{)MC^xh;*F9LY`@gh> zjd-TR0}bFKN$+TFuuWGHE~CVZJ`po8RD3s<#lreL(-RrqnrVm`HCh}IK`jiidp$~( z?|0+*v9-nLbB2pv4@9swZG(SmlWgCERUcV`EWI-3PEtl9Ov2?PqNW zX6e7tv+e{|YnOW`;2qh0J&p+h<*1{u5C?9n_RD+Cr+s&xsaZ`J6ws*t(?Y z(Q%d3$KZ|CG_UIZv5Mr=2B~u*2gzbaea69QxTQ+D760|_EY4oIB*8b6OL}+KFJAlj zaXg?JHd1~9T`|ZWk(^jOk`EylZ518%`NY&q71`)t7y<!eENY}-z4kv zRm-L7LNusjhW9@)#ha(y^P;n+tRq{Q=nH<2-xJ~*)#GV!tCN${_bX!<`nEZ^&Ob9` zK?#EI6-+mD?jRx#&uNH}ZG6J1j!I&Zl-7qdGvV12Q+X!l&*-I8&oFL zqZ@6IGe2mb4^m~jx||;dO{Oj)A_8dFP)cK?==)tJpOYnyC*4UW7X7AR5l@d>5Ix zw@ourA*KXEB%J4_QqJNQ;~+gSF7D&z->r`nrohslKQoj=Z_Xh;krk8u#rzA%(_uha zJl|Wc)J~yT1c38#0!@75ulVmIee6G@Y7xiqLxWCH16<}`)|&f5$TN95Q3qYkmiIQj z+R@-C!rpA_(615Ks)=6qf0|IHMan?1(*J-i0K7B?`xQ{~1TJTqF$fs&Y{VD5f^c;A zC|c;f^_WAfZ{zly|JXC^4uZVq5APd!Q~r70HQsIJ zP8IAS_%Z2hpRRvxAPX!ke4C#5npe0^0HTP9S zOUTwmpE0ZJwafRiy{fSYGO+i&_U7&BIMnu@)5r$~Brt|aTFj#Xnlk+7P z19`Iye%0iN3#L+Kjh6+?JoN`c1m4{#&s-7eI~2OoUDVEYA!krh9dNG17ME&tfrbr| z%|>rFbQ1nPGWfz|)45b!YReA|bafRIX0=8UOeL2LctjD}<_wT~FUG{TBXHpae-tOy!)-ff2;Z9al z-*!SsSek;duN^39G%9NXIJ#!%kI@d;c?uGThilX zms@MWUq8MXEj!^g7cnVe-1v0KVwNFD+mseSG=-;XK;x#Qq+ELu9Pi!lbJA|_p%@{e zva4ivU>OV4+Yaa@-CwH`_1RFF(aH*9b+KzhUw?((Qy znX{In5qycuGe0voXmn`BVRLDAH9V#~KM?FRHO$?Rg4J+SFOkeAO9A(d9Iw%0KPeOB#0e>NLbLqmsF7 zhCavUMVqxqINQA?M$s&@nQrKNdwWJ&c%ylv9^N>JcWds}$7K)O6vm+$ObbY&;wi z=pVggJcLgOqg!s&Kq~_s9UT*u+9wqdxw^tc+g}6j(9YtQC@9v7%F0R`E31O2DZL#_ zR8S@8gE*K=T(={f(h;?Bbqz8+I>#M$dZPmg^FzVp> zEdpB3_l>}%_1Z9o1aX!|S>9Qb4%?;+=LO8j*BN}P&z++MQ9ZC@uWP(w zTJ35g`km`C`6y_s2wDBCZ|f}?X1S8VlSK?2oQYPM3b!>@{nj3v8-PLj*nr^lstkik z1hpa=B+gSBj7{It`7W}JKmX&0IOZY`JUE25i?vrf@2$=vdJmtDQSd-3H!7WfbFs|xzSA6G&K@D!BNRey7 zXVBC`*{tmO{D|0FuO>=nvXN-u8*rYz&Xoj&r;5nhNiAx~+SIg(zi1)E#9-qJTmJL; z;dEB8*$bnLq?o{^MGknooxPS+D#_{m;+f`yb=uJF9_PjudJpr4vl6fQ2Zc!s6VySY z;x5kC5XkB*silO*R-xot#K`esd)wBE`R19!?7g^zeMWqo{OqC#R@q#3%cxpbpDR!c z&+X*QOvpzcCbTZe|5Ia9IXBpU&W4*fMTC+(>G~_|M2IlrkWNJi-hb5rFm))OP|$}_ z5@KDZ3bDyXq9S&vDEdvIDHaG{MUGUpwY357t)`|F)~S-Ap<+X8YimbG_R-RS38bEo zk+&IgU(L@=pagpf_y7P)E-tPn`xh~%o$X1oAi^I~iebAJpfA@BGEXx-TSzk<4jTZ( zRld$#?*#>thz!LBv}YIlrM4fg;2KS9yxypwI-Fh{vzH3PH8*tN*Q9(hB&iuM<0NL@ zX?*?Gu)@?Dfcryaxl1tkhPLVgv(*Ik%R?M;(ahx&unHJBu*|WI73;aU96LTsLF*tX z=}c~=B!7Eg42c}E9{CPcd9sBuuIIV9+Y}uNwXQ@q54CkFBByO$1E8dbkt#`A?&%+Y z(w0`Tm87L{+(VY^bTJa6d2#mE7JX3}mu~)EC5yG@h{QAeb)uj4{{H@BG^6Kc_5BSQ zQI^zo>`)r(FE5362P#AkL=z}fT&|vz5AFA`d=BSau1?ui`|Y8WlvH6MJSOOqfu1fE z1+WDDIeGDTqLp&fDRPfWs7Fz!=y}dfF0Hc~;@w7Uws6 z#VpRF!KvXD-CT+d*4u!BC0OYmjjx4`Aa0DG@LTnP2Br7Dqi4oCX|)7 zH%|k)d?vOVYKg58fxW^iIXhWS>D=7K%Ndj4ZQO^#a9>;m%}n;NsJ00BFx33q+huT@ z6-}(AS)6D^U$e%#MCL3(q-DpDWAOfpBm>EEcRcWo>EkJ@=@9jc;G7V15ERR6SUvLV z;2^X_o~7KFF2t^rh#SNi=XL8cvH>;OnHW)J}1@53?l zOFAbYx)&aUU=>>P##B)y53+5RXLvtS?@b7a+6L^lZ|7U@H2|+x3?eJmVr!@o<{Mq_ z;(5>5pwx-|ux;9k)KpLw4+qbva@fpL#9Uuj2w95<$Ast|4~GB;H}}Hw78f5|Ocq+` zWLB5?zIm?hn9Mk}iTCig;QBw-ALJhRTy*1tV|F%tXlR)Be{nfl-0grK>L~ttw7z6}$5Ke%q=qE|htLn}6 ziKAqik&Z%Q4f(H&(7%<#AL5LQKVgA>`v`DwOgeuuW?Kuczbr~2)0mA3w(Qe)17?Z z@enaNEU8aJF(VMLSd0aWpx*;eu8jT02zn;#3`?5ga=yWbINi_89@w8*Nd8=8q~F}Q zSXv%#*J&K&4x(0v5&YHOT`^zT_peF06K|kel=H{nD}+Il>q)rxc%wV$?@q3 ztT<(O^&@OPs=NrA$^rqeRAIS(LcFVn>5m(>tydzInHQ+789$pMaP^mgN_&km{vR`n zzr?k$Ho8mLuLMGoRX3zYO4r2Ar_+c0=W0h`h=DI=W9{%{`Ef_&e>&R}u;22=yeAD! zvH6vd*i`--Nomy2UxbPHrH<-u#0l@4Fo$1Z1^TwL?{E}LBL{*=62|eoK{JWGB7;jD zVc6Et26qNth}+TIU#NYCpDXjoLdwTTXnlsimGuMvfNvkKLLUx5&T>yVd}V=V6siw& zB=aFa#e5zL5k+6Ra59N1+694Y0amX2p3HHjW(s2tjg{#Sc!mgheD(mrZzH45$<6sA zDIzjMn#J|&S7%ePx7xf;kIT(JOG_GhdZM;+CmP?V2L#(<+8bJ0(plXQVE~^dFme1= z;?aF>FHc}2*XBO6^hNN|tg-wFQd;k2+~kA9R*9|fNt5B==*Wleb;aJ!Qmw8$8$PX^( z5W>QMIiuO_swc*UB-?65d~e5tcFEInPT405IpS%&iy@_(%U=K2ybhdGAc|Bll$T4T zzBd~pbObmV0U4KK1xpy3kFOi0UQ+m5fAZ7S|$1_7?)MWAFt10qBJ?l(^2Rh zGNveqpI4k9cP_Xb-@M%D_uNm9J5VKYZIt>6piE^JQO^9b=QQRUwWR?gkHu6A`+M%ybvb9QbaP@(SmZ^P#B9Z*yUpUn6>;4!fK)7Y*C}k>YlxPQ>=#U)D zd`>qNz?jl)za}N*vIPiww@5e6j3=p?_6018M&g6e4p(Q#?Q;w3kc8x?UjPBTyRBfJ zhg12-!0chj8`cwITZ!Aoc6L#)`{ImKq@vt*X>~HKA*w~w;vlkhmb$Mbnvq#cD)0Dn zSES49w>@K@FQn2nd7&8)a$M-ks7M^_?4oJ?ikhGAwmw2XUPGz!XH1C@fxya`mh?u9 zlPq!wN&^EO-#9%T-`Ta(R8N_37gYXz|DjW4wmi)7OmE=vqxh--9Ns(y^w&GdDBFbXfzy!Z> zYCdEdg((F!7?ui|-WLM70Y@T!U!K9A@7OGopN7eOT_os=6a-OHiw?Rf{85&YXs3#V zblb$%-pM)hb+6x2G?MGJ+FN6@rUq@Q(ubi;_x!LWa z&FQ9~!pQGWkGaGnjh_hLu?Z38HEor*=6BUcM87 zbJaGk4f+l=2t&ZVfG23}sS~-P7Z!D{4?!syS#**Hx>1rEo@NAcz3u=dlIm5j?5{RF z)|XeY(dWw=Lq8LPw>h}bc z9t7;+D+=A70rAK3C=;y-hNrUazmY7ze^dGR_)h2XDgGNDAJSXgbn>YfYpb?MRp0fFz#5dn`;x@Bzp`NtcT&r# zh^U0aaX&#z3HkM>jk@?fNxIN+s!DUuDRX>d`s?vNXX7tp!HP~37?>vw5~nohSuv^j z*L}^N@Q?a2z;v9#+J;QGG5B$Ma`JGoAxrFgnCH2)u&@rab)}`HO`!9CZ{0O@%uFmq zAR8e+(c9`fE-h+IPAd#_x_WHDBr7&W>qVP1a>xRXqCd@Y_j=i3fQnl~b$H^&|8{}l z9*c>=M1aMmG)S*xN_`TDbeT!Vl6UBdjI6u4w`~3n85(!{Y#)edNO-<<_*E~oe%p?sFx9>aqf5h*)5%9(Z~((&#;b&7 z^GBzba*ePa37bl4s>)gDGv(-dby1`lX(9Dy!i|ub%s(}DdF&LWAiV5gkXJv+IHBT*hU`CP%!-j3 zA@;O(C^`f^UiC5GQCuHqc}Bs!w9=e^;z@%H(u4Z&Vmm?fpbs($h+`vg*QDpVZ6fnE zZEqC;vGh0LpKcq)L#|FrgGo}&Kd@%|f~R~a;d2?>U?Z^!2#Gf-1A{u6v5ct?_n z5y>UWP7?%V^pv>(jEthzop_ic9vP8D7zEx)}(3ZZ|~+eA&JP@cf?1-bRYa)?Yc}?5e4owgDdai}!96)isM=9vf_}EK(UVVGNYxpDyq5bcP2H zL-Yu0g1Ux=q}kxI?(S}2^4lRsWw9^(J*o}961H-(i#DgANK;R7$oWJF+7a-jH_ z^)vhB%XFtHVGs79EiI?NOIpW*-!Dt;51~sYT~--o!O&MDjrci#t7Y+d!_1~;)IVVy z25b9-f0!{hzDY?Ok>cj;pjxevGx4<63fL|7fyRkXGcOIN{=h>D3uy3%n2xM?{F%|d z=oN!%u$%$of$|qZJn?W1kgAJUSI^c~s7rKzHO1V1{p=`?@rZdmY~_Gn|7#&@CE>lx z0CbHZ&JcUXV4>FVojxFxB^bHhS$h^uWI|Bn>%!e8{b}o)Fn`9Zi_Nt`qHN*{Knz$~ zZTz?o6?d}x$(d;x;L^-GmUl%Gf6@rOPGF8OYlNRm(>Oui=`(hcYC128P6Ol3=nv@m!;`n}>gnL_r(@5F#%GG&) zf8TSE7|4A}{GOh*+CX+6v2dXzgS?(fX^K=RlGMFMWG zE8r}>3}qMq-FUs>l`bJfC4D%l<|I9`G)`c&74ykJ~sA{xXam?6_uq-SsZ(Q#C zX#OE$tU1@+Ac};+zbas;-;f7YHCA~;W$zHeOJ;%YK@{bFX^It=J0JfRP>d&qkZ55YpCOg-#rJVXiaTV7t@_^Uiz-NlbQ=Yq zv$^G`JN~vK%Kg0}z{Q%%<0A@uy>7Cc-i7tT85pEN(qI>lu6qakr*SCvY1r!8f3$P= z74ifJo-6^gx6ugj_UL>$Q?_O3aXF|qS^773nGHGq^6C?ZoV-!Mt#!qKsVG zx!SExL_gQL{E!+kN^J5Yh`<-upBx6m7Uu9`WiZQq@s>vJ3+nKOs3DPR?Z7ZmDG z6YQ$W%M;67UEN|ftzE32t=N-FJA3f7vA@{m!oDKK(SdAe%LQ)<3vTL} zlp3IZYf5j7SKVyUl4Mf>^pRh8&MbMm%<4eyC^kO!Z0qCs>I&W!ylf)brp_bY(%K5d zY6Slc5asiGCof{(9_$?`C@Qj5T&WCyvwEB<6dUaJqNzdqE5#&P*z=ujy8o_O&^J^w z0}FdT7eZf`N(kfv!QEs~v2+C9{U;iTVDGqbM;>$$A`E?v_TCh0lvib3F&n%ZA zC$Lk(TbWAEZ6QBBdLVH&73tpO27Xe3e69DTZV3#_Yt6u7xxE z&x^zBzd}iH7OE?QR$r7tnlRN?OMT*RivIwSHhj5u$lCp54ZXx? zaiZk*`mG8f80;(>L_hK^Q6@^s=Y-f3rKj<;a)>kN68e+DUHA+iWt;x5Hn-njJQo%h z=T;Xq2%<&iSYEmFbQUSKoT+OS(_LPMMmTmr}%1$F3hJi4?!yAfDoco8=YO{4CPZ zwFRNGcAO}F4QlY9Yq4_00*{qqe4IqtSf)U-!RXa72DrX&HvVUbYu*1(%!7VXNEU$tkgw-Hf{)^+}-9 z^I#tvjgBp9I!`F@XvX*vSc(vV{!3*8wu?-OaBv*_gItyV4Ir6(mA5tw&cW`94mg)PS(BmdKDg+a0ikg6h!+YKm zo4-RZf-f%Q^_yvh}K7>A&g?bJz zI@!7I%$EFUH|9vB7q1M_mR60v;asDzbu8m2P(|AH*OJ6IbBsuz>mTDUG`4Q{e ztGE%TL4JPpL2OGqiiGs&Y*N?+mqD^;W+AU@iF;hEybtxf$a=0j^TiJGhc?mC-xGdv ziGY0>AE!e&U!l3y!jK!<0Z(D2hHF*^+4`Q7)`b>OmiqYlAs@F2cB_+xR>8$XE?it` zE*AXKui-59<1mjz85c>Lhn6-!n`Z5&wKNU>c9`ZWhp(YMk0i$z8=Zj{hXEJgUsD2a-~zAUdR{tvURG`E8jjdJ z)Ht}f05drT#NS+8k2%8UTl}8qap1k3mxuqu(&FQ!uKV5aV=Yjs=*;}VE#g^Mk85e^ z5XkRt2)!e{tHJTp`WOh>p2VdCxxim$+8=(uC7~} zE^*q45Ft9Qr1tUkCT~BE#G6$jo_>@MXp^}zXVp<;Cr1O?w6WwgE-ti7N!HQ=S z^U*+6HVJuZG&-6)19uTJB7b%sr)%(&#iht;dVTBYom+_hXZ6)@bwsR0L|+vjNHShI!s|VK<%s{RPu$MT`fOi6no$nS#%>`6 zx<^|Nv5FW7^eoFrz0iw$23Z+*i)!RIC?NLQOTbrKP2XU5+EM@X*a(; z0PJ|@>+PohF7kZ;oozN*{;LI=SI^hKUN8Ofz3e!hO7Pq32G-l?21IWozy59bUjF*G z?*IGz=a%=OAoWlCKaH-x;{io}QeNSJk?~;2q^nU=qwz{$*Xuc6TgH{zaER?x_GL_s2= z$W~FM+glsx2V3~SCn4Uf#C$>5gQy?*C#R>DZt#9@(!C|bSLX6UPTQcoID&*34}c4y zC~&{<_HQfjYP;{^!odpbdWB(gbyX)?j`y&ut!-vuMM+uNKwEusCRZTv;(qzQIP<^R zOW0v8UEnbO;=XrvR}4@lUOQbVFG3 zR}0~Q4N3n6k*28}Fp}jr!Df~0QEuuKwt8jdn#qF#$g4kutrEc; z?Rx0qa`PRv?Ik5gN7tADaCI;S_-#yDTMu>3&0Ff|Hl3Uz$-o=RMvu`^e#YT;H78F= zksY6>v(BOza`)WiNz7mqtkoSl+i!7qH{ah^Rh=K*Qd?IYU^@a>Eep-;)2)IRMpfJwSX8I zJ3sHL96o}J(~==5U}PaB=kCtYQOK6(LX`eZ?22Eym&L*We7mIUXl-k28jlcD2p?G^ z0}ID4D#B^ysJSB=V5}U>dua5jy&i>pwI%~#)A}EFZu!35L**u+hpmAoEK$9q%0bb@ zaZy1B^>GW5x_G=n5SQwo(7Z5j=q0a5zlPaq_2idlheO1zQ;`uSkj3nio9z_Vbr#E{ zbI{u(?@U6t&$9&p1m6#c@~@;x%I;L-F{ z`jX%1Kpa1N!CIJ!@8M_C3FMXD1Cwh2pw!jVdYFn>azsb~n`UqCr}wuPz&&S;_$#~Q zho-vv&LY#VySXpGop!S~3UIWhCMJZ1bypf=m@Tigs}ZmJ`*%CsCtEl;noaDc@`XOe zs_I0~I3tJ`6bt57d5^CG64yGcHMfRT?N$lgrSECJPU?N_Dsm`7)WsJ~c#qRuUA)88HfqRDS$QtUYsa znH-El;66UisVP@IEXNv;ypz7(VQu*@i;Ozbh`h2>P-=EL#JX`t7Hs;7Lgw^~YO0tw ze08A1C-@OzYkP_j?yMRP0|?i+=r1BmdmZbqAzktDpZNdoRm?ltme*dC*U>RhkBp6v z1L&m6@)1UA>ZwthiLoMYNQhB06B82~YiklZwx6wK&&B`r3BdUjCIF?qva+_kT8`1I z%d7cP@5Al`0CBnb(F$_%^RwD1Lg9nKU*=N!!$((conRgX9OSFd5@5(oq)#+)R>pA7 zj>z+#*r1LkeF@|k?Rt!>l5aa8Wqs8HPKW3py&EY&s4`R)WhFX z&{bdXtE8lRKPx zv2vF-o>9mDykgiBuuUu(nrUnvV2rE*2T4;cvdIAy>wU)idximd)e3r2Gl?$QRGoWz z+ItlD12}|fUXX8%I#?6Z3G(vtjRD7O)dyzjs}}en8OFsn(~&>ir-|oAV<0j`a-~t` z=97H}V*@lL%Bvt~9sL+msz@s3NutA`y*qKMZ*KIo5Q%Nt#yCn`o0G*&;`IUqsp!2K z1OJ--1)O#hqpClcO`V-t2EuHU02nwS7|a8-`kBg$U3~%;WI#fg$7%ci%i7QHLY@Et zGo~%#de=<)Y+S9Py4tKDi#B_MZoFl2aev<&x_c&9XjvlhEm*HkFbn|I*5&dk5TY78 z?TpS1YWM?g&6UD`gG1_*6gVQ~kT}uFM=mfVuJeogIyL2F?Wt;hL_$3e0~E_Fy9|NS zKU7ka8E4y2z^EJp@PPi1r>>$hwkloC!^1P$Xz}_>AN0s0Lg|~mbt+LBS=h;bM~G0K zprVSqB&GtN8}9b#a#fYt>|I?DVDJMd7cF3l8thJbg z!MUg_bPF=%A%Usw-?HG45nc+cK}IWi#%mKPU%s~5S|s;-_wSE;R1cf3o{P`-6sK!Q zysI&`Hql5oNLS3S?&hV;Tt7RQzbjQWH-^mA`wWDi)#NbgUr5@AOar%b$V`*Kbsgcj zAd5Z+dxmDdKt@gyX!xE^70Evo^Viz|bSEYz=DXGU&W>`32_#^`E_@FT?h6))Nsx+6 zVBjV!mL92Q))o>K>5OV4EEv}Vm01i>aT-OW4V7MRZl1iqkL9l4KmzQUo1&shzNqe9bIOXBgJ^48g@;dvkDs%;Y9lLSGe0+G+EAIBd!kj%&roA!Y|NV^O-HS@ zJgcl>pwMG9H51trOm8D>klx$?TA%hjTWRPn7IPe9%Sz8Uu&~UcY{vd#+DohrRSLWJ z+M+|;z_))L#d4X^kU=&`^*15#BkC~Vksme;Y$_#l^mXJ^nMoCu)$KuJSj}h*K2{yn z45Nf!AZ@?E=eR2|Lm=bQ*u-V0WvHfBvOoPA(+b_~b2%c&K<2xx+w9Co^F#c?5=I&K zi~W9Bhjemb*HyakRU96036QF#Fryd>3)4F7EgC_;7Kbi+Q<1inQO9fQtAo3Gack6} zYjR^37&T%vSvQZ6lSgGI|1=%u`y2o^5fVv6*~S@@^s+Ka%9nQ6!z=G-(j{?C9Uw97 z{CBumDxrF-eh1(j<8*XzBZ=tg$5oy9i&^11=Y}C;RKyLj{+FB&ztz`g>V9M$`~SH) zSKtN@gJ)}cYQpJ;@%)r zXc2l0Ud2hBtnxg7;!|gwLniY?b487rH}E5A5z*Ne*i{Tp&M8 zPtaTFFfu8kIe-4_;jkVVXL)7~@Yi2zsvU$S51RKuS8|qzu#n;%Mh}aazpbR#Ejm*L zpNvkUHtl3!ly)RO;Ip%qBHsKJY}z#Dm`6|zy{;R6cMs5j$agb`C;ZIPQd1KPNg6@U z4R5jhY_p4$VoCh62*Sgo(hdAEklyg*Q|n<1x1d1+c}~YagVN{+Dz*xx(`hQQy4+Dq z9d-fxJcab?S?pJ`y1+#$So>;Tb5d?1WvgBQ+CINJ=;E(bRNu z)I|47wV*k@G-or%IwYg%>L8JL!_8;Y(z1H2t#h>=E`@@aSj^-+AT=awfFu)P0_L&} zRK0O&nk6kQZMlH=jTt~$;CZE3Z3F{K8cX&}Vn4(bG8&C5L_W}V#C~?tQIfz*ycFL5 zaxkV0{R8qXs2@(7hX!HA2uA)tPj|?A`qUQzeJXfLmG2pKtz4Zzh;=k71+Vf;ivi+3 zB0w=b@23~VASL~rx!!Vk09d$r!;3R8pK<+DsoZ&n=N>b+2O81Oy^e}5rUjQ%4)sQj7#W#hc0Bsq_Q8xaJm_^Jg_xx_l8&7~q{8xx5Ey zQ{i~Rca;Yc$-A<;RfJj{dab10RL0emWb#rxDnfF_G`cxdx zw{O5dPcqWzTymp(%{j2fC-e!eZ^m>&KZ z)5S+T3cSD8 z0>+74a!nJOJLre!rihV`ML0~=ubP(TW;vS^3MK$6BnfR`@{TnpYfqwfwVD92s3+fSC@ck8E#1NFPy*j_H~`!+z=9Uxd+?{gESqc4f(Z}Ix? zqH*$y_sd{19PW~f1DtS%1k#1S-?@=hoYY_)Z_DI?5e2YA`M7_a!W;Z=cW}SoY6?ee zI`+Ss3kl+~&RVXYJ@WYEFyxa-B|1i0Zl-e1>7pywR0eh8tP%AsHGu#}7b45dP zLD{o2OP?)GMu2-om61Ann5y6hj9D#|y4fFg^k*W~0qs2Pu2Jn3UtiAOKnuN( z)U0Mdi|qLce?*a0xVLkY%fSo8d9Ub>Yi+XECu*Ag`D5zeen*gD9#Ph?*V|uYaJS^) z!2Df$Vw%aMAn|+exw!{YeM7aKe=6EqAEY)sNS4becr#a?MkR(ek*5u`(3qz(ovF0# zdxPSoA`b55`o zy7One%uL_=F+W3xTT$TI*O*nhNfzV!4DYC55bzfMYuYe6?XzWoo2;>Z68~Wz98s6c z{um%fp8wRUn&AX0#Q+B$Pdg8sfsnB9%qs1cm3Z=T`dop404IUqeYjcr7+ssaV;$qL8E;lyJNd&xxgdsxS`?x z{9K~A7}#$#&Ch$!t3LfT1!G=!Jw5HlBKHr>o}B^rCmA};V9dp)L*SozknA&V5}e`x zk#&wynYZD)&X{c5m^|6GZQHhMvL@ShQ%$y;YO-zH*uQu0wf=jrwb#?fKK69q_jR4; zaj0qiH*c#vrG+oS%I}*!-wAH6r*(mEvbmn0NhN>7DlRd)xoJpz+3ytp3zf7lJ)KhL zcX0+#qV8}8T}{-{?ve2lK_k6u;k`h}A79pw_@BZUeRoWV-ZTLU_4L>K^skfkKZzj_ z1x!>{8%pdFEPYj7`B}sZ93j-xo<4<#Y&(=1_m)K(!uKQ(ap+c=LV2h4G&wN z^m|`WrLncC!^^oDh_4M$n1~``#7IwcT%%q1X2ObN<{}V_y{uJV?V>NhYpc%OO-@Oz zYX@VJAKE+8D+AHX>-B^uzpVA?O~BLG);3$8$?;P7Y^ly-`}OVZhM5UuGfv~pBiqRe z#?cKiXfiC9P9wqxTN;<;Y8~(6keP&$)G%z{PN%hZfBogIuBX;Q^jR>Uh31_`IP#J9 zKRyc@0FnsVu=ofq(q3EQ($8GZTG={`{k+hGSYa`?RWnV!b8s#x!{}nxq%jX9Ep1%w zkIxB9fB?vWPw#g&YBvRGSrv}#)TEd~=tgIZsg$WSbC9XuG-aft?jFpV_XnRLXgp6X zC7a8h^`#;S&n8~SXtAit)I#7PTHuzusbjllWlp*2S&h5J%;#GFZQ^g>v}DP4qMuDN zYR+es>d44=8?Z5_-6LJL!(3&7YcYC>=iNMv2~M43%i=*FXNO_^gStc?lVlAa%m?7$ zGG#~>N5@B7y&}-ccwU@ApeMU`bFVP52qBtM$ii$ykcE+ggNx93q^waa(Ui7pp5&UN$yPuNu3pX29F#1((*zlild%nm*ePeolV=ZnKG0l`{Darx60tS~$39 zLl`?99UTdA380mp@%ZSzE01IiTOS@C4pZ0B-VOx?MN3Bu@M?eV35jFxfI>7~KJr|a z>uo9ZxVb#UUAVPwZ35Ec6rPr)mR1h7A1SHHrb8^Z#tpjF1rD~c--q_*{JKnvitZq& zF%AGaF5M8tNf=~g=ek&MbDE%?2l4Lf(C{)kg!0|hDr-X^SRR4zjCp- z)I4@3#<5x;jpVZF=I2J1Li!=nGT^DOAKrgsHn(n+49O)V#B)CY+5+!gHWHB!q4LbP zCZ=yp5R8jZ+YUV+k3cN~c>>xRFsp4(-j)TtmaVlql%4MUBm!zAF#k}8+S}V38n#Ua z83=s9>V*-m$aagvL6dF4HT4LrjWosm4(=(M6f>^|O4Axx$3Uf+0T z4-k@#qW4~Kl?$?Rb8GA9OrZSZl?Y-<#&<|(!D7%2#N$m%OKr7X(bZAeSa93v#cMAk zKA|2K1RguRZz}&WC9o6-jMaq!u?OL(v~SS?nCWIIfT*WjwH9^3ki>?|J?IxTL^$W_ zi-vn-;-7D-gOak(gw%ZeM+3JnYoP~Y*$D@BRd)kmO*gD~6~DXj-7ALPu5Lxcp(HXT8SsVt=xOJ`VEw%+|6J zU5v%`{rpJQUy}ib(7swEj3@o?!Ro3#bEew}1ofE~f3AfaH!;G%n2Rl?IF4z(ZbSoV zb_H2w1p|Bs5|S2){zu}mY1;Pn6_)(81@(7<&_ofu;1VgzDm>gJy~ya5!HsUuzeh~P!RaI&jn^&cB_Mv1rETp zX064J$LI0o{ZdCdu8h3ZRv2O+xHR#gp#v0n}{Tj%kq_mBJYuwaXX!fR$GRR7L}8*5%LukNrh>~=W~ZcA6=d1S z1P^m>Ya=I6R8d3U7{}+)e^>rjH{IR*Ov^Y;M{BJ`5qZ76LGx9anVG=-^AbSNUtV6; z!s%sWa&s?+d_A`I#46A8-wdJw6~)0^fMvNIS(Tpd9ld_Y;(s8B!rPt%jpV{|oSl~^ zu?=JaBsAuCVq(Ug$$g#gIOQ~#)H`qjqex>x;;!czY!b^^Zhb=LeIZ)L%`7kE70UK7 za~hLEovcg0K?%*{>Vok6;t6%rFj0MxF#a6#xSR2Y?te3m+ve< zSbOx}OBTNopYR*`Wd99^HioeWLfWQ|Htq)I3`CSZ0!M$uzyvERhH|{GWWm?DXxH-f zz{_cNYu*$i>4LS4gV5V2{EPZ7MTob^-J6<%roLZ+L9A5J5_OLHN-ShfpN23?Xcu}n zH*nL<+gQE3$jTjRBO{fGe9~A(h34(x)Ax{w51Mg|fdL9xR}VG+dCJeJC`;iOn=@QB zlgOLn3T_oWHff47Vkj#tKGTkdvpUb7&y}xz24W`ibGvCHp|;rEM-fuJ@x|a*2knx) zb{4za;n6``H4Hs33N*CTKN&>CDzCSGOw%N@O6D1rv6P|7{+8SG#`p7~lYfhc!@xnE zdIBm7sqxA%H9Q?3k0dL1(&iUhZ+rAP%#i8$&6I~KH0%bDf=9qoKRy8ooGVkx`j4g+ zht1A5AZ{3l-Hb%Y8*vEenW@tEW`;WpVZBdxdI4-|35D2TAcl9pikY6DoQsQ}j?G^9 z1JJVi;jl8>=w>tVcu~{g;kNEA1Ar5oH{5mJE;{WUdR(@`JFZq8pEmyTxSN_CW%K)G zGBp6YjQ{u#-mQE?zX;N$T=C(ByPiR%2CVT_)XJKA*Aq047&i$oybo_ zBkoaYy5FP;vkgKDCh7ggGmfX*#X)>4FH8ily-}Ue7M5^=3NC@~2XuUTdRY0Q zBI?NAK~c)vv>K3>BWPB2R$rF4bL>byBq8?EZ;32IT>0osusA*m|pkU@`I^-tYR4xVbs)oU`8NM(l^R-(C%}+1L}_1w8S8Gb>d&*F^b+7Byp9L!9X1 zMSuT(s-xZ#W$hw`kwvO8mbs4p=fxS29aZo#Mp1{*hbl+A-u}VtK%(h*pOkgXgLFg~ zO=yg0XxxdieTsXU2gTKNg0#Y8u;A-(u|vHv!!%knE!>pt_<$eLgt9grR8;VQs1Hq5 z2SKro23orD-qnNI-MFA#e{>uc;I4i~x1@z!8WD#x^g+s-QWv7JQ@DK>^4`i$HN0gjhjN;?6{Ed5{hMjnR&Oh< zwQ3vX(teVK>#FurLs=9EY$*ib02-%^#UP*%1oMYb!T60RElHY~ovt%FIc4`KK^#_r_Ua+;!eY7#$NFI{q)C@-5l9ghGn%*nxlQRfq|A`;=^lER3i2{Z5}Q9n-c zT-jP%HzEyD0-OMki`4~(R^E+(hLD24bcqX<}XKiC>@3IJT-O73cD!O9*m6G z6)OMg2mPTN?msWvW38^Ksah=%7}!!QDv)Z_ldYr=e6-Y5HX7~qL`3+aa)9U?tkkxS znwl7^uq@?uB{&{2B0P>cxX@{DZ=kq@`N$|sBF;ig)gZBL1O<+Voa7reGd7-PECD9J z@BVRO(a1R#K6(<1@~NN@=&rJbii^wLW|t3;=Qf@?@b<=&23p zFs$3ZQ9QRQ{Qo^+Yh zGy7y<>V*`j+X&B~5(rNy{OwjR;ce>U2eUe;j$T(oI<`$3T}^EYo%Ii-{iFih^+8Xm z;!So#8AXz|dFipIvh}Uk_^+3(ug^SJ`;|ul5|6vZoUc!$&;6~>fB=AO+Y_YwjibCr z9hvS2+wdPaw|aMpu!!b3$k>`+ei>Z@{Hs3S>&t~j!u2A8V`fSd zP}>#0(=o`fS1~E;;jnPhsvDu18z(H-SY_B{<|JZgONJ~c-$U(Mpwu_GQF?RD8U)p3 z;O9ag*Cexuf!-=5#;j;LTyx{ls8Pcu{SDo06qyN-l&qK~&O9+Y5~KiKmjs{EC#_40 zA|BO|DwZA+XV@{-*Zze!X0|;pEt8p*6~VMU)d=Y3_0|T*cr2+}KlH8`27bk6qm;l3 zhA++EpO4P>t7>nC-3&EOzEsDQ%qsJh!Jl|RhDA>9X7{(BX9w5b=>cazkLwAl68hU~ zTayJ6AbtkiZTEd|O7P)?)J#$^Q;v#{K42=o=B}>Eis`$@$C^q?|GIgu$mz|+3n-cC zH-E75i6P6X#Cf8h(2wX&P(!=Cbn8$t6}?t>7nVw}ee-fQ>~I-Dq@?wZi;YD=Me{|* zDXw$k09c01pAM zZE-ZmoTRcp#IAAWbhHLZzSneje{T9*@p)XXt0?dd$%ZFsdrRl4fU^B24W<&&ff$2f zaPrCs;&eaP6cdA#?ZoipoRJ&M;IB%Mr1bH5Lto5lvL;-Mm5Q;cEwyjEJrspHnVYjZX;CPhqoR5aqAjf!%Pqc$@u zLE^ig5%?(kx?c+TSb75VBZBp$XsegY4Iz#IRQGu>5{;?-<8h6{VN(^bqt33sXH5H= zFV${ry)L%;Up@IF9X@S%7?_z|lVjc+xwAMe3$URc>J%S39!4J;qaSz*NfB0~D+6F} z->Wf-A?SQ3tqK~ulpbbh(9CYRfDq*b=-Nb^ie+pm>NI>h_z8*0ZkoYGk{_v3&D)$# z#2k>qZ8RnI*9;RM{fu9)L>~txJ-0|-(>D8`L|?b9U)vK%0jI2a9_qu1rfRiK#w(rT z_HK3q0-r};uNq(fzA}m=QlK4U*Yj0CJ2lQ_DbS5Ek|FmUsZzejD?Zw=87bZRC=-|1 zM#0B>udH;D2-a{w+v45u$mL^jgv$+uX!9LYS5C}MOpHm54rJ6g+Pd0WDh8PB z?LlDNJrctu-Y~ia`zwN#AuQ_$lIl&!AgMwmH%a18R5C!E%Y2u-z0XDr5u%}@M51nL z3~s-B>=XoH3DD1v2!fXF$EvmT`9bDwVtsaZr zKRh^cTP?D1!jw`P6}ExXx^Hyk2qpG!c{SE*-OQT;E28(c(Y4#baI*PY??-!2>ivU-;U`XwDB7m)L|++FVs)OFrQg`uGR!3^5?M*g~qo z@X>ycO?d~N*S8altb53zh=_zBLg7=NZ!q@mm6q}~f47J1!P|#PLKy;o!YaRav%J7; zGqG?>n@;1NN;m`yxNa*J$ZKQGV_czIz}^vfa7|2jfOugbZ_+oPXpjEyAh@J}20H1OAy$4Jq~6{3yeMCEf@z?p=q#!EZ~*7@t>Ddg+#*85+9_W=RX`w%34&o#SNW=F^2^TnY5+y|79 z>3Hq-oEAC`zCE(^fxxUk3z}X_?X6GkkqP4*QSEzaQrxpO42V{NK{|nUf!LZj&UJM|5}!MAwC82 z&2T{1*xuY7iXgB}%a042!8;!kukjhukDO78#S{c|So!vK%ox{%mDDb|W$68T-Vz+3 z*%=NjR3NO>=D0ZJ_e+0~MPu3)!^wqZ!&oVfRc@MW{RM=DKWoM*4D{3zK(EEz;B4uzvyuRPoE6q&>*JiecIc_WC^d{6j4gDm}V zOfKSTYHF5Ww);YW>CiJzz|j>GW^b}zYaqiPnO-7zId$!VUmN#s-y1EJsALPYxfERl*Jm|o9MO}9{ zA!uFq>uJxM$5$N6R*BEA$d^9rUwwVA z9W^UD=XOf)4C9?5EWaa{TrBL!qF(X2DcUvw{*j~8@}uSV(B9tBbhc~T)B0CrtWHZFulw^$S$$*=SNCpL!xTiuNy%4{`EK)|K;ZEdtS4zuDW#IeSo;wYmw)>zS`yU;Rnq# z2Z7YrT#bnU1DAt|`&b|SoOCS1N)*3yu<(>KybpoNCrJzJr8x4VPUM9#eN4J8L1B8NojIGS%06Dx9#~G&p zs0F@VeMxFrRlLKA6Dm`mndu?eae+@OibL?&2Lur9(BtvGdE2RZ>3IpMxJk*0Iax_L zDK+?)QwVJNvof)wSGUnJ=EOLL}piDFFB`HCtk1KA|>cDA;?q%0K3`jd^ht#n^O&1R0EXp0E6 z34DJ;17&~ae)6i?N^Vb}$DTdy-|yS4Z^p{jSj-Qbn>+jan|eYZ;Njs$_>=dO_bv}X z8H1Qr$D*ovZuIZ=bM)LC_lf-ElsB|)MVGRuCDV>(JyI{&bev@z-NyGcdf9n_=(bIKq}pcAPxl z^ST~ZUY2hr=d#~O3NEm^ufyIhJCGEHZvlQ7A0Ho;e75IaEC)83cv*FI3?ed4T1skj zYcnvLkAp`FIMdmBz4Yjr!0gYszWV6u8JT>Y^60+nhhywTjrXC5}k{kGko>Cj`B#0j*rQA)1uD*V9|Jh$ldic{-m`80G)h zHf52w7Phy$%&Di2EE)K39{9hO`Li?DZI6u*owfN|`5l!Se7=3%!x_B3<$Y}Vf9~bI z%Bsn2RG>*{HN*M>B!4{Itbohto=-G^yRdk^=acjE?546fH1RKkufwgakADihPszcn z-`6}oy8@o4yRRpDZZh&-+v5FiN1|n<74W$<)%2=*J)CY`VOy9bg@+k*G}J^rwV)LV&|^Bk>IEPyY8k=0bgS?RLOW2CrY%pEC2ET zZQ6k8vz%P4$3|QH_Z49n-s}L1WC&Usi{|i|JTeoFQ*5AKF?K%nz zvo*}j#LUFPl)EGYZ=;-{h)`i4N(;mpPA<&}*)7&fDg(kTs9<1EZprYmYb6Zr{17Jklf z1(hi=AQ$^&^Z|+ej}P7hZ6J9ypdTFR6g^^R)d(>_$ckjKA`vdany<%0KtlQt%f!OQ z3r{C|LB!juxUU34&fcH=_ITlQS^?_~giPSe9o{;6zH?=olEl=D19B5fh`ZL0BmfOYXAL2y#~B zV;(X$5CQ4M(X|$gWMdEH1DXY&@;^Mqt$eP-bM7@6k(tSV)-(xTT2$kYf0 ze6Pun-Zj}EPyv{9 z)`jK=9glM(5_|$2mdqE6yk~nqkvpt_4(cu`PWc9NiAs}}D#$>2|0SnMk`HOU872tq7Xg>T~#mHE?8|l-8qM*=; zhp0HicW)S#qzqZEB@QKX_q>d)G*z7uNbCvli|i)s5gX-Ym-h#iBpQD3R)}pkb|)0m z&=zS=i|q^;f`o(iO4mXa$x5g4!Q<7NdA$$XOa9YH_|f*;w8O#5dbQbxDuzueG_7vv z9?1(?NLweK>idyexCExYpsBE6AQ*gY)c_G*PZ&KR3pKqFt|y3wa`o0ficM0emghf> z?UhmWv-#3Uisgq2b(Q1efHJwiy1yR`41eELOOrn2q$=r^Q(Hnp$HfIrMY7VyNW(Y{ zMAaGo(YX+YDNDps2fX#q=1KstK1q`Ds}C~v^5XiHq3C069kngK(|v*22ciW9Pjg>n zV)6kFek>gTd-_jDgqq39sIPAx=GMg}5*!+l_wyOax2SLgqC4~{iLUpdPc-ZtL+*yckArN8V4UUHxKJy#Z9lHoTp76M%$j(g}UzR zez@$uYlK4-{=oKZav(D+z{%tU zg-r`ak|kQi_xy7&BAiF1wH6hK3!NG6nzp zUjmDZ-8;=`{+^HXkv;;CV;3C`exDgvUkiDkPSYuun-gg*m&+6CPw#UA&!bfQVrzB& zFY*4*^H1`5+=$S^%X3umD2%Tgx?sD|{^wNewyTe`O$z=ObYB;JT1>xhlUxgSvg8My(?; z`&X7o#29V0XD`3^#4z+Uz#TV;&W24U9-CYAU|VEh?!e6tjX{@=;;bYC!OG>GK^kHAt{ z=wrBh<0)^?Ksj>-?6!UxT}FnJB&v}OtyhA%{VQZ9!f<22@NL0MI)s_EMXEG~mfQZX zZTd^s%U>L-;P3kS`Tacl9t%#qf`a_tsi|G==b0o#8SMw+R1gr*-CDR_&X#H$I~yAZ zt=8Jo+Bg@g(IE;x^%$nG`8<^gMBudH<>uyPXXj>SwkN_)FQ!dQ7n3s9eC>s&2p{{q zfW(G;2oSV^Y@n*D`uyS|+Yk2NwK_{}Mjxqvvs!>cp5NQzMXvo;`&HZ;42)xyU~^S3 zSUT}lNpjiAN$O21_+o)ZE`ODa-!7G7$`Q zyL@JKwLRd=znM+2{OkmTLJV<^o?CPb8K~Irn;r?q3y9_dEw#Q|2$x+d%w%A{itJA^ zWz&E#DhVMdf{loTFh&Ir#39d`aO6Q65~~DKVYc_k>c1(mNj;$t?n-duuY3nWX`^_9 zX}I(?`iqx77Ju ziy-e^(2(0+(Ne`p|v&r``!@~c`BjBku;H|ai<*!4q*YOD9 zEA-bk(SL7ZD#YOt%tI_^XE=6Od;PKRdYbxH4h}s>xjy!72bjjYTQ50VFFQy9qvXyZ zCelaoeF=#CiSs-lV0aL*VNx6x20Bz*7S1)rD+CxCJL2Pz{>h)S!=g3g&DMqG@RYc; zB%^6YhlsDs5F{<_(za2$6f^)q9pMVLtxO)jFD9$yeDv?MjolS6g&^|(_^}V@HS2@< zu1y4h^}s35*TZzrLsriR5nW{^jL%}T+YD;TGFI$}G>Z{W@HePZDK|a7Dy^p>mpC53 z_fdhjScBJ^t#>MY^kR$T)HIS^G^CF~qJRsYPXD{s&yY>%i3uBPt1h9BgDqV;>hk_V zK-+$ybu2O?B`#Fo;_R0fRFZ=LBZ#IEtSWCtBZH6g1rr+b2T$>AJ7ly_db6r`|KMOY zwMMv=4rVp&Y68&rw-$^Do<(FBO`t@%=+GBj0%xJ%5W`&}eMOH*5=7%8~p)R+- z$K+mvAhvnM$5Fq_qj=Y#yjUi=mEFx)zUQoUC=i)1Z6k>{<|m`;ILJfU@1GEhnV2<% z%}ccWZgpB{2oL98eD3liBKyCpJcJwIfZRKupPm10HbI$KbDUA+-!smy$|SO!nSMuv z0Y@nO6C3tdY3^|pix=ceHs=M(AGPzoc6pYZGko=a%c#~d&EAoAc;C})Z7JZ_= z#-xOK>Di>`x#X0T&sjPDo&+D(Fq&S&M1(m@k=y$~DCxO5F?LkK_^dz)ioXE{b39Y{ zYa?Y1-a*iGw+FMiweNeWfKB5FP$hMGj+GH%?+VW!HyKpStPsPKN^Ptf|kJ zn3@*(N@RlC!Pfs z%KxC`bU7Msve+=0!2xxdot<4Z&$PhTd#zqaluQ(`H(y>`I~zo{U9KHJdQk!fTaUQXz1xU)TK*k6T+pzhTG>z%D7Ern7(vO4Fjn z$NGJFAhWpC72L+UWVqO+m^PR2V`dI+1|4%pK~RN~Dbx}%M;tz%bXvq74$I_3 zF*VIUlh13?Y#&3zKyY{=$EOne;a#BFc#zM+%NxU|z2rb+v$p2;s4C|qfAs1;|MK7S z^MElRL)$fsO4c#v_LhYb?a`{d?kUfX$M29{4?bI3{3EbhLsuZwS%>3-J3!aKUS$TC zUqq_V!95_0Td*>AB8>UVnrOVFxG>;Is>Y2YC?*P>7`b8|izGl<2fM1IVoB#b&Wxf^XX%xJ7}G+^^(l<>!ytg=`!HpI!Hq*o`~D? z^F57*c>fHj#blpiKw1{nTc|{$ zbQ-xMb-lhzi;0PG#v|_RG~wcRlJMZZ!JL&}SuTOFAu9F{`Vr2^q3Vc%qW`j{i{b@X zC}6_+9RN9&Z^7NH?a0=#0}G*gFSj93u#UL>0sT*@q&1_`?JUDVX4qYyYW?ThV?#uD zrVQXKbi_B>0$Q$SI))lI)4ad!R{T!pNvtBtOY?OwLCq6mnH{z$vMC5a&b)^kNbFlUR-Vx}Clkxkr%S&@FA)p3CVJj0P^l z1l~to^!=|C*@-HOFbe6wPDNSn>TfF*Gc$^YM(FMY6mz?c_LR#R{J^%S)`EhdB><&8PI#c)9Lec8F_-ntnBMg$Wx7uff@FQ^j11L$%~i*Uy(-d01-@Vp*F9HMS8~b zhb%KbF(wY)1R)dq@-K-s7_|w33R~4$^K)FUE^UEG3Q-sKlvCgGGPTjc=ru8lJFr$3 z=(94o5)2@!>k9(a9}o#48xSckcw!hHu@tibGop-~GJ(5uRIX#a*8{;x>lCg64OdgrmeA6J%f7>=Ldq6SFw07}Q8 zA_2)w34FxecS7tfD8FGWDN-h`8D-^W4D^VBprTyiU`2!|aeC`w>Dq%K_GCOmkTg6& zpvcQ%z<{^%8ml8SF|l%->vMY}qi2!0w%OL;H&7ZG`A?$f6AQdcqn**60?nn1ZzDVX zqXO|KQYQe=1|dW8jVItjhU|uDzBuF2;bE_@#~0|2C~K|TdX5jcYkl1GKUz^4x!6N~ z#did_&Jhs`F?^4s8YnY!eu)bqg4qWbP!DMWO1P|Q5Y^}T&5hY8a|5KkD#f6)z)VEz zQq%B5#f9l^o>jHMx&fxiIw&!rsxPq^o|JcNh5(&X5+ogBpE=E5dUBfT5C#_2HJdV_ zk4UWf`j?je30IZE)2j@9$h&p8Xm~GiI7x%{PDnJ%Q$KTMPUfQEV=;`%jKLatadh2S9`k@^HHD>%BCrG0~U>~1v*VK{}4dIEA{2%!K z(B>->y*@a$wUn0DmNIxQBx&EnR|NEv%+KDlyOa}c;<&N>fl3hv8Pzp6o$w4!GP1a^ ztg_Kwm0|3WH9!`Hjns_kO_PfDs?pzmC(~Sz&bR6x+X0klK&hg#y1aK40Eksdb0u0i z@AQY&3B1P^6p&;R!-$~Vf-NIt@i+tf7(@A7-V+3+5L$9$G1+h2}*5O-QQ9&6XTQBm9?ENTLhN< z&Y3t9x|;LgAprP<#62Mq$JS?BLaeEnqt#m|0b~4H+LoC3cUogi1i|JF5r{;8U5vB> z$6PSSNUhNoF?H||-Ub1XCX)bufR8wg$aeEJ&~K6EKkrR-hw27IL?GH`Vq)XR z9k>?c#@%o#GH85SNtk~^nExU@fb6>3$xFD-8X&jakGp8cJ0=v64^E+mM~LP9dcX7g z_=q7p?8jXWZ7>nt4wPr2-1}}cL|w1OB=}*Sq_Xw9*21&4rh7j%Cu;?c(aoT+N0Ahz z*OTdYg~~3T?9uCkrOWMpMNmQC%wID}RJ?>{x7lYWFM~0=jn22(3^F!QlJEHald-?x z|> zbuoWl@H{OpayZL>UbcQlxrMA&JP(%I@hp1STWPn(op?R@dAexXB~H=gUyWsqB1X3YwD~pd2=aL)ieXc)bHk*pUq+m@ zokYuh5e{94!gqKf6z;mM@W4yq{PpG^uvFi8`TIl$c3@=KCv#AZQ47K|)&VcS{^G`RvVG>I-Hf+1E zGwANG5Gw2+*RBa(Q#ff(LJ*IjTH4yu^gP_$t4m8iVX&aPJ3F)gq%uYHMi;T)6K7Zg zn@W6w?z@~THg@*e>*WR$V1uEFvI|(w2~g@wY_uh8$;c_!Iy@M?jDVuE0dyE?z zX90L@ceK)IeS9+WvuG|x3dSY@xSN5;BAQGJgP1 z3EY1vGee)Sej)GkD@o*^pu0$B8KHNwNKm-G5{IED$uHYHsXxLQr86{}hVL$YJV(kK zNm4X+xzpr3N;D!B2|P22LWpgZ|1oMj_+K^K$ZrJbE$hLAWk zk3-DwaA}%|{6J=)_$j+?_eSc;%_6#g_WYwq-;eWuWTM@xijbakQe9pjcDnJ{zdB@V z)X&x0pxDeyMZlTG;{0tf{@Y>xmgG}oNE+2F*`MVw!5;lF*4~M=-&p5nzoM?Uc0K%= zX5jy6Wt})7zqI7j*4<&tpb^IRKIrH2;O6qz`0+KdtowP} z0@xOKb!~^kLp-yuN4krbgTh_=V~&sgM)#4r`00y<|8;E7yR%v>-_#_~yF}?}eR38t zxeJfgdD?W+xNC2@ggYYi*=I!YD|)T+K5&9&_!ENB)zXy-{i#s zv=KuFa384fC75Noa{qY zh$5k8skO9NwP2cs-x={gm6`V4>%num_%3POO1zNFD#fr>Q;otbhwk!E2svG-S^dyV zM+QAC!MddWXZydXZCLYj3sg~}K`Xi1+v`Hik<;~=2H-OMKtS;0$AWFSvRE$t7}%2H z=r-f{>x1|8>U?`bEc))WAWLU4h5A>Ym})Lma^FJM0N{Jqtouem$BLs^`er)mnXZ^0 zeSYR~`HbZJZ5sVC{Xtzl*YEPDLBKvifnK^(BDDH*;#n*ytCMS5xpk$4hHSS z1_cA8nB_ftk8775Pq{#f8Uy{9_473+1K{73P5Hhke4XEn^dKP=;y@bbC!zWwhMIvn zMJ)euGLeyy(a_Kc2oQi*nq4q7cj`24M?tpn|IV;WDB3FUxhLQcWK{f4WDHhY9kwj^ z-&T5_?*syFhOi>-0Xo#?e}xszxKn(VKJGBg&`|(<`UKGHb3Jdzt^__gf0DL?&=pQv zmWft<*J1xS3wU9Sx(KO^SpY1m0R~sE2s!Bc#-~Wh*xDa%A>()OMEYbiARtl9W7Uh= z43=2LC-kqVV9w8p6>>yDdK8SKO`?#Jz2W2~wp=734boxAB^$||2xVMqFwSaRrD^M8 z1HpQ%Fw<4EbX_| zt54&TQ^cxmF?E1BkpYkcXal}h4FVw;5a>Hlz|GJ8x9;ayr(D35=M18)s!a9n_rdn0 z;y>JQ6%iS7%u~JG@6o)bB`u{)HW3gRh?G*!G&(4b#$wi$f;MMYfY@G+0jF|3M^dXA z*;?04y^NZcCUvZEa2yIp2MP~Ovd%dWwu<8nqj_7-C9?f{DN?-VOD3Jc~me!0Dnp@?s z0FR(#lGd+WgRf3~v98Bn=)b+!t@-uFXQeq<3Pg`ykVG-Yt64892jJ|Xs?X_4I4GW9 zmbqPkQMw0Ec!i}htjv74q?}JLy+)87N-bqg6X;) zDYSmve>87*h`f?r-Z~%*?X^QnRxt-hP7YQci!D?N{5IE$j7^Z5>U4KUSYVIEF^4R6-`gB^*#}2wnpF ze!FytIA|uyF3M9eh(ihrVPO2P)8qf)(et)(dwUz3lS8GDi;s(I?cfk_T=3IShQq?# z0w=g1>_hafjQ^nmn*RpG&d0}_LBI1jh|w22v%HC35RhYccwCSx?=An;L@@_k$%@ek zfBXF{wyN7>c#T}0zQ9E_XOIfCoW8kI5p_2sbRpC2`si&RKTjtgc^ydn~0bI;lDGGcfgx#)abMq z?s7C`@W&O_;U>2?6@J^~=ly>ebE;OiyUXY@#OOs3+;tEs4(&_Y2+jW56Ne)HQ{pys zt`lay9kNEG@jLIOeQ^ZjLG2jP0^Q45)M!+Gaiz(No%F$GdeLenTM^Yr(7!dQ$q2Cv zI&{9z5waH8usV<;4N<2B=UgkEtUTqnpwb%7SO z0idLN*T}}aBDiM8lZdhkNKz^H-(u{-kW;_^SuDf11yE^ zK29SP&AzNA%4%Olqhs4XpDhrkRg-grpHze9MZrY6@5 zxVh;)54RHXIqj0m8A2jBXDAXL2qNWb-Hj>uC#{IujwuR*qY9##q6nd~@dQMfM$Gf@ z@W3t_c-uwwGsFXPWPH%ssq0nwgn8 z+ZcIz>DhYO**fH`{2iS9O`QB4gEqG2Ubf~=u9-`-GyB2;zTFPS-447ftf_x^xjoF- z`l>A0{&D1DXJ+TgIYw!c#QhyNZTL}Ewio24bxdC+_(WUpWHvU$)NWGq$Jbms4`fWT zEKli27K*X28-_RNhV4NYb8EWnnBz`SJqk{OxcMaSiP9bCh zrs+W=qhvBj(%@B_K1bCC-C1UK1U@Z`+;S{va~qd5q_OjU0b9@l-iLVZ`~X3iKYG<^ z;n2Jo!`Kb^tQ;)7YBibEatd?c^bKN_r{+)asfIDa(uNAjg5k-W5Em6!eX&p$Yi)u(XmE*g(8^gX)KS{n&a=MTP+)zn!4Khb^_NT zpe|71B+IaFq5t(Du!wN4i=A2 zDyK$=Pt~v4m4cGH0XjW0E36R~26aEogcT)V1jTQsE6pzmI6+{2-q%6@^r?J@jBbh-?00U zXjDvxK$i#*LQ*`l#+_3hHCuT;o^#2w*1BxFPzDk@ ze(30Nz^e`z%(%;4#wJuTw&w5$(+AQH<4Taa6dioqYyo=Am>9?DH3~pUIzBub^dB_e z!qlfo+orPNi(qX^U$H72Seqm}g2sV%JLQvJO7w(OEvPbbRGE@Oc(Sj%JEG4w8MG>* zpgbE?&}^;2WpzzLtwww_YoAzts37sxp~SPRqm>WK1x>h@9&SpQLol1hZ;#H`)6e0_ zuHm>P;aYwutKp{JFFYH$w5LNSv1Z=>LMXq!30l44uNWKo=lX&3=0J#0jm=CS!$-YX zUcI~tJPnl*y_l>97ktOIWk5Ntb5jboD_oHvekp1@u5Z@JPXnWhG!J(X!a>%IoJ18{ z2UC}|_yq=fIu}D}7#!#Ock$S1Y^PCU zqiJk3PSb{sjg4*Fc4OPNZQHiUM=y9*pK6iBfgH3{h*1Uu1{0)J zz*!97nX^8hv%L1UgUrp$9M4yvjfJ-vG#XHEE;c)}E-rzKqq#YS^o;3ahl$wpY5Vy2 z*bQJ14|=@~PG$*w0%FZ(D|!P_TjG3GRn>Ke#f<*`eA|q=yZpMlnOMO%8sr2-?9WGJ0UN40|>fQecFTgM>5=CL!&%9{$Uj=zw411 z4;a-GC%@*Asg~2wQjNCuyviT+D>#gn{e3DoE*Xkzc=Q43O{ykiVn(K99=a8O4Qtvh zK${B#J#U(z2BA3$RtZ76_dFQCQ!`tkv@`lwc4^{jdY6*vWOennhZA$JtDw*QrRrT1 zDLa!lZgAKEJpeZt1vEi5Tk5aGuO1NNv5#GJ1 z<3)r&upc8qOx6~d^EuH!H#Y~=ta$ie6laxZ|Ly7z`|~4u>Mus1tbTV<-rx9aW_rI` z^`iYnM>nS9p2|TMliWIO>(h97Nt6}ZtZ82AG!ODb9dlWl@#aCVVr`fsO)A(U7m{T> zCPAmc0&=&!wU5wiLSI^`9@k?^!;*(IY_Qt=$>oMRwwww5kb(GsWYm-l@*WY>@%rNG z-`!qg9hs+Fs@_Wh(V++!y~o&Prg@Wrf7JXrs$46TurmTs&%E3fooucjz_#BDX=0f> zQ+se+bD@lh^B<(642_Qc3@up3z{Mdvm|@`>y!RX?Pbt;OTv{b{%pk?OF#tq7yu z?24}{;Q6*|-1|4weC^3@7gAWLtOF06Lum%AwkIw*4cQy*jyo;)7sTP%oH0^(Ty-76 z2f+OF2KhwYIwAFms#z2P5~kzhl$`CDoS5zDYS4qaa2@n3yhR=_OYT!#0qLE!Ql%f* zF}X0pS5-DQ9w@OVDMc;6Q1fm4HqaM*jbS#ZzrVZA@PhT#6vD}C6__MdapRX6G6KLR z0lgk&LEGHA$MX#qgoF{39l>rZUnO{5f3i?_XkPGxk0dm+LaeQ{+{*2rVG$`Ti9-m; zP<%rTd&i44DM@=kBCp`*07!T1fF%;D8Q?SUmmtNXCHz-bcE*IXC^f_HZ^xz2~wNLT2Ps;U2b9G1ab!J~*Li06UNcHG&^~G}x;_cVN!$3J|Sb1s~IVxEB36%6? zlJC{r_O_rS72Bh`yRPN!4#eA#WdLejVQyJoX!^;E| zwLlOr@PU)_^Sd9}Sj#iT#l#H*PAcXnfQ~)k49Ha%7Z!XA$#x-#_4aH7eNd*a^2%GB z(`2Bo^!q$)7Jx!;tzo>CDT@zbBP9;)Q|$F<`scaztSeTr9-5zs(L#iWRmGxT;R*tf zCqdcFEW}8cJRfMbbVxYlM>Yu)pMs}Prgtww7p+JB0I`lUG@=)!KX02rm`+M64J|P| z?i)^x*^W{AGcVgLo})&kYB1$nQ9ZV3`-BLzNQHR2Fg}`#ml*p4IbgdLmAnJz14G&_ z&=tTXA<(b!p@1_gO-@hGlOCVqHpKn^aL|g}cRXv5ldM_hT$tQ(iv(_Rcj7s0t?dSM z*t(sq-BOTdbPUWI6g#K;ka>Ng?f<>)*(bhKfOmVlyDA_7Gf z_zH`Bmw}<-iCfY`T4OU$c$*fOn>ANK{jb^S=KP}lfGYvtQUq}4Mo&yQdK)5UF)97- z+roYuT_Lt9w>|afEAm9@0^^4PAZ~YnI#5C!-VRu{z`_Q>zyu{X`UmETX8HFRR3rt1 zIsBk}aF~Ssw){;n=9}Mmh}KdrIcs2cp8ruv^gI;OHH}jC+uNbQC*U)Ce0V@#`41oE z=xDXkmQs}T8=I={AC!jiM7mIEyW1l=xd_rEPz=5gem;?GKge|6$r$DvmRpvKb}_yH z=lJIPg%jyl3-a*R+X-H;YaFkbq0Hzc?x*@iZ4nks?;NkJ$@v0vnyo?N?@V4}48zu~ zbd@E1bcJ1+4wCGZDHoXoofZapW;HbiUj+v+G5}D5+1~E2kyXl#j z@)%A_&GYaS7$?{irfhZ+iRBvF@~EEJ(&t58==nLZ448TLyJlFJ-bZi485Ga5H=Fz050Co(R>-Hsd0;QE+xc`WxKow zVnf5Lk_T4-j9BAKkF90pX4ib!f{rAiXH-6P>IueBfk?E3zvdMMe*9y`#Mp9aP|yfa zbD1UGaZ+I9JHNj?j0qU0O~Gbo ztv~W0*qF-(2#S2cVDfB4z*%B)T_#?TCF!b z{_{2ZpUc1X$!GrnF$m3HT``m00FG&~aKz7of`TZIGySaRG2QgQQr+tuAlwm)Dd5sJKt6dnJd$Ar((M)btn}0t8t5(kuahf_sNrN~9 zLC+uNuo7hLvIBB9eDClbHO4&kCyGTK>n|JhG@7u*{|@56U@8LprZXVez^d8MTEv5I zu*oJDuIQc|r|1uDxrvY9RUtX}3or+K$MJfu2WX2_5PSwtSDsE_xvN068RT7GSQs=7 zEA=~E8B~QwK;U(pkAwFs{Oz^#^K~gpU5=aN^J$Q09xxexj8wjjcs-$f`iS6AX8{o5 zj1eRNopp>^4mNNaSV@4t12(tz_h*IL=lRI{k-X=1iuDIPxAYVG2QwFM*cj0AuksJS z6qqg8{2=^-8b@w6y%dT({+ovVRJS-5cLnD-y?ituV|y+}vpQiZJA{S0b7d3wZ4_ue z(j_6XZ1k9kdzU62#1W1zmlxb)I<^xaQ9gOs^R+f+3r^MrcymlyXN#`IH?q@k`_q7G z5GwAvtD7>;%e3PQwBer1dp-tna>9qvA(UPo3lu9^kZ#JRwN-q)WX5fdS^VFECr|rx z$5grK#9Dmkx9k_A-q&WM-l{DylS3lL^Sxz^3-btO{8*IB6UvP{Vwgj(C<1tPe{z%u z)BhbXfI%UMXjoPgd+B^2968-LE63&-w2cf*7rC-RkqwKwua zUq!z{e`mdGZg!PcV}xGE$6nGS2Fs{llAmU#EAu|s`HP#@#VK`u;!#y7Tw<%O1+q-80Jr7mOUEJwu8S@1ycXop06z0{+NheB2L~3a zybkG?5$iw@^H1Nb^e%`KcY1LJ4b%^NXebp>-UpDf$zZgc!?nTvG(Z5zWxlTI=JxSX5*J zl=mq7Pg}rj_}jos2zBPuiCX8%`ub0ra0mr*d|p(V-dSW{ZsEou2DS1$K1E0oIWg5E z0YW@&>tjaFe|BNOP-I2}P#k=u?sIjmC1p`op!5nPzTC2XV>N{GEyAh;$ts>}IO= zd$mT)A^U_U6qT9z+Qy#auuwsZ_I8MgO6K~j&%7;tuKhVX3K8p%6F zSlGrE6g_66UkX&XxB+i~kYw1Oc$z#TF>z@E=d6(3x7qT)OmnF)@{y;dPQ0?=`UYWb zlp(_*0IjxMh!&v~>{w|0t~zGkbupnEsUBSH8`x%?o;fv+r<6xli~~Ht%H5j)x60_tyf21TZ{<#QT-APCJt!eu51P3C)zwsU5tz@ zEG%p!K_9aCR#?(nTw+gx@fE?OJg%aI4adZNal6jH9RSoDnC zzu|}9e`d9Rg4Le3T(oXC1FnMZY>YD~!D_IxpX6etTr#1C8u91c{f^|kS z{lm8h9$I^QGU0{xW+UY`ngIoOVt& zJHdeQ(1XErX*bngu9UtnZoI}je3?iuwh_An1l2p2Ue_pm`gQdAI5>I`z)hu8A<_XT z!da{18vqi*YZom4)k0&({i5gj;_s%+i;K#r)IyOy&Z!v7AR7pLCyPNhu%Yi+n(^^(CFTXpd~K}Bu`m!9zam27O9qgx4eW} zLutc^OQ%#A(znapP40oOQ#T=b=o?ZW_XJ^sNt< z9lg$q&H0wDg6wS+c!gGNLyg(}%5+RjP6FNFPJ520jN2bH(6RvDk3o~Rjo0d^&D&;qGpip&V=bs+w$sFISL%7^d;yGkG@(Zj-OVFdFh~c? zXD8M1XtdIF!Zy(1eY}Sd>Xa~h9Bd8IB75l$XQ%C$eB7a~?kbWOUv zLn8SHxeZsDQqguJUEtdi?ON@@9Tx1K{K={toSvgJG^WteMe6f|oZK#93>s`cwh)tN z|4c&QMUeti{KJxSkK!t!(tSVE?ZV}0JLo?Y5&IgSPaTEJ?RcYwm#x}h$!*jZk|z80 z&in>c_6IT%*_b!Z@hAO<6AZD_kGfJqBg=hJ|Z zL{BvHyHl|fFtWPyd2BZZ9wQDNO`(raPN}*1&b-T_Ga&27F6$EzAlWjJOX$n|JzrAT z7Sgr)@0j&^UESOOWGkcH_4}L8fCnG&w{HNe0wDS1dgyD^+ko|3pmmlr&&Ew+qxd1{mY}*=c5;3TsU-oReEDNjG3PHczqb39M3x09cXq;|M9cwviX#{^8vOK9)$;A zE$`pg-a?Ny>(`Ht=cjwB1}Sw;Puw#7LCGfP*?n&bxJ~_oBVA|#cUVeIf?e~qnQV72 zhTYuJZT{U%b*0ZStp=Lx-+_DXJ<#FG3twqG>| z%QRnu_d`bH{H@hI9%XLrS1+Glc3m6GT*n0~JeEx*J^2f&Yg@xib%FTzit_QX2@v;z zXjA;-y*LdTEnI?=aQi&j#xC8BHqHRI-a$K~iuTt4J-**C^(~_~lWhG9-sL_&YKxVl zU0a5PiX)&`^SoKDLg$J9viOX~R)dt+ZCQyU1fs-8v53=n`#@E};yWuWl4%R*DorAh zF#q}xe625qo0tdYcmkOnq0Hcv^yDFlZa65#_F|kRAE$D9VZU_PUynahEWaWK# zns0@>s7DLN^a@8)IG~n_B2${bgZZ=bCIjE$C=uDmHgNXbz@>$PP0A>s;Bf%VT>J!{ zAQ7lW);2aWWtiIIQ^RAA692n~t%!0KU}CUXQsT^v7w;R}3{9#or`+Xn3{S==W<`(P z7qy($0gMF6$5qhd+48Nx2hc&DZ+@HuMZ?DI7i>YoiKSJo_&BhfWIkuOa_UWZ5$mCN zMhvq}Kpsa-;Bje_{^$QJgu zd?10|`HzXCRK-~rRlVJgbAn22CSp@s!`fcs_boU=VeE{`S^f<~E@hI}&Q8Mtc^`9m z#VdHOm&ipqc$~eVssMuW59OAa%|*9V(DQ;2@y<{bR8L4mjt+YlPXw#C+3%bcI7m5i z3+8nG*rWMqwmgQEngD5W75kNXm1?F7i>X9ttLN%H(ele1R+jmR6~WK!4@ie~*T`*G zHxdy&Y;N~iTXBC~#$-$w_+wNObV)W`T3l7)6-&`1Er;F-QSC)&5rs&I`h_3o&#NHTi( zA^7B(P=~plf$K%uN^SzaApKw>@7kJS`4PQ97RINUorx6UjXFpFJS?dz(EnQ={8P;^8ouBI9@NjJU z3d6AJ3y$7yCyf&`T~CUE$`D9Uy99=~&94_sUiYP5psOt*dZv~maqPF|OWjnVe_m7w>gkS1HY3GS^>wMtnAMd^!N+wEh6?f6SRLl$X6I0%P^yVMl9i zgz<)iGrvU0aqv9IS_j;!3$98f3O1aSOm<4A5B7B zyO|c62%GEI8}coI`-Gv(!vh}u*V^{Y?96>%G1U{4(ZrkH;#w(kphcL4*(-|Rh@0`b z>S`E4$HnHPFUapO+5^b5%6@bneT&V-KhSJ8wh5Pe=Q2ydE{f&phK0SUqNye{55)A6 zO0YHN10fCBaRMqiebZ3U2ZG#b`f2am;lBikbHAR8g4+uc$ zg^$N?i;_|i6oT*!jiU+H>2#^Rm>r)7`-L#?Ww}~^5O@TH>qV=>x?k>3nOdI6zi=IJ z>3kGS|BF)t2+gyT9Zj#rMDO#@<_(%+;EzwcQ2?@NUFUg34Q_~KltvDc{>FaW9LuF) z^E#jn^?Ww+=MHvkgCA)D9SHQmusSO8mq+3B{2Dea6#vSASA#@Q3a##$bS2< zGqGGCjz~UQIg0<|34=G&J(QzoJxop(J3b*lU@&aC6|loDdp4OgZwC@|T;EsL_8kJH zmRjeFDx-C>rTe)rpVmVMu>Ap>UY>8hEzZ!qLj62?dWxC;nkQX1>$o=5M2+DzyO8F@ z_n`Hi1_Tx3x4U*WW=e8dz~Gu8FlcTL8PLTVsI~;bB}KYRr5>!Is3%6jLx6+j2A%>b z+8@wWrAYtq- z$cE)^TJ>rsn|AJ&!qYlC;XU9&C8?fZ7n$*bS72rnXcFG*L2V0Pcv{iVYGG! zA`?_}ez<;S@eT_T+VH@oj;Le%HikA(_*Nl1voUug(n@AmTh_4+$pmsXLkB36?@&aN zaetDRG4y_AsmouOtBBQ7X!R$LszvO*-aV#5|A+tIWX=S&HU^WLR8WgP@hERxv>O!x z(+C%G2kFa~8n0%_8TbD42LMuxeem&m35&R!{BgGg6N#%lp~Pvq)^t51!*qUf0dRng z@V*ceFSmL#Vs?x#0wzfFj%^FP*j+b=Hcn!E%eLUl6|FHQhAma^Q8ycE$pW@x0JL=-g({@r) zS^+SDfFrP$%;Ul?>vd_6UwjyGw^LD=U6a|*7{B^$6wn#Yu3zVURO8tU@d5Lxp&^=( z#`8{T4if4~{Iy5-GwRNpXB}e^U%lQruPpS_x~Ru-lBvs<{l^2U?`|L-@|yE%Xd7)o zZW5ex!a;8N=gN8zEoi&cW)H)kC5U4av8r`nh8i}P0k6>r8#S$%afY2XE6(Ef?~h%L zwd?s&!nGBui>H%)6X)Kdi17>&&c#F#z&)$oo=T=Sj9M@-XwKK}p>jP3F^0wqdFc1` z-@gtYzv%VYSso6wR@fg_OQb?FIb-hC|Af;TH}1wBg3{3|QgQMtfX(${?|q9|{=qe> z-b^%Z%<|(LorNsTZb~--`&vQG)tne7RGz9g`Xk_Q zSkCsCO(HL*XrZ!@#0pH5O%K7?%3oy$aP=$Ivw$9a`qqYESELL1CsugjAc8|`Tk zgjg`RY?BlIaP%X<{O3Q-`jf24HZNzv<1$0kuJ{1owjv871_X)=4F&*&cS5FMPuHEsp&ws@++G`KK3VoVswM$Y&d|+0Lim3 zuHp($*jt#|S8q3A7AmfP9I|(_Amph2o~cRDn?$39Xv4NOVhQh~H|SRR7ELc^m^#gcW@ zHaxhW$m46ET+%Pb5*EogQ~_F%BHUVaV~9pT9r!dBX<3Z|<9HT_TQxgVQ!&P&+a9$o z+(>+B90;dcer!;Q6blI~8+ya@R1R}g zB`n1)^16S+#ficaM(0+o=MB78o%-*Aw}S_-3&_7Xb!x0U9alcvJB%lZH7!uUM`)tC zgM55^98MR=j6G3V8N3shzl$Vd1v1(wxUoAEL9I|!h6X1#`NBbex8x-Q4|p(yV>`s= zX@HZuQO&#QhB1vMzv+Nn)(&?)sWHB0B0NdQH9Bk>Qi~#rNJcI2-x&#mrof~nOi>Mp zIP^&28YN0MyhpszcHR#7Z_03{m#o{1RI4N$-jc!>>7Yxu-_oyfe^j(V;*S6chZFv1 z&^;Y;WuiC=m@{$2~>B7FJY-VwUlih@@V+$z%Es`f9ZF5NdyDUHGMblZOkgYeuSrg z5>Yimi7-@k7DefVJbv^_L_zU7*QOZB(j8h#b+Vz!H@%qtKUiLsx6@R*Rm@6U|BZ$# z9NHjfs~OTrP-yXKc|byXw0pd_^Jy|gMup3TBP~)>r_Cz2h@6=PYDHGV3s3<9UT`ze zD*Xfg&p3F7oKJ~&t=VswmCK?&*42#OILH~gXQcPjQz68)o3sxb^j?^ zl@#(M8E=n@?j+SK)!~x|k3`O$c7zVUyN5mNpxF}$Z&1bDARmf>!5J3LN015bpULh_ zFx!Lj1*r@;pL>$jsngX(Y1CnTx}S2x7+X#&T7lN-s(I4m!CdG0)@iN5A-i>VT7u-` zq+Ms9R7~h?PFWtLin>AW9w7-8T6KTA_!{GZ)6pa-?o)NWgCB{cdX6Q!sGRg7LmGar zq~!9fD=fUE|LvJ1%BK3C$F_1rS-Yh0+0HKkTdt+$Gt@QinAm4A9OhYG~j;v!x{ciW#36#NmH z-C{c;u$p|~_l41avpRAqa#xY`f0jcE!J;}6Zaa$V7E&u~4SfSnJIW@7rv4eHvhS6z zByUQKupjE@Zu~PIM*$n(_|{K)W5Rnj7{GZXs>)wzl5*37BNZDE#~K?^Wv{+ftQMJz z1#kl2eUKKB4I*Tt9yx;tE|Xj6$^Aq}M@Qy{wj7!=p|(WS*w09(vH8}ftAAzvGn6ro z!V@l_RvPkC6FK$)*-?9DCRy+wenF3z$(-6AkO7re4TC5h*|R;YrnT1{f|Ke_ZH3W% zS#WjqV5VeAEN%sV>*b)Pizz>3Nz|E2RCGhu2vG9aSufCSe0m4FW4fv?t}IRgqi(*l zFE<7d?J)bF4PWM^*0=?F-<+&f&;krq1I{1>9x^yS9&Z@7TVFg)92AI(A$iKM7ON(9 ze%tjY0`JP7G)G3ZptQ2{(-)EPZ^<%Axo|Lo!oOKVhpOi(p!LptY&!(f(mi%Ur~y4w zCZKC7t!ObbGWvDt7{<|a20+3Mph5N%p(IgRH7rk*-So?IckHdqobjC%-U;S{`hno# z)1!*LQb_->Fi*$KOt0WV1h$fjlw&X{PhzIGeW+ zkyS3lqDSC5Vhg>Fs`4i%OVtepp>*+&zkdjNXs!4P5n{(S^G?-QQ{Em?cP z<_(%ZERx|E`_3A0m97iN$P}7@w~hl9koc1ZD5@aV#uwLW zZey%#@t!=Mvj_9huH|l>nVMsVj+=g35H6zy|NJ5;tqCosvJ+U)RS&NDO#J5@=S;#g zir%5&W97$Y$(+oljb`v@|LgeW(Z`g$z30_n%f{osjLVnbhpiVS>kl6%h8naIUpNNu zLKEVA-C73RY;9N=KQsg}BXwk@zi>wvi+%vgYLF&Q;+&?Qdz6vZ$tCI)i$T} zZU0dylV39!!=~Anp2k>59fG`?iQq9=JA=1}$L;gu9Y~@i7h@Ki2ioKRR5>Nvy+J6i z7nuDR4;#!jQDt>}s6h)_dp%#8TZvy;sm1q%+BwZgS{F;HGXsOZA^#2r%HB%=+`QZn z5v3U@4srkZsN=Nm@E>-`y6rmfpTuD2+dk9fN`08ZqNW`(;>_Zzj1Tno)5l|H*1c`@ zXs$P+Jk&_#e{piKQvl$p!_jb?yDNtw?m7Vp9i3*M*}rFF-BB1ihn5R$sK)@LSA%E3 zBw-V6V(&ObO>d!N!E@|oIxD_O?tu9Bl9oZbqj**c%}5tD20FX8J2v#8rljQjXaT+_ zk!al>*WhF=!CI43(BNn#={|o3U{mh{^qQ0T(*J&3z_qId>Q7_rc*?D=zV>+4{( zkhT9e2xvYsQ&f3+{7q2wCg(p&A+4J~2bQ4cGMikVxlO-g*l<}kANTXEHn-*UWM_mt z?(Z7wxTPblsS#EpZ2AhP+x)w9K99G#PAoy@QdhM;W6gs?O=G#E-Ow4ea$3(=7x?g6 zsA#RNG1JOdMp1WV(@<+l+Gq*U z!0zxrTCXp6vyHD6kf1m;WmA_!PA~tf`6N6@(HxCUyXtmj_~?9t*=R8u)%u#bph5Jv zEkAX-iX9D~y8Hp0sDVMEXc2nB_>lItc(0s;_dA{HyHMH11+gPcFj@@;t6{Ve^TlP4 z4dLLQPI8sCRn!u&B|m$JF5B5ef-H|4T`E~)hE4rP{tIma*>Ki! z*U#Q4YoxzbNIKwRdEBsr+(hXns5}O1`P(NbjpU-x)lDler>+r6=2V3~{s_Z+7;J+k z!RMK-i+w!6ELGj2%700PrerA*4njk8i~xv*P-}=))UoVFaET7jpcI3blof2NeWI}(?F?~A{H z-c*9l$^F?)9&t2qwVli&o>L9oPt`1YNcHnZ!2vDpNm}ZPpVq!qOxjC)3x#$+yA6yUrq@c6^e^An;CCvbe6uV_Q`Hxy%LgXdm&ow>!eg3C4qc z&ozC}>iRv5x8vQ7xHyt%N3gG$EEY2*hkvgNYhUo?C$|JQ*)p%JQnv3=VyvSonS9s9 zcm2l1OD}aN_xoVs-{PgF*>A>;pz1J>pF9I9tRJp^wuSl~+LoNj{E>Ne>lyXhv>Hf7 z<~(0nc+WzK%QYr(Xm6vPgb4(%5RJM$&Rx|}9_!o|Pd}L2UfM?J<>2dB)tIrx9bEA> zqo)-^oR}b5!UVhLVj~nq*z|4WGaOpT zoyWIPIpQYu)Y%uuPU{U+0A3rK{32(ivf88(7eC!tQ#=lp2`~n>;XUSITxTs*Jq6cl z)Hx|90ImjT>^f}sX$!7Xj5BpjFWPR)CAS_gHz$#l7nRgm4uNuKXq;=a&Gp`FA#w+o zr=R5^jngvsOCT95jTQI}Cs=o~lhs9!^ZW>-x-t(!95Si-&n5Z-PBOU--1g<~5qi6F z;eDXC0q^H%EsaLQBpNFB>xEPbpDC+0Zv@MfAa2NNdui6tsN6K-w_rsR{1i&3KR=x( z;luhv6&Cql&uZoQpDDsP@V#OqN--(q`ReU1Hx3!DKhT|airw(%pZ0kY`Hd946ayMs zOEsSR<3XfDgHq}$JCm}S@yc;=gnU7Pf!yIWjU(D6WRj+-GtlgajD^ImU4gRC1@oh-Ete5^{ug^u}kF2cJ=jKknTRSiF zgU!#rx2*SHapbsRnH?)ZpW^$mr5mW4>Mlv`x&LI3=-f|2Hh_80Nb4C^#$uEVH>}@w z7n$|_T!eY~0+X#^Lh6MzBRV?C?u6X>+Flh5%Iro5?e`c++fw$G03$@_gRd9IFspZG zl0_XOj${V6m_+Mv$7;6bU$zrOzBWm(Cz>Iy`z$b|oNS&fpEq{nm&>ymzMBR3Tt z{Fle?7Q&Nvew z_8rhB_~|w`vxgK)o@!SAMG{$xWzOyov!wdfA@`dSU$ilPmNL6IJ{e(SWC2FOg6*7P zkD*&b<@J}YU$n`G{VX}|xB=myLc)U~`z5R)4y_Xr4R)V^AoNsS$CuzGL1DHj6}1(e!vj1V@Zjh!6kUj}wJ^%{}x&HMhl zVvC!gn8*o+_+4eglp!T@B0GF;BCRhgEZJZmY#q0}sY-phITXmYCIVd1p{utkE)0v; zhupuJ8n38cyzHhC8ZKHpOhHbw&?7T)IzG{gmHD3`-h@V};I{6am;7=y%UBQ3$N*a% zXv?%Tc0MCGL$?EQrMZx$q8yEpYSkeTL)OVMLG=={j7A#^;iO`{!y*`j;KY7`b@l&^ z;cvn=`@P&ux2W-+#O1r!5W2(w#^gL&1f%*M?i4FC)7Qurl?Y`tPCTdMCfum`w%}qIxE)7Y)WWUBM!cAj_I%61sKDVXnIem$_OmCXZZ9I%~66&q>tADiEKJL zIwV%~5S+5~4=TerI_}rwTagY|F!xnoL#SgY=CA~Jm1qB@MV85N)T*rUurrNuIgK86f^)+y7^gf1rrN;lAb9* z(jQtkV3KPv>fv49(0b7y#^CHWT(rlMIv&l zF6dxxj6c7A=CSbOzv*d~Y!AG9?QE+uu4uN}+@AK;Kg>lfuEYhF-dher2PZ<}FrY&W z3tX9a2-fCNK>r;L8A?p%S-3&YStvsISi&wT>7w*8!J{hSraw)zNr2y8DsRvKw;{Ol zC;!CI^Zqqw{N+cidVcY`e@WsW{flI7h$h_J(T`$ZKt7{C`${|TdxllwtlB_O=+#5_mOHebDydOuRvL=yp0h_p-uGR(8 z5GdJ%hwgRAbHs*5da6?S`6S45`|B%fW+Fqug}!;kxsz4%RgM2mc`^RV@*U%=A+eq? zMFZ`VeVcc($XIr=+jypB@-rYD$Y}Iz|4c*@Rv9BsIOPCZfl-FWG5~Cz?^7h&`A}ck z{3gdk=~C=Ex*p*F#4OST{V zP5Fj+e;C*X(wPOAGs!2h$^+^&D->S8peSz>GHRS?jp(SzS|d~-_cpz;@7@HlQvS-z zwUmOjtN`y>;4$sK0o@?=1vDw0pP%0|N}*^Gq%c#`fDO;yW1E~y8P1BR4`Iul+fOe_?(C}oZ&MKhhNu#v z!CKEtIGTix>m_Y==ur`ntd=ExKaG`jqBXn=g5$4mf;$r(2~I=q;8A50`OPA0rUY z_p`7Xb{oAW+(PjR=8F|naEDGi4W*>iA*ede zm&_H<*s)35t^4b^wWpndfdQbBX}Vl*O-dFNr2AFY^ma2EMaU!EE=D9yg@J)l z7Z!LNPZ|k%wq6|=`)$<#g226%{{+6;oa0!9|IhI!$mRKhg56f8BmDUDQ z#j!`aAtvN$=5e2i0)6*i|-OZ}Q#8D=|_1r@5VE?%L<6gvfX9!A!rG`N>pYv$9w(4U{{!#iESfna}QY? zf0>@tN0ARojXl>!;e6vhu&uM9Wjl6dzH!96(wCd=gj7r>t>W=`>B3?qkFdP@jTI2Sl-A;`W}ZV(Xv6+Mn|vBL35I~ z>x#$sgbJs3h4YEaQY{CW!M@*i&H{E3);t^1pMNLi-(M@D-VDw&oE+}HuxEMhEnWXw z)SP-p;h(0Eejh_XLhUFUZ1YD(ZZd_3Z4@v48|+g!Zfxj4A9UzG4HIfeajJbe9- zK95AhU>8$wvZVsq7CEDh59_E~k9xfe-aD&O$c)+`D zVg?Qjwo7v#QY^EM90%N&iC?GX&}E;$v+?gObhOXp)cq_mDYl6@QiP=?RBgvX&q2LGB*R%;l3{79wTgrRPbLSV;n~Eu$s!0-R}^u+3+n)7zO9 zV*NelI{H$aj4IoZd@c-@F%_C=1B}l`rC4OyzPvm;1B^)i@ua;TMH>rY;ci+?M+IY{ zu{co*cowW^JH}RO@-I*x9v;l$aGA}iVaG}XuISos{)K2TJu|a1?#?^2{W!!-(yC9( z%gx>0-5($Pyn3^no1IqcEr4t*cJV*7!}RpD24H>%O2k(n57h(6@+qt}%4g-`Z8W-1 zJ+18g0HTzDx{|7zz^X~t*47qKVlMr)0eTlj1m$}rmL%1rb)jzWH!>w()EROL%U`QV z<<%z35OczaIB=Fn`f+|TsXflqN>utZcvD;oTMaD-hM-swQRlqna$=4)G+N*7@JP?B zYix?+1j+5nYo4A42&*U12folWJd6RVVc0od>`j@Alc|QBRcmaDK(2@rDfU{5+iGvO zmR_6dVt|3`-1SYU0bcgcOK_eJqrh@gCHF=cV^Ut9>Xs;_l?j3-LD&37*W+UBSiO@< ziz{ut+)RnUwPnPEa}&{Q91+R}@9R91{o3Q8oxDH`T%+APw3fibXL0*|Z^HZ`8f_bm zn%f;MduTt$p>ocNS9=tmwP9~QpTKpcS)*4aVc25Px0D2P^Tqah*Lj9 zzps`||Lc`MtaoyJkML4$KRJ;8M4dp#$Z^Vc9Zsm{>g@c^vI5#_7HjG&dO&e}-}hR1 zu4uhmvj6eZM{ZJF$6f4v;n809rwUUuIaUX62V46mk2SGw9*=H#ddN~bHz>X*f0q38 z!D_e=IX8NWoW(k!HIdMS&OIh3vH{nj9waK$UfMltxElJ)t0=ctNp(KV+apL>!}-*E zlvR*fT_(ulYs)!IdggMrrGA3bUs|I*v-@9l6FiK3yZ1i6w+|Xht8cOZ41cx;3ES8g2n7b2-J+=dN7bmN=?PV)@` zUCBV7mM!Rqth?c1H|P&ul*?anL1)~S^w2zd+W|y|*&cL49$SO`kpxIc*Ga}BLY?0b z0y$w&j{r?tXL@}f6e2LgY>=nD}&@Lb{`a1Z+%nm(eCR7~( zt5AA`Y;>-kmO>_{sGw6vp*&GUO0gr1XkQck&_W_PLQWEDd6J6ppA$Y0m|OUC)9`}?Gtj_T z5WWc8sz}Ac#+#bb`>u_7^|sA(G_)K)uB%=|0a0zdx@kN~+v37)!To+^wYB4Nmv&T} z(#oMXKLdD@>2NISB<#%Ep2skNcO4}!=Ab;TAaBk(EXq46EMhkmoKUJcd@gQ_xN~~>K2X-)Iutn0i91Q%Cg87h z8syD`+N*qNi|;5zj}th|;}b_}R3e=C(4k$_*qG$V&qyaTZ>Xk4;??{U8bMf3A0s@o zZfk8s;5-Yr56aw2=C$gAyQkK2wm+lYCvlD)=?n8)bM(AW-WeP^r& zta!>xCsA_nG<%!{`H1?E>I+0{dksEitSbAp*@)c2UfeG_M9ou;Ov znRjat;Ez*|SmDn&u1v@dqPYQ-9B|+RRR}IIF)pfnyds@DA$F39@cMY(af>Y8hfLecIDWRmK`!mBI9dG$07eFX|q zhN}vce!e-#8viJ;c7&C7s4T%toANp4DgyY#4Lz1sS4UWo;tgw%q`>1_`l*Lx=owZa z11&`MaiKGP^WSm4Y2X#$_V2o`>|y$0csyuu*_)?vq$zyV21-YviTa>8l1wp=c7!w_)e{Ed%cuw!94J;UmU&Ep!$ z+vEY)XO-t?7RQ&fbCaV^Xfw6-x#uMQ3*K&(?b^>Uw|p`fPbBrpG{(iZzeJYK~}I}-s2NN+jjb&jE;?qH~PoeoN2g?x@= z!V08_2@)WrpKst_A?@oskTV@EPQAe)Tcsoj2eC|52#>ZT2eq+HVF{j57~;T`TcHn( z3p*)-d?lP)HlmV2h8+f)^o519I;mHBO1RY*nE&QP3{C0W&cRw3Z5t_=JWeo01zXcb zNKw&-*7C^)6}B{4v3HHrEJ!L1E8BoENq3nq5@BmbR+f>sFi|c4$JAQ|)UkA3yTO7J+zC!_cXxMpcZc8_2oPL@ySoNixVt;SVc{Cw z;q?CAbMarmbyIZDnl)>TXRNU;EN%>HR-fZppvLl+hP9056H>v1#pOw&NBXd8oC-g2 zx4t^t{GF>~(e#a~eN6g^xbw^kR_GiMi*hd1NMojP-cd*8+N^t6=6n$1`|$mc;G+6j zc4B+^l#mnnR4MTBPiS%TYIdx`ohfe3e;Aey=Ljo)GQIqX=~edoA*c4QleFxN5Ac@t znU^yER7+r;?5xhV$L7Cg+vCU955vH-%D?((+djF55o z8V74u!A&omxdLx&j^VIFp{GCJ10P3+qS}Eo1_3#2=6AwMcdnKsm519=%Plsx+-Grj zzam1Xx1O83=?^WxSxwFA+KuZR^p-Xs|3kgV3ePRJKizK;2SJAv%WN^o`Uiq5&ugz8(4Gc0=6=gEQ^2`&4>L~gcn_JDhR~QaNx5_hdS0w;G)ao7);3{TH1<;~A4hTb)j<`cXu0bGHZhG|QArvm%GRDFh2^6N-Um4LPvp^boZfgQBS2wp-CL3(!azdM!8d=dJK;#5P~m+VWwUk&bnwGX&9 zSncwE0m7I%g)^|e5hz)z2?znxV5h(rzOv+8|NFndaOFP>jFzGIK42U9LM$lXv(hS2 zOdcJZQ@<8Q|E9e^!@MUqZO9rfGbl@pjF*{$ZEH5qFKdbegOnh>s;P8SCDjRq{Rf0B zsn5r&ZaUaftwL|AOug`(n1R?G9_~^()aCJn4?DOYUoV&Oj_1`zO%x-2M0Bmt=RJa3 zb0|=-tQ5qVUs?4um(KL{C%j=>U2~%3w9!dmK@-cwr0t*%(HXh3pkekTNc%Y+F>dLc zre{!FC56>cr4I&^#(;1|4V9);w4BPhH4;i%ss%K{v`H>!jz_R8(x(F|*38G=UGfy- zyfJ$Be!F^sNi9>=@f5+q`X}@>z439I%6Iu_{O8Y$_WFg!DXre-8A%Lmw`$;Zz65CU zZ~BvyU&5Rw+OnZC&t)Rqrpobgt>MGc-s8aAT`BR9$*k9@lE8}B1&xcrMs})^*6t8t zxHe3j^{f{ufw1M;ke%&P_tURC9M834qLwxnISaAh;O}g}leit8?Gr=xjm=IgPE1a1-S82Cr6`aiABl)={t!L9Dq6^Pe?zt@|G6Ie!Vm7)j^(~$ud2*!G;ovtl zOJ}gLsW^BsaX+i77b*r%23Zy@Em- zogv-%wgmDE^iI%%aXxNsqT47IkJt$|0S7GzqGWo~VHU{HjZs?Vf$R}?g%xkFW1)aXl9hDiM$6^FhgFSi3 zKEOwkW8*)cxw&T}C7s^xeRJ@WsnZQOmDU=xUpP1gt{o+i1A)K)^2L6UiJIfOgv)3B z=lcXqAxEdDzH4inVgCS#J>;AJrEl(s@X%h-*HupJn}d`-f8J(1Crzpq%-q^E^b(Fq z7$PNg{I2N!Wdl1kuII*!p>JnDzo=DbJX1r*#4+B2Z0 z{y_$P-pbgbkMgFuocrBt?QZtUYqFA$YmNJ#U$9=d-i9BMd$YZ?@8uMD>N_}{=!!7h z@tO1GZlcDS%MiR}Y4>$=*^BeU{gW9rN-**_(rl)m+^Li`Bx_zjY1I6a7u1vS2z4qI z5E+6W^k=9D1oJ(Y)vwR{#IMqrh#3VZs4eZq>2YToUD|OXu~eJ`$k0QXzKJ4aTmZ^* zPamI*o|?qjhEkK`zdN$(5IX1;S+9a4Y|t&#K4@~LJS;k%5v$ayYRJPw+Z0AQ;Xi?r zG;UFVrui{lFbkQ6(u-P10~?A%JLj4T=4iKW|H|)t% zp`(4=dy|aDlcDY-Y+aR=apX+%EjQc)a+*kQ6seJbcvBd&;eW^o*?-{t2{|_?t2jTk z=^71+&osmin+0p}PZk);Sxrm-RCZBSQ$E*l6^D!?H*iRzsOqIoQnnpefkA8k3@A=I zK88{*NuIpiW5Kd8ZdaL~Ho24_F6d%$v`S%XKAE1Tez*T8;p{sc;AqlifvdiLG)fv#X6}eUC$Z+CFLXPZRaS z^4=~J^YQxlRN779F!tpyCK~&D8M!+~iXgPfU}e9DmAN5e%rOa{)JlQ55L;_K`sLY~^zkW=`8OW=h@VWX zq;oR_t+90b_7xltCn^#nn$cREYow|M&p#|ENz8Q2k6ct?``ELc1jxb}Dui5=-x>7# z?t&o zw4PoF^Y8BgrX{#ReX&20D{tkOjrIX5wtu%n8LXEo|Vdyb2aHJrfX?T z6 zVc{uiOfL0sZozhZwW%wteDo9-toi!X*fo`7!oOTEQr&_tQGrhP-EUFPQ@`k?=Dml1 zwOzbAN9YmFZSkgbyQ`ub z$D@+3@K-bRCLL8OQHso)xO1YBSIt-h8L_S%Fpf>_EpvRv?&m`-NkaYk=kHv(C(m5D zru6tE8-cI6uYw%Xp1wWj$F(R&59cHmekd;)Cus}Hh@lL^!qQXWw=e< z?y9p|dUUqUh}d*-#oQc}T`^=JvDt7Hnh7|!aUIhaukwlcp{bes2_s!jO@^9y?ru?5 zh66iiXXnR%JAe_}s-)D)%2Ko1P=K{+xUycE{#=*rES-;RgslV%D_D7`N$bpunl!C3 z2t;S`NIN*A>DG~!zT}ILY}>g>L>cOF9{tkhvg4rSE=w@hDATi|ZwRxqi`>6>?gC#; zj`2&3U&_q%ah}YbjIMdX*22)KY&Jj3&3Tw1F@|4lEdG^0jBF_wBExvir{ohW!Dp&O z3NGSR63aN~L`G>7Fa`#mN@NzINSSs}*!y(I_e6cN2E8^USnqOEorHM{1)!OI-Hl?} zbemWB?#52%1Tlx8AkpP99 zh~uKA`^`btwj<4N>!P?xZm$rzA8ZPx%vHWC#}Xw{3|~n1?}!4cgL^HkR$=iMQ(L|| z?vFGphZYf+se`f#=8#xFc0yfo2%_2jvfLR-5`Rcu`QScYLW}IIes)fEPNBuF)hf69 zjNEyn&qIQ=Yro^xqly;q0-zneY~mv8Owt=71Efveihp2p64$aahP;sJHw!x@p(3Tg zOpOjo+_8eOTu<6lokIzEWADEI@d>OB=E5)P-Jx^FN?(yskywqUb|(MrvZy8t&(%j& zbR=@oN$BXm#TKI!XnK(JQ3HC>EAM*prK?;DWh3TeOuogmkFd+gJuN%^dPug85z``u zq4!*>95s}Q-6%1e?7+udbV0V>yj?5rv*r8|51FLFXPKa3j+uBQTC7t>7L?|vp4G## zQ(OLzG6br{iWD+my1Fq4I}@gffS#<9|Id}m+CZfQT>190yJ{?@HTH5UdC6D4xq_l*3B`JI)NDkMC{Q~sN0<<8-(%Z(y77bNLcIIY?nCyXO8u6GRc_I{xwe>_l@Csr>FEtP*qnV4vHY0RV zB|CnS+jvNR$35!%+pm)sJSHeB$Z8pgLD?!Tw)Bf18S^tQOBo%=!%jt(RN~7vdO68@ zX-Ns05!xYzqRK*Enf6#ifQ5y>wb;m4x9uK?HehV<@(Rg{u!TjZsSIuA{IKCkOhnK> z4iSomW<4uvNu5pXb3}SCJ!X-z4UpC?Ruz6ECLUs#g2Opc#vC@9uQDPuho2s4lM5DT zy2m0Yqk~Iw;0$jFWg6;17KJum{yg4g$e8U6&WxhTH|r(HoF*7Q${-Y$x8lWb+&8qM z$bJ$@`=S~+*}Lj@gq#WPL~=GS$2aAR_E9_ET+xEN@Yj!u32ZK!kIZ*PEPC4|mP8cD)XQ?Pl-O0hQ!A2xV3JY8#+MMQ9l#DX9~_uhs*lUEp>< z1VR6Gha(BtAU(^azZ&K4ohMh=m}1_4uMoym4dh_W5=~iZ5auxpfQ!3kG;d`@$)XFj zHT9z|HPOizMM6jvIz{R6xm)c10v4Fa(flj=a791Mvq!{!CYbCF+C zFl0_58(V}=V4Jk%do397OmJ<3O!$ovjO@8x8a^`@BM>1E6&Dx&iT}6CN`{)Ket|iZ zbz)xiC+FRcqZwuKV+_~7{*(1S;?swqXy}lgDB+m{O{+fJ1#t1iAPw@N*P!TR50TkR zE7SIGhQLL&Ie)nh(NWhYgZah&0~b@@@0;4OIOV*gjHF?+R`6>`(iP zV>56JdUz*%yC*rpiH*erAx*uI>#Gu(zVACs?jIAi|BgG}r&5Qjg&xemi?%@h-hLv$ zaMUS|A*ux}Wcs_GI)AFu7<6bh()C<_^5HiYOUP&veJz zm|ZhEKlbMU$K3wxd*lWuTSe)D4U`{jaifOEAsb%v&#d{Mw*8Pq3Ln`=1A~Jmyy$bE zz15eNJO!wRfwpp1g^!g?m8|*OH`6Fo(Sv-CuLYGc6x0!hSl%_^YJT$7jx@XwM3rBp zILs^JC?U*;IOCac5C}#^zjgxAEst~T;-q>WCZ_)G%dt+L$9H!R(^C^j$jAx`ii%1K zy%Pfwcym+eay1h6Vx;&Ek!ObVb?syI4k8P*(Vp@&>tJ-~$NhUlNw{T;NCF~KN|CyJ zEG9(-K9_ilD69O|v0}P@I1Ig@oVnut9%L~I4RrLqattT2o6qEV;-ZYLiJqMA5aBs% zi6*d(28|92oF^U#@}b{x5E$K~qT$Y%-mHHN_c}oIWPh66^XB}bkwzt}aY>)GnT9vz z?B<^%78*k1N^_Q8BrV{)-2=exash*W9MK67T-f<`zsBViuiX0u38}7EnNsLq57a`}y8!1>=tz9-6NXDsIK-}~9&4jaw&d=41z`(bd2kdJ zl3Y}vgzKOc?Ihxla5$70n?o7R04Ioh*!t1?{E-Vb-5oW6NFIckR{>x&+Dt zh;)}(8hy$^SsN%9cez%Tw|AcQpj&a!l4`c?iEplI+JQ~*qEt7Tk=^W^3;SAmSS7og`yxCh0>$h|JJqKc&`Vp1`Y0UVs7yfcc}X_ovnh!hZYePo!+?VX zO3r1E#x}X95psJ<5`+vGjh+D~BQS}zoUvl;w! zbOLVhp#bsdmw;Q?V@Ci61_Tyhw*TIMF6yH~iN;x_p&jK`MxRN5uN3Qkq-MeSefL#K zyW$hpYzu45V!}Sdrb%eNL%OjEQ;fO`(E3JG2e*!K##OhhxRyG9YKxRK(!D2FNCnfH z?$JP*XI;V8^>CYke|Ut0lcx!c0#eZnnd z!|~|zcRozG+61UctCs$rCE(U(HJOVTr{%un)c1XJT5ET7n|#aZe9jjS{ApNuB80``C z&HBon^i6mq9huvE&sGgm4eu2Haz*y#N2NjFxsj$=6yeY33#m+(7SP;w&jE}cGAPjFG=vjtHfLN@hOJYaRoNK#RZGn zkr!l<^>{!Ai}q6cnZ!cV1f-R|o4h|D5gr##O=9E(uzY9kBeQ*GK)(Bi-{j=<*@`4| zb%fSn+~lBSA(pGdWVxK)XC9L%7Tx_}8X^Lulbln_SBO25VRh0e4LS4mzl##iiD=69 z7KiLLL6BOom0p~m2v>hBcAKA3H2x{GBGY!$Sn3hqD@v@d=v`>)p}`^=@eeJr`P1xU zLa&lIgRB=o5$7mJnbpSuU0uW5=OW}>NNhlTd%ncUy${kBH6&u&95nXZY=GEnx|y3- z#f}?v`cti4U(nKmBe$CTKLo;k$Ia9lKspD`m(7-w8UGDR{&U#^iqtPeg0Jg;rg!(b zc!U>b8W*}&dmsm&f{X~A^#~H%O^g$vh@38rL2!PNX=WlVTVAah=fA<~3^ zgK%`qW>*DsqMTP6fXW*#L~R(?)!Ps5$7U0rcl^sR7=I;1Z7#e4ilz2f-eJ3o$BWmN zcQ~q;hi$~BN~h}ETMgd!3a!nBtQ^~mwL%Eo)QTqup_w~>;##C?Qm>m(gS(wudJ&6T zV~ctBWUR`)$C6W8sb8nCIXC)?|JvTGo8n#>mTM)NI?csRH!-uVivzSyak|NyNDTv_+c-WaA3gVTnB>XjNul@Z*jBut z$*Ch8oHWYVJUUGcrp}7ihw_@IbdcEAnZBpV4S8T?*Hs2<{ZQeSJ*FCj3da5It@CG- z)472`e1-(({cuIsRrZAwLFt0v8&7MDh&Wo? zrbUYVCHLu)rZIYo53zD0YhHCKIFdQ6X7rGCZtwzdM*>h7#`ZH-M!vsbs&C&8z@!Ep z|4IG*X@YrZRfLrk6wbH0KLFIyKy*!Lmp4)`ll~UIPP}Ete(-NkI5|sr%wk)7Ti1VK zuvr&l6N65ar>i<##nL~`1lIn{c!(9^^ulvW2$DVRYxFJ0*CE>%R715$FG1$ z>x$$A+4*PGJ;>Y_hB`Wbt}B$!==|b+Cs4a{HwKdNz!_s$y;hwShkGWU1wOFBP`_Ef1%XXfAb!n)UVC!L#x8jzu=P25r zVkul!B?o~I9|TN1VVHS3)pxHWLgj}3a?*L0u&EGtJP0Qsof-yVRmI@%Y{1EE@Ol2r z8p@HEQL5p}{zv8QL7O;PW|`2YTn${ztmj@M6{q7 z4PpfSw_o}8M-2{(+6sbMKg%4+ke|X3D#_~W;tay%1P$zLQ=`Opcwpm@zI>_H=iy=L z^|k}lO93^heW~Bs4qdY~?@BZTa9sXsaGiPYicHDKW8}k~eP~lCvb?fq^k9)j=o$!} z3{CX7Hi;x`5Pi8cD?GfhY`po?&nJTd5i7YF>+ZPQVClv}&W`^BQ!VV3LOJ1{sOxc7 ztBA6>Vwh~+R|5^Mj9M~cQYjoumX$8jvA2?3qTzR*eQ+OWF_ayGQ2vP)7RvyywW;F> zzp5t@v|TtKrZ?p_V+sY$%R-_6lHht|W^g{fNqU?K6WqZD1g;Pj)sv&2=oKvKG57~+ z1|VXgWNF~dbZlvU8V?Nv$?Ag9R{*7k%bq*%e3b*(F7%shv3x1p2{Olk;OSg|%lzNn z(4*>QN@%T|VVm&wW^-3tD(dKw>`!{J38m;!9`Zi2=PA0+px3i_c5ZkKR*bD8s&}mV2ROc8Y-M*JdImY}xGEC~s0ThLtRC3WUi}Ibsjbr2 z(rL;${o z5G}~yCmkJE*Pjls9v`pYtGA_jJMn2+R++ws`#|(x5<1h0x+Ox+IKqsVg>U%2UolLj z#bbQFABv@EaOtCqc0%e#9780^4zJ&Cw{$NY8T}=3pqH^14?MK#AV1>cSiI}QL z%lOpjU{f+eB1k$^qOLa;hd17-kZRC@a%NvPFxr7}&)zSkNMS;x z3fXM1%-#K=t`$=+-`;GqGE1;^py>Sk6kPE+EJe+(`kZNIXo`FbK!?;>wbyWBerpyz zx2f0SsglO0go@%6p8rbVSPz90Ct7h%@r5Oe$=xlU^=Y+`;kGqgPOGfXogZT;cu|Uo z2tiE>GkXRcPOD3ryg{a!DK|=nw3WDO|D?i%CzUog>m#@7EWxl&rX7WSTf8U^&A=X0 zg({u>qk1W|-9b32&1C5-vMws2g*H|;jJo2lYp3$N{j3$vMwbwEb7juYLL-aUaAAuN zjuucgt-#&o3jqEj=6{?!IywSOQN2H5|I?5FirTr@=xBKbg?h6&*AQB7t8gf{e$`V2+!k$M(AqMbnRl0g2LD|%z`sn1$z2A=kr)mlw^H>{k-AyIaV*8D-JdUQu^ zp|%Z7fP_&YMRYcGKrZO;DuWVQ>7Q>|9B2%~hb102+knQbi*4-aky0tY_q$t~`on}f zKV>=ZtUiS8Bd7iSU?cZQ!!KbwO1y3l%Js^K0FsL4%>?bO-@rp(RXd-eNo;rO>lDr? zN!j!%l5Xj^r3kghp>XdHj$Y){@AzEOpZ7Us{oW<0MmqAuQ%3OdWW&fK`wWU@+^TUf zT$}D~lm3}?_X)oZtmMJb$&?2p0PxpEgQFwRzbMMs6rXshObTG`qH6Hg_@iL?dV-R*udnYLl0XPFmgorQncHIq zxA`Bfwv(95F1GJJBl4KxG^x#Z3Lk9odl98H3<(1(g~U&vbx4Y(GwtHpMNlMUDI&5k z;0@-Y&ReHO+gEa+B-Si9|7*oVUvk<5t}DAgx-n@3T4OqYZut55oB+-oCZSC}L3K9A z$CG22SQ$9#NVq65j`t{fNE&*4XO~dApxu9Stjctd+9;)7?PGPRVHkB#ic0{DDvZBbWF`s(w$A~<+ z>1R{@SrxUmqbbKU5%e&TQgMy0#omGr#12n`Cm&kclt?ShXAWGz z%(?uOC4~Ccm90TxpNMBfPmDgsK)JUOCuViVAge^h5)!T)a@7)C1W^u88?;K@h@g?t zOS8r;NteI!w9zD}I}f>yji(hh`ly`*8P{`#Rpo;GO>#Ju`xcW5Ci~Mexg%aly3K>V zd$3DlP^Cch9kM?2oiQ=5*U~CG4iiP9-a->*gPEC`RNU9>@Y0h6yXNpt2NSjxMf|1l`))>->y-sl%P0^>tQi}f36Cs_H(LH zJhfl(>G9mTpSVizPvDmimLM>Os8S@b7j%TSSZ5>FO5{eRbof{L38)QfN+q^fmJp0& zi+_JFf4lVWj92a#H#+GB$VAv$AHfJw3;WT^0}+j@BiD&KMFt3zA9)^K*`hU{F?Wi@ zZID{1ja1fEZD$J_&lJnZ-n2-n>h|1l$)ndgzcM5KfDW+UmlaxG`@6`&!%}Z~t~=FG zm87`Aablx0H@D_>7c*@iNKMsH4&7*~`#AyhTct`4SDjXWy$se0JTpeVnLiXk1eXdI zpp>shTVtb&%E1jB2nwthWwe5|J z1pe|DPGJk82^!V{TF&D?sjkR$kD#cYX9P%#@JNcnLPIz354~{v-F>|}gF%OgqdaYp z!2Ikz;pJp#qrgL*Kxsjs%-Z*$fXe8uzG2}MjGcy{XzI!k<-!n zIuHJI5FkP+pb2Xx*Gwt?a05lteK%-75hc=}Adf_X67}~)bcg^xy=#`V*r2X#9o#6^ zi_u=>pDXN`v6B(i;f`7z9plBop-;Z!Pj{m_&o4>_E9~(&O1-aglBR3Xs{K7CI%#^l zIhQ=;WibIRcAOm(lnRXjLpW59=hw3-bXDq0JtTDA1?gWvaG##esG1AM^lv7W(@_jU zp-qN62w%Dksba^K)pNuZ2eqFA&He^93LOI69Tff1pO`EjxUJ($Fp;?Llu*(dD#e1e z60+Ij!TM2`rLu#_C0*JD(d# zqOHn5!d^X++Iw8-1C=8Z*O?f@M)+rAgPOy2lE;P+?AF5zsCINu9n1Pj#3RnoqiNhp zTR-QWhZ>@8jEFG63bw3PuZDNVLCpZ@!xhntnYFLtU6%yIwGAg6EW#R{q_a#Z$)}ab zLCCDGBEw-J^_uzw+0DFg)rv8L;h57X^#-FvMh?@@{!MeA3iRx!5lYW_y1BT(mg|r> z4DGbg2v(|#yyNB_B5vGgB&57weZti|H_(Xmj@Lncfcl%Q~ack3~@L_U^Hni6jX<@09x$Gt@w zBnZT))PLOG-SvW_oQ;hEz*y=H9f~zgsErOAcC=u7jaB3g;h)i`WJLkPh}?#`S6hdj zSyASjs~p?Q;>NtP@#|BTlHgL*IK4!-h=StC!Z4|#|D4Z54m;>;Aki?IpWt3wFp(wU zrEL*)%cBqub=zw2Co1ER1ZV^l2w_x-MCg1(PR`1@FLrC~wd<-}_Qyj61AT%&*r{#$ zv|K%pBu;SLMCL|SfkB|kY?d$+7FMO8)=AClsm`z=x3686SS8Mub#If3H$!fj$m2M6_e z%K${MBQ?KoFMOC&KvsB&sl{cD`m0?i10h`5Cr)WyJyiW9yut*NykAt&9IFLiTJ3fR zz?>c>w^4S*A&IGzLwg9guA_)z*@VKAKQtiQuww?;(e%p(V7|}{9NqOwVxU?$+G}RG zm79t0Z_~#+l`rpw*Y$B-cH?O!umX49qts1}I>Ok-z#bp(J=xBwA+IF--BF z;Ht;C1%u%&5Va@(d?4eFX;JJ&whHG_+5R7;AptxPa3F1iPTfRs7dLVIOQ6I{idEi0 zRvdyodsU47Ek?2^CetQ7pm8oDVGMoWROZA?jfjwtP|(lIdVdUWst_1qY1V$l`&uGt zBB@Opu6F77dJw}XADNA9q%K_))5lfP%#mz3(1@-}a<6NJsoSZp_~9vrCfO+2IYs$z zVj|k(e2I~vPvEJ~2CHe946e8)h?VhteD@?~T)!W>roym-@?Q8B9tV=TIhPf;W=?_> zCf`*XW(ii1bw{sG6ai{YTCMtoQNmst9}~#{7GCduh1KqFl&LrxboIinD1|}~{(J+B zLHp3(pa@xTWNWdVLA*1TBAB7z*Z0{ZU6X2A6TK6X7;-#{>+nWlnj2&L@6lKA@Hmzc zFuNh<*YBYr5+O6nmwgj|GU~mV>yhH4=6)=`k)kxv6Vk4_el_i&`QqMWaGV~{%qzHR zP1bK-Ro_NDbj|0{KK9}?GzqFj!7=^S^aI;ys(aj|!;NPZx`qrxPa;WlXR4RNc|XJX zKhchsC7MpkiO2<|zTFPD>T#{a08|MQ12~6bJ|Tr%oFuU!erXxTwxsq;b6 z=mNYy9ngu+jIg2(-_|}84AU=XXMvkms_&3!y*fy3%%-`-f&K8x<*)~aai?Kj07E<7tRwcqRX=9!_A+wmxG7G*80vIJRcQdAc72(6CD zrT!dK_~iY@L-6_Nu!PkyYExNXJ*6qZ9_M>$a+Y}d??71-QXHMq!1E%T_-IxNcEm7= zQXMzB&(|GC!3`?{ZaD{M2>q+p-?B2nCm3O>xN6vO*ic)i7P%%&q4`n#nh|XziKJUztAPxAuqlDz8Mqzrd{#|y@ViPjZ+zDk4lOg#__td5Dx>bNae3-~ z+A3+WX}}~)fkT<#dC^r&8J0q$nW!r>rt!;hMp z`;R&bhomzJ8fIdsntyCtAw@W%;SI)xk{?99AJv!@sJ?Qksj6w94;LM3kN9QK*`1euUsq7HRU5 zR6-qsO;7U1bvw7Uj98E2R&0SCHNNziH25XOd!UWINgVe(si@KtjY=&Vy2qv3eU7Ld z+l5^(M}*z51`fg+czf;`Afab2CSeU(KxO9UiZO7F%n}YN2uESa&{R(ppq0=RJESPG zqBc-ub5xvrJ9O4pyZ+8kW*k(=9~@S4i<_0ybJH^(s~^-Ocn+yVlu(6K87vF1>m{d^ zn?8zIAk{oc{_!eqC=2>QS#ZGfXm+S`O7J1J+S~>FfhXmoAUv%Ci=cMz|E{X;q`gk7 zPPVhNoBm7X;N;qRd>9e^kH>WL;-ds#Q$U$0bUN+&ax2c@Sir{yelVt*vs7Jl>hD(? zj_NSPf+&xxdt-uMTN@C*lIU-QHmV@ZUks~rC3!b@dH!PYH$2}?1`~pa>8h3=zN!ZX$)O+&rX=nO4m3b4WeR3iV2F{Y3t1J>(`4QErRlG0iy-pMq|(S`MR6N$_xkftM35PPbGJTtOod|~_b6AjCju>kYJE5&SY(HOBqnI{vc>Xse!ico@&zeQJ=;JZdJjWqw9mxaO9_l%Ve1K>mOr2@~Pr+;U(9FV>o zH^K%h4Abpmf=J=?fqjs6S31f`N7wn2lGJxfBG@@HZYd$66D)?d3b2^Oml@pvqf40q zhUln=NY_M25@U%2Qd~LNoTV#=PoV+jzxyJL^*XhpgM;$YvI^qemoWwQ3ot4!ZwhQF zmHJMGQOHTb^SEM};-gZSAK%*d9`1%h5L3f*EcE)yD#tNp*uRTFj$HoaUv`-Xk|jVQ z5I`vN2>p-OuR1)TL5b)zxS*>R=L9uD)1{4hA0ZZKSwf4m^1vQjIGIWcWvVntO-x8U zDeRMyC%6cg!!;MY+A8uom(#}que&esQ%kh{7%^ORhQs`a=RDv@=u{WLHIsf3dO04~ zGj800Q1oACMxCtY2aPd?T_bI5VsFqlD4qSEUdG-tq`h{|7hTQJ5p3FanJK40@)*Y8KA3ithhaM!Zjne#fjCD%hv%h(H(_ryj?JoiJ z2Eev402+z)H+px)y_{(DIUqOZtH}uc?JR=wA5o#gZ>s6xfRSkKmfHS7g0PZ_4S z#Zv(@q%nnf*?7mx5EgBP_$qotK9izN!ISi_`l132i*LjL{n&i$YzkUhtajYvJ|`m@ z2qDBoOPq_iyJ~3Lzc$rBtP>`T5z120CLOVafHc}FsHPKi@xvrC6ze9Imx^f#*Qk7U zIIy8k6ivDd4HgPIjcY38fz?u;?~l8O*-JTmRyxU%(vtj4HK8A07RFW%vJ^#_mQwxakr(kyPLGy_9 z<=AqO_EI8WypB?4@NR~SjY`Bc=$4J~w+q`vd7p&$*~>N1Y+04+^}sml)gEytaIRZp zQOP6dgLE0XYaiIbVNv9DV?Mf6;vSf!ZU%=n@C+$sc@#bjze)12TQGT1sJzunBmo#~ zF(FQAMU9Kinp?HLt-PrB1Qn9*>iv@|4wUZWf9Uno2w2F0RGQByzkm`R zo$10>0|I`Ne>FM;_vl2TMqCz}>6cc7oc|x-SILk7(zd{fMQ|l>if`gO#f=*p0@=X!we0KTd>jU^ZO;=aGZ_XiyAD5|vc1i!6&o?L zI#_JnK2{VyoRm5s%}$+xE6Ct2?O077(oBK3LS3}mH_M5u6nzrQb+c<8sth7e6;@f+m6P?Gs7%Q=0+xX^dE|;(0J{Iy+o)hIX$uxlR%#0PV2pu9RS5aI7418< zYx=`>_J40D6~TN`*3m5e02X|7V{nwD$?VuC5V%VUJDcJeix;TOs5?2L#VkG@k;f}| z56FEA_%vX?1oJQ>h_eGhH~KpBPfX@nCJ+{V0hPMpC$%5mnmt5V(`fO!I|4F zVkXshHF4|HFy4%m$XuX5YATmtw>#^C30h8`vu_Mc5+<8DI;BC;|=sR^gi7 zdk~R)1zrQO^#8pH4EpwN0S1pz&hPuuR6g_{HWn8{kboVQ-`yvY3N05*I>6GEERlYj?jjF%%9^0+s2Fokp9K4$dSq zOOsee);Y}B62fLUD#A{qCu&HnWuxb=-l57gc-t!VzDro87mOl9;7js`ic>W4^esPW z;cKRPhFaYd(93bD0B@=?@H39Jd_Z+5?2F(WlY9gX7O1*5MWfXBg9JAJir3Bc{irpn zAVito@VM$&{EU=3?3AKa-sZ*yBWaK@rPI*DCPrmq`v89!_TffB2^e!$@}7yAj(0-7 zx6C9=;RL;RqdBD{d>jknryIk#VE-nhSZYX`+B6DS3QlZ!2;|z-i{GPNY|R4aH5Y*< zalI-9laCcCJd&oKN#4_u@ZTQyzq0vYKO9<2du|As1C%1`_W=$*7|EL+J%1GX!2OZ{}K^}PRm{03p5#w^47|A+Gs3HG;aSKR;q*m}#T zs@Ap*l$P%9?nXdFy1PNT8!5qsG)S{(>F$zlkVQ92mvpCeBXB0}y}$RIF^+%yrDLu+ zpXbgi#9ovh2u+ikog4IkRiJBcAtGPpE!^-`JUNy$HrJF?G81Y7sdzA5&M|~po=UO; zZj`l%Q|bDCQng#5;%#E|E~vSm;|qL3NI$Q?!=70$eWmtKyB@`W-pITda}BFe3;r(_ zd_)X7LG{~f>&t!q_*vm59r0qPvYZlawj)t(O(MOHNiXk{iWdj~@<6NyZqx7$^13 zQhFVfM;)kSzUKJNb)=u1o?9J%NVt$nfB*@c9mgYV6(khea-o`vh1hS&71Xk0=1Y#C zAVL}7qu5l*clp|fw*!Owzu=VyUW|@}E}m-viZ5gBO`lI*JVyMe>%%c`9I(IWhm%N# z-a{izxD1{g8qzoaQm$VnWC=q_-@vmfH0XzyAIhm1K%p+VVb$fvLt^<7=#<~+ARloT z=AEbOJOZf4$xC>v4kDGu5b3p7usXn~Io*d3BzH0du z#!STKMVz#fd2l8y5aPw5z7i447FO%cNABb0I@B6yqJmitPa5uT&sz|dV> znK`$?{9cq6L!;dNpmoYe0GwI#&e{C9=LMy@cb0Y`O?&XIP48K%2 z>^e(7^qqVick?s&YeK>0-tun+nyc)-Ysd&PB5Qw}{465dJbx%u`_XftV|1ga)>)$h zRvy>&r>?Qq{ih%>ONuHx?K-_V2*(nrQ|v9pu;H~ly{3#w^J5cy#+OKwHTTbq^+d&9 zCC~cV_MLwU`GiGh*)n7El?|S#x4KX^AP|{~3x3>D_x|FHdk~tTID5KjoHX?) zWzg^KY$T(z7!`QMJQD(GbmVdic32sXk7Nt0OKtg`U_MQ5Wxg~FpEiYnjIH%vck%|- z54l&%t9j)r8eW;*%PctLrO(0Mk=_GDN>@&fp*h zA0tTn;V9rz!XQ?iO(284FnWm-RrGfe-Ip^O(jDB7yHyrEz>&oML>LM;b-bfrXTI;udQ z*X=&z$Q7taraO6!Hqo{gN=l3U;=am}@`SmyM7)$zR3)i`Q>V5PCuGx3eLs%HJ|p&`}+rg zgc}kPQbf;CTwG*g6;Ui&AI5d1CmBNe2p>ov@;Nu^4CFr-=0ZIe))>SeGDlfC+i z=>kmhH&Fj*w#H{Ss%Pi*HcLF%+RVc~S&1KLyU6W_2$fNnOqW6dK=vMkY|EHK-!<{z zv}&l9q~IEk9L^mDb(ph<4}3*6eHvp6#?fFAls z8Y7qy4BTyTg^tW(_qn8(V$^`E2&`}O&p+Y@^mvv)t5;`U!Z-FA{4T|jHH?ql5Enhh zV~)@>05<75^TTt}g?)u4QZrHX4|>vNxcY0g0IzoyW(<6`%Xr3n@si8(yql0uOMM77 z=>THSt#G7KG7|Ue*_jI;Ga*qhre2L1eBw=SFB~(v{0x?)MkB5bj ztpueRNz=^~drd}Tu9ww|fOkZMNgnJ?ig+`LJrEpm1dll@|8}Q<5LXKhK6~<$ zj=Ois9@jj$&CMXiMp8BmjCWlBvDNRJYHJ4(|63{#Cs_K=`zJl7GdZJQWYmd+LYQ-iA5TXS*5k!5^Q9WtFSbnmJH+)K`D|}DDi8}QRC2_CdPofdFfbLLV=j00HnX0(Sc=LzuNbW zV)LV8V_)2AUG!VQGVM4seDje8^iUb?a`SkUjTZ&RnDb6xxrKKwK&!0n&w_;VluXFMksjJ>_E;s zy3dnJM7XFBWJ6AB_e(Ae;%BR(^g4|n;S<`@!$JP#b-9X;1qX-g@Tii{2_A~Sc}edSUI1?N%3eJF_7gfUVCRn&#R zgDVAR4q*DQ+Xz-7ik17(Uh4ikpi7-Q4hHoLJ^lr(8{hq@8sS1lhp(DBa9_TP7j{ra zV0Y8&N3mR*3O>|U>@*D%@{XjDi0`?)C8{eT`d0E4QlJEP@?&L1QvC7ovZ zUQ~oWQ01CiyJVq&LiIUZMJ_B7zf8-$oEQ01VotDxga85U!)+LW?*=a!s=mmRB`&%(%%!khY3s76v=4S(fd*z%&H{bfA z=w&A)Z(C0blY(7R6$orJ-G(A6Gbw`#_(}Ynf`8444{)t24@w0pVWoK|XkM25(8?Mp zwy18HedJ8AoKV1phPRzJq3lC4$EzJ>H~UeO$hQeA$%)pnn0ren@aUR8%IrC+V@nft zP5?l?0IE&gaaPvP%F3beZ~*Q=F68-Dz|JtT_wl1AU@CH!`WpkD9QG_RG)at>9gSv| z4z<}?4KKQp6TRZy2ASRTk|^e9UtdUZQ)nc5agfV=A*G%3Xmdn@%Xa)f4e$ugT*s1j zmZ`ulK)>9w*hFB!NUQ#NNOE@jR>7q&G~g}!6ZSXS)0_vusS1J7w%W3lKFM0FvM23jfC?CjlW3wJ8^IXhGD~XjAuvpOb9K6#Q+H1 zA-hROB#9ox9{WJ1RbWya0p^?Hs~2Hq|C<@S3^xXP@Ia#v=VKdZRtCR-kpOn9WKn0I z7Q)$~+pRdj(yzQHl?>}M)(Hr|g~`dx%ybVwV(?*;G$Wz3p($vMJqOFg)@YQJ*bLG4 zYf#B8ei@8G9XFr$B!R7E{IVUb%A@MN!7@tds_@?1nJPSFC+4oGbLR0Af`JMLUUVq+ zW$UU{MP0cU@Qj65n%D*S1h4esrF&xDGOor`yKG~bnrp~XCniPUI_l!ga_X+YW)`!-@&YgWmA;>!$Tlf9>X9-5M=N?55x8;EgWb%| z4w(wo)%v}<{F@Rs3ca@lxYDs-hdM31NQU_!3D(Y~EZKSaCwn3DTe2ox&|L6tZg{z3 zC583MMQ+B+51vBCifBJeVr5C3+&NkGWZPwjecYQ}Ys3oRMkIg!f5%!v=`K{tY53zC zBX|5`AN%_rao6S3kyin%0%0H08&*^2+|l5!PA)1Dg04nAc@r3eEywr)1}yO#wO1S( zp2Wm`7HHGe5fe->?slyz4oxPf=RT|Oy?xMwt+wBgScJ)1iH@<2^p-#95Ud93B)iO7 z0VbxnDH$0@zYh-&j%U$Mj~ye{^#1groAHp<5A)K|if^Z$mpQC>PGy}(S0U_~GV+er zGt1GHN^r$grrT%YPMejva0qB~0_gkT11LobnsLt&KBj*sHb5S0GHl8CYvR^Y>^49k zvxe!~y?y9F=A-_c0N_n|&SulZW8YXB`hXgj&2{e;&+g3mQtxrT0S83TQcMks5 ze*YztJ3(#1kQ=9LKSs|sOp)TNiemo-(?6rosD@k3c9_sx!Fh*+*Li%Qa`uC_6HLj2 z^sF>=m#u6R`XTsYkQ&Q3xI1Wgi+Allf2(NSm%6cNP5fd2!ts1W=G33)DzKi$$^XJs zA%k9VF)7&_PKVSdX&{ROGQ^#ouJCjf8$?K3n0IVNd`Ly>5scuWsC%Q;*>t@}M4bb5 zw;$5p@{`Uz%tLqyY8Oa}L4i>^chcy%kSc(|?>J>J5ar?lg5|{SqwmZ+aeF5bP$>;; z^xd{^t}T}Wx&JOZZdm&ZCv+2;;s2C)y?NgG{Ij_jm!Dd~z(+|@krI?Fj*gd37wn{> z5;MhU>*(lcXBUC!+dyPhBpRv7G{{sGS(w_vUuauYj>7}AL+w{94Y)AcRv8nx0~nnnCR&4%bS}HfMO~LI<^2&;=V_u8hvpQ z2V@92sT9 zS}nQYz{ErqE3u*khx^l^zO--H$ZUoOnhvV#uD7SAv~CJiqY-#4VWJkan5bbToGaC) zU)atJzha|ej|eWX1#(>T`hjXsY8W_a71JA(d%fRwzXvmG#9?()_t8hIN-r3N!jtPGdF7B!1F{+=gw|P&&s0rs$LJcLFRI_ z!Y5&qYybKF?PiP77|s7#M(5j~ST!SZQR3-gTVMlqsLN0ue12Yx7-obTjy4K@@|#9A zo!rUM$;4rtit<-vMsDCZmzU!9ZyVP3&4u6i<4D%;MFVH3E`embhpTKqr4mZ)&Sb1y z7}@GGGhc7u1#L%E_?g7Iy4u;b0@2UjQP-#PVJ}OttcoxPh&w4%h7%tlrw9=ur6Lx*KZWcN{xb=@Dm_8 z>M?lX%y@%ztlyZhtI$b2cBn z6@A9HOkw7Aj0q2@7fbf*g)E`e!-FR@w<#tp?(6!q0}_zPlc<{pcPtv=dtX1J{zM7j zXVblG_K(+%KFy$cfrN+ezEW@Ve&<+iRwbG>4Ah_{f)A__LX9(i_PURPF^zTE2N2tc zaVDbP?Sm{UItpH0@C4NwovPI4oSdBg-ezWjuEdn0aM7Ec0aYp#)2qRNG2;>J7_OL*znhdu;zhWLY%dBrIhAtjRKYzI3c9iTF0{ZAq zV9{|y+83PtnGBe{PTUcM*L6c-J6Z&vk(_5eebVX|nsUKfJEZJ|I|S670EsXsrxU;_ zN^lTR$SZL%t(J_W8wJdx=I056PXN`Qa9AE;;phcG!n7p3v^vod^F1A%8dVTi>#N{` zx>>`DJ@Q7n0;=VVKm*Bk*x`;#`q6Dx)*6K z$Gho}nNSM3)*=>2#uXpem`8liaMQ)_@t-qxT&z*@YFnlblHd~bDBbR+?`Y!KL?}&m zQTlr_Kf;2hlG2Tq>e>$*ARO65-37aV%>n75O2{jyMb)Soj?_Q#qr|LFQFe2B<6 zz(-217Bk)Uzr<Xu@gs71@0p2m98_8z4TzF#RIoIZg z4q?FH)yz&HP<=no@`3htBHtW$igPOz(~AItnYa${;S%lN$tl8vQR0*k6$nZ!6py*z zoriVvhvb*q6j zkk1W}AswK)+R_JotO#?73Npl_fIduK`|oI^i*ZcPN!#5Yci*JaO}j+GbD*vSjy7mBDx zEqj^v6&qwLhI3t~|JfdLW}2m;g#;m)DI}WUXF#SnJGf_4cMU*vF6y4HIcY zK4-mP3wU4mPd5a11)04a?trWaZ=E_Mxvf)ykq-T9oj%@Z;B$Wb_;Gr`gNi_1tTFUg z+m2GNyg(s`{TF*0N%C)Qj6Z@}e(~AYO~_-3*oiyDM;hr5O2K{{nBUp>O^6DmfngPX zl8|5CGV;GUTDnV2C<>3)=!3zex}bpoUyDa&cK4+LbI@p4%*J3C=?SMgu2JgiPtM6v`xwDGORIX)`nO_S+u27 zKv_l2hH$`_p6R(%u$Br@ek2Z1q(Kk2l`{j11i2~8S~VBm09<2IA#+iC_@4K3#5LF# z2!D4gf7kZO{Oppsm|QjZ72{0e3jxy;jJ8`fPS zg3GQYaj{5su&_7sL!=qDndgjD;WTlc=^Qkb4JHbxa{qLIz&ms|H&;)4Mp=i1sTqh& zZJ7Ms@}LozmK9lla`^iJTnB;5y5MgG5%9uY_G%Q7obad9)BD+SPXhgN9+YRz zs7)tkcdx#7A1xVxRAQc=DN-1(-3W+2<}l%gQ|8Db<>5*zaNA&ELsO-{wxZXRb-*D< zVeHIg$NeyvH#N*dsNnF8-V$o4=YUp`yr>&O`D%`1rVs^jb=;~16I_g)$P;bx+Nzb4 zP;^jV1M_A+mAhs7zgfrM(~Hl}_qK!GyUGq2b9fCqGld~hyg{0y(BI(oy=2t4QBmPA zn$bhUW%c@UL|r%d)okv>Z|~%!2_I3@0&#)xTolewRpF=1P=x9HP!}y%lCsh&w{m7P z7b&(<5*>B~2=kmVZ-_l`AT&Hq(N9$Os@&?>{kzIBV0Afvw+Avwsnuf;ylgrD+fXlx zTQBkbovneWj*9??qy-2Xh-5MSqU`qFSP|HZ+ohsUGp-PAHJY9)d{*kS5D)A)@aJ`~ zdjmHCU^Zs{j)1_S7K0U$svqzh;VdZdCgnVk*7SV~Q$?slEhr7eQ?QO~?86Z1-pyEx zH>6Dy!Dn%=Z5^Pr2vQ)-$fR86xoI~#03jerB!4IRQpaE(#Od|{Orp{G#`K$dK?;}} z>8+9+?_6LQo;sz)x4<7l1VI0RwxFi3@Y5YRvcOM|5lw$$e3-zlpKMPxH}1b(tz*C8 zN^|wo52BR2Hv!b|-~j{|8T01w6u%-K6W~2Dy^$v(EG#UACuCKj?nvtC;bP8wOWb>!9$9fz zfx~Ldv7pmJ{P5kcDyWl90SQs9Sb@^(give=*5uS`KQNNS(!S-Pe9`71s|x%`fQJ+0 zeAh96{=fUB!o|*3tm6QlS=nHD+FBED-nlB2qI=5dQ}V9mVJ9nl(>U6q`)J5d84V_< zdXrcmP~yXN7`5u!LzyAzk$ax~DgU|;3PIArKZnxM@0tMHS#?N8oK2lMj`&=a2_22E zHlaw$Egc_=A!YS?Z|ntBv^mOsoTBJ3mq}K-R>}p ze8%I<7{{SzaDQXlRqZ$~nFugnFs$F+#4Ip@g-5MbMej;^jdEsL)*pM7PpqLB*292} zPob_~NO9LDVPCmz$t>g4f*?_;004@T$=-LH?7yO|R_Pfz83PdH{{o3r{9pF)Qb2_j zIgsv>Ov0XnT&`ac5IGv`qT!?^AypU}`{`&9D_!HtR3=gOup6T#(j@G*q^PLK{}3pJ z4-f0O3^fTmMfv!oki(aHup?S^*eC!}oVt`ON)<+3LS8|3AZ}SEn>SrStIpze=}$=7 z&DFv0FMwgzkc}=9s}Qr5Qf~U)8}MD+1sXB~z(XCZuMV65YxLut3VxBM3$>r=^Ai19 z!gQIWe-D9vh*CY+MavX{I%Gw1$i&&%KO*TD2q0tdlnIAjmS7~x-KMRD%lU*sOYzvM zsHju{`hoOW81$5Ss`8uNI$GcArUt;jWL3m1iHo#vk1JSTo29=Wm#%Gkz0n(kyn(r& zP*lr06dV}5!`D8CDt^q$1jB>lCBrhRT(%d< zJatdl^;I7`9jg|{A~V|+yA)@O+Vo^AcMu}{9)JcfCH8r|zmjj$6Y{)d>_-e2J+x3v zA)-^apJbG?#4f<4R!GeMsZdrOSVne^mo1zdqirk~;dE(B*7;TzAASJ__6QL!-xP#Jn2Za3r?CTzvD3{5d#X5guJrr4 z=r$r7kLsHxofXwW$+zePio3x*<8)rGeG$-J4u!~>uQc?Sq1oU3?SuZdvU#!qjOtk2 zfUqo}54fdXz%3mkHGoX3I`@nok|DH4f=7UEw8Sl-2;Roc4cAl!Gu_3bSn)J1EiKO` zNW04DcY5*E)D$0O;LvgoV*{_SAHFIVnw)YaUw3E#R$%Ewu}L*p{=RJ0mtJnHxoqO(*<}TVzXf;g=(ROkmkV25q_i# zuBD~M^-0-CSh@CpS7!Qf%Wzk$;;OQt*HDyf%c5N%g)(N60`edo4oLh3Xll#+)q8x~ z)=JMnKl{zltE-5ujlxeLcbE)^>lAZw+!|m9-{0$pY{@IY3XL_)F@CkTIG8#@7wAPm{C0O zmq7q9{2*X|SwgpACbK7HXmRBeSM!bW@DbfyZkQRAyQ^OS<(eH&nWKed2q#Sx;FR1( zEU7Fe`#Uni4wG6l2os5YWr|-&=m-7^aA+16BcX%ou7?Yo_akd?a?YCS`0!T6=HtHU zB2<*=^xGAds9$gk)|+DgqW?vhiYnAQE-j(6$$)VZgbJ24RlbC*Kp?^%2%!Mq*Pm*L zTlRvGCpd}yjx*eiL(M4r6@Ml8`2E@)1eOa zfOzjI;8mS6eueTAnB|s|Y~x|lQ|D)b`5)9@R~ocn<0eMCtcNBI6XLPC^Ubh?6+}fz z;}<}m78;mUt%nL@QlS-f8%(EjSsm#1F9rl*B!P8#Yl3GFXo9zbD*HwyAN7}Rf=vid zfekX9d%Seu>;g)m-b)Gx_QzZkw6dhG+C@+ZNIA65G#K=HLN!B_A#68)Rv`bs>*Kv7 z4O|vJe`N&6NDJ2LI{`Y3Xp+e2fy=O6%`+e7!;9bZY)lew)awv)jXlP-zH%@t_8I2IBV@Rt|)Qd6W+C%_)bp(FMrtAJG8e5Y zou##spoRR)IJtYNrt0!MGg2n6Rh=TQOS{qnR(1`@F8u%PB!~OK~@<|Ge`g#9OI>!_Z z9$gosL%RZ1T^fsF{9lA>rnrpM`h{?u%he=*kzy;qDSm{Hv1osF9Gq*YH;z9@)3ju9G(|6qC1xp2Gl8A9QcqKlGa7ursKw)`mu4k?&tfVrB;QR}>RcEPIK8I34@t%5vpTzkE0k=3^3m~FatmnrIL?#_}0##EC5d!{_$827U zm{bldyZ?)$FK0#Epgv=hO7%^`0h#(slfK`Nrj^bW#{!f0=VMJM+yk)2buftq-YXzB z-E1TI1`uiC=a=DKnw#4_XheliWOvDLY6Y}{0o&r#)CC%IbGL{4dm^;(IHdfHv^3XN z;x`g1il|?6&gui@gl4Y4o`DMU%ORl&p9WMj*bsxB|N}2at^hJmlzd;4ePa@ zu-MP({S=wE`&>R~%yfM2f7{kt5Q8252% z7|KGjJVvocw;0Hp>r*6MBCjKqyZa|KYV(u8MC?@3wK&OJN!Rc)?7Z7cL7&nQENqSE zSJ)k#p>XDbIdoya<0RF8(4b?oE{I zO0Nzww!lk;U-+)hrLa%utrY0Clg?`J;NohiwDhj!v;2FV8iSu?0lojTX$@uDO3^Y805g~B7Ro{1;ujzLTGsxzA2qKlwqy&knh0^;BB!~LC?&!ISTi*jl2~_ui{lxLAT4S!Uu}?Fu9=3?<(jYlf-+b4D5$dxZg6L9ZQLVfOHi6 zw+5~+>9sbvA3;c#w$>`cJysjfWoO~V6F1a_PH$U4yz4PA- ztu)|1Zt*WScJw-kJDt^?=@JyQ2cjW+fmQ0dI@Qmy9~z|U1?tyKR^MlJ79DfonE1I< zd$`FbgBh`?_*_MBMbQymT)AvXpmCpHiCZ{OdXNUd!sj~SnZqs=qQX}(N@c{06!C6C z+j_rl$XXE|HmF1urKZ-p2F3zW@`(_m<8nPg^7B&~w0TOga&du`JE#vUo(U@ln6k~x z#YL1{j??ao87&+H{kO8|+_F zu>R0pIS}Vh{oxPqxBb%6gs8}UTOy~I9T?sIQGuEEEu$O~{5w1o20A9A-u=@AjMk)& zqV7F}wFN-_OsWQ$B=*>%`FT(<3<3rUoxWZoNm({KUXH7UB1Z<>;2_i)J{ zNCf)I)lSdN+hkcSMr4$Qtzr?mkd1>dF^>q8k*Id<_FPHWWv3ki9~=8Q&G$ zdiDw+@q&mGNA0R5rxn=%*ctjO({c3b|CXY30Rax8zAtG}2OW5MNiW36mQb%3UDM?| z#@(swn{AvMi_M*@7mYV|W6vkkPmOi6`wx)ivv)3%6@ZMQ+IMxWdye+p%#;*DQc}r2 z1eFj@Lcy=3)XnN>NNkWJ`oVP#D!uY`Sw>PK4peMA9lcj)VYt)>wyo+|)ud_CaqoYi z{KQ<}`G@(-IspUKMG0=^N_XSU4_ptV0YdENM%GL11I&ZGqBpuJ9$t7+>2mufA_4+P7|=>EIp$EXl|}vm@yY7uh+OQCiBZZzlO~$K zIBS$~9a~k77pU-pQikGH#ZK=>J^*mp#$~YTD2$Pv@#@1?JWRZ_0(4{&95?$a@HPPn zOt=0I8ZTg#Ru}#cE&F{!i*5K24hoTnUz-+dS(Rs2OLch35#!B-q95ZBnl)Q|Y3KUb z;TeHyQzoCUFWD8}T&J-4JsuSG7NYHXX-v335dtETLSdwZvvVv!?nIgaM#W0|M(SG> z5?UL9l%Dr0yI(^7l!$d;mp%1(Bzp#TWJc*Pz-6XL;M>i{!ky; zX($)Cjt1ZBkdRBlf$IN3K)9Cxe<$<&kGGq>yO7I$OcXQ%f|7xM@3xS&yBX{=c$Nta zOuoCBBImw!+Z!JoMC>bgwgTWehmW{&?+M| zd@i3aMC1ZuCN?fqbRoTAupJdr?Uy%KcDG#OsFWTcoR%u2Y0_31Me6TQH$zzChEcRv z7G>I||6Q99AcG;-eRozP2aZ9V$9E!~9cvm#w&Rm)H;@L7c>j#jZi%DM*!1?s))uWe zvVlh}9kBbl1st2k%_M#w8XMrKLR)5uC%JxdZ~${Bv-7pLw`)!g2KZwJw%N^;xgXB1 z2a~db!%?YWY3L&S^33)gX>94+3PWg=wH{b5f&H`MDGb}=r>t2+{l9yyz7%f9+``qL zQ?2$d6b==-<3-_fbHB5`=O07~f8jhC)9xYLO9q4tZ}oxM;Fz|-8|I0Hg#}_Mi_om* zz2p7V85%UD2(>Mng~p-K%KEc3BSOuu9fRSuracID#zDS&P>I_)Cg8ToFc})>n+r(v zjto=Sm)-_Oy)q+2JnZhYGTy{TNgC5p>Sk#*I^I7T%?rAc(ZLv02WsE*`=DVN;JQ3C zG5g)z#Z)I2Hz^ff>(38l=Sqa}iiPpJ39=S@gOlEVHX$G^OAX#iV6q*0HW{ zZeB9?_l@X`S%LJTND;?(yu90O9hwEbR1ka14H}tR&nvsYm~npiejl=|@@^13j;Hu;Js^WUVI!3qmnSO! zbQ8b!!?b0@|2ujExW%fL?an$Cmz7JuL2P{C$L!06H%5D?-R*nvBP-AA6mQ&4JD;zr zo)+5uu4TUJ&aJu~zJi?OFE6*Rwx8G&ZhdwfNK}Cm+wXTSVXUmtj8clNR(qegb3f$> z@lnwFc6$~Y-6PrLzCaKrx{xY8A?-%hos?J^siNtIWha8nqxp3LlWSq5WTXqvKP1~% zDr(8@>)J8vwof};Az~2(pp2n9pZnnp= z9Sjh6mQtoY>9&^>n+qauLANWN>i`dvoHo z{@KBK>;jeDQ}EYh|M~WmqDoI%GPJR8-TR8NhfcI*%?eFusc$#u;+i#*Megg76+OuO zst&r{Vy8APxd+?K@I1j$ZGH9Vh+pOkRzO7^=Ap6L(YLU$p*)UpUse=NP3TgsB!haz zxcoEV*x+szfk|EO7_fr*`cH4U*xe_+I|ncf0aq|@XPg%O{o6>dr%QX#^M1$$hxe|R zNZ4&edE?W8({mRH1gW=gKHFQ#&%WOfa)NAr==YgQ)PGu4@pD<^p%FAr^E$daQ+e#t zafDo&Bwf_#CW4DmRDHTFAd88A+{m3iJ+y}rWm-q3lP>lup%j%|ne^X2Z-A4t>E z-A`Z{H3w!Huwb^R-cy^KM3TV*Ut%FsAzrV2`wSbtPmcUs)7B3R}yzGbwhKiSZ|=ch~uY<}L|G(<%?40uni8nK>4 zbARy{hU9?MzC;PkV61~zjB{+vT}1ZG!$-pTh-zFaPwWG?D;%$ zN+SUTxoGEK{xs0kaYXeG&n-?qr( z5)h%Gn+&`*DSX#KJ66^zXCB6L?+9}9Dz!+}LXV^9wclhFvQkz5&W-OvVa|^$HsmZK4jHcmwmddAh|>9;gEyWN?HdoC z9~4;+95YP61)lZx*q?Hl$?+x!Ql`ODnPc+F_}`^IkhcNxYWr`<`q7LfHH@>_?do{^ z&rU6UZZ6jdn%^wBpY#1Bl5VhFB6sq})ydQCfbd1B@k46%Q@F@ew>6)UZ=dn~Ud*4h zm_JwPjuP%St9OSKk4MFRo7vBotGAQ8ei$=1k83eDq-10A%J15US+Mc%} z35>jlynUV^RjUtP+4ox_4{d&rV;z^l`R4h_#x7U3gaE(9+6N{We{t(r;Z5Jy2*rYs z5^_2%i7Rl;$A0nDfvP0kH(XpUz##*m$*h22Ffe$MD@D%VLL&6Sv}nG&y8~t!?Bu7! zL_|as6fzsgvv}2pYo!G)xpsxa!2kp*xg$R|?6Yi73@h*2DMuTpO``kvqIpA2Ntu+@ zY=-}F^N5;y3%4&LqH2EWd-r9N8X(SnhX74ZHWa_wd-{Uv;*WQU`gRRJ$znv*H&&jb zyw>NO-aMC8%;kA*OoVdw<1L+dA9AQ>g1Um&^;6SQ2t~@w&{IV2Hmqa7sLvOEkA6;z zJm+41=Rag9JlBf-HbTii@3onFlntaylO_R5beTs-A4>8tf~$0QB{9JU`m-co_s`Wv zDYv%SH0^YejYVQbkq#H@0f3jk89tSUBd6p?fygre70l#k8%Kyj?KcVzjP=KS-wjKS ztwT7$Ttz7^DB_Xl9}rZ+7ZTdrTRz>XlhN$AG_|-Hnu=TK5u2(Twv9E!!;XcCCC0

k$^V*!R1Q@x?oqKtM7Vk$sQS+jgHyEhB{@LOM`JU8#^z>)VAx6(<%o z@NtWSf<+}|*9G6anWymE`N2mAee4rKS^tI{9awSICY?8Z0|ltoMumiYxxxm-xoDF( z-@nDYjy<|~fcaksg|lXsGj-8@vz^_yDb(XE0b^>u1ZqE#aDrU?es$g90i2imiy?-C ztGkN1Wz`KMuO7C{hMy9zFpid}W_ah8-)|U!@-=BfF^V$;v5x@)@O`(?>fI&9%0orR z?Xbw7TVvk`wDd-w8_1y(boHb?3VQeKK4&Y67;m*qcEL@PU6;d3^M{2I?C7vC877O}|_I)s~aPCdjt3=G>AqPa&Y4 zbD!;d`XB-*%Kv=6rFh~^{PiI6=SzN1sK|3$2h#EF{5+YH-;Mst{U;$ZwF=0Igvjaj zjkk%z(V(^O;oNn{?H?vW4sp%sqg5S1Cc0Wa799?nq`8%ED*Ju@_aGT+(;U&SSJC-{ z1*%YI7FH!~^|}%Qc>?zGGUWHiW6wt&9(!#!SSJzXRd=a=7tc#TYHutD zj+`&pZ@uI3J}Xn@Xz zYY7S5SRdgwsU;nPZ$@%FmPVhu!yR3OVmF5e%8c=Rq8DYU{(SPpo(9zjD=C%t@5*(a zYRVDAb98j{$vnEIp&>atvmfARxb)=Os8ecL-J^}c9GhHukcu&!%7oHsZv(F(2_}qh zUj$x04GloZk0uicTqv6<--q0U`ks$;+&nWIysLIlND7KG{lXz6{#iT@?j$@Mnm_|~ z=snA~#jD&|k*|h^dUzE|OYX#`hI`BK*nDk<^3=io?Tr#w4&lODK3qd7iBPg>}7h;WgaBN&ZDkLwM=ulfD^5{1XATeNJhxCw&t0999wk>1vFyB3C z)37ef!Xs(%wXu8vIJP<pxA8&>hh9xb5P%|3geMY;2yyd2?Bd@$oi{NW>HV!TbAov|R=F&BaFjZuJ&Jk^bi4_wm>LXxp8Z2SYZKiCr?9Z^-gs_YTpWfuWbF5RG&%|(GsJS=Hzvr)6qlNYJ{r?}b-a0DEE@~S`KqW=G1Qh8SLO@!Pl9cX2k&p(7VQ2)T zyFozd9y(_zr5l7Hhwd0)===@O^Stl({noeEz4(KHwa%P#c3juK_P(2%zP$A38L>GO z4PksojmqO%_BLDE&O*5@@CIANM2mr{tsNzniH&o&_6#?AT{JQt0^<0^V*8(h%glgOqP> z?WLw?#Pf(0e98X5dhXHSl(Q?r3IBibIQ%>MUGS1V!y7)4D3*N}K8g$V;P_C(Ki2>C z_Vce~mNjfYS}MV8+I4gJu#3qwrxnLp@Z*7xo6u{q`r>m>e5iM{@9&$qsYzJXIdrIGr2gF1J8@T(-ukvM)qGv&VM z`7e$C-#h)N4bwNM(<3~s(X;FPBWNo;lxVae*;`Q%pU#p}k4l^2_(zfx6{D07OjoP7QeI2cdefh2WZ9ii|qjjH= zq3{hNQje6{Mu>`nl6van8x_@XLaRl5k$k+v>P>I|`v_q4;Jy=sXUTrX168diIiNpn ztO=6@RXGjUqPwVYwvM7DJ81)%M{}bQQYUn)?v8U3**wp_kVWYO*_)o!R%ljPrkJ*Kq z?5uib=bpG7bUff~eT`A_qO@McdBmkkEl#%+r>Nr%iFg z1!{lD8f|t*cFs`CYR2f-aYRmWORm?vT2C&DW^&QEK4HOXN z->LdJc_UrsD-*)I)3-76)F2wi(iF5j!m3QuZ~H~!hxgkb62_T+q7{0OgIamR&4}6j z|He`XJOGVPre{qb^6EY1uudLwuRAbX2~+KMm!&?dS^6%F$=KQaywJvBN(m_ykEUbgXR9CgEfjWK3lZV}#PW0}|FHkRvH{y@ z3-_5vw|Z-23wSR|Q3k=-@3EuZqrkp6=0Z90r$j%VeTt1=%@D5#fH~hIR#gzI^ADhDp*xC8 zwJi^!9iJ$bK13?UL&cIPa}C7Ono{cC&prakEa3skb1c;TdH@y0RPqnUu2oWvHGXOZ zs^sSL;Au4CiLw}_|EY|1H;Bp*`4v-?pOU2TF}V(Y#!}%Z`Vl**$~6k2qYcY?V=C{? z>ah!k1rsrJ<^4E5@=<#Gd}Sr;LIMuEiR8a|U=CxL8W;VX;!jqG`8hVCM(pSs`i8~f zhy{`mvswoI_cLWgM*CGDC-Ayl%0ubTW#=TM?sq#Hl-&Ox`m;XH@kZWrKF<70tD7`< z@$gm$rNo)F$kTmV=Fb%~c0vh^Joy@FcXm9#I zPjeC_!1xI!J|q`!97--YBef==vYBm~3n z3A=enkF@Zh0{viNqL!P&Z!PVoMFc^g>%?C97|^`dOZkP#(t%IK#g&VjjA_hNB*>w+ zptPD1OUaBPQ;5D}=4>()553khW^g=c;|N$P_3`i%+0jcjXop)<({{di z<8W^?Gt_TTX`6bE(QStcoG?wwl-=wyi4oFk@2;|f`$C&lrJ{}Rb4|Q1^NXmYziuZm z91p*6Z?2!Y%juGd>@0z$C%h8Qn2pXGCtWLKNL5F^mkzF%d{{u4r26N!)Z0UZj_ifd zQT<-$s~=L}c=*si7S;>J0i^M@D{w(t(MwP|pFH>mai`;~sQUaqc}=I*j6>#igL5jDBcpB~U{j^9|JfCRBUkDFQ>$dOWPA?F-(E!rPkCNOPoZN!W@K zYUI~D*z`17PdPj^I5;?*Qz5Su9?lh7TWO=p97;kBbBKSE!gZ>TbUoW!1CT=d@cZ4QS_%8CSq=dvU@-nb6kea5NbQ?G3kOMJy8+49R?pg)hu) zl&xlXPwxz0^asGCE;fQpyw4o>e`LTAlO+p%rWdx*O+iv1bLN4fbKQFb<|LamYHjnz z9YP3=Gn^gp-G0{9Z~mMYUoTeC0U{rmYEVyPmaAhBDv=ndYva1Ur3UDGuFGCg79WCe zj2W8UpgWw!r}*`F%YEYnGsFhA%N5Ot$Aa=nxL(Jy;HG(3Ya_Po>(R zlcrn9(?70Z^YUi>HGQtaL-Bnv;;3~oaJ=w8&zbU~?4$0?@JA z%2VDRXHk~7xGtsL;5*z6%=zBzoN8uDS%cID3}w>pa_)wXGRsd84-xD|?%uOlrZY*! zj4{Ql<(Pw%%8ZHI%zBs=Sn*h18?q(%{shGOXB*CL)_rb=H+=UbGFZJqE7y=ztDUiQD1LK#vN-e%{Q~r* zGs#h(qr^1P@5y$;I;i=fCkq>6>7xY~y48!!^nmBJA*X5GsoY15+Up(RTd5s8)G_7) z+Htx8`ZII+BqE8FAKQy9tVKO9N=X-fu_>vCCr~rH0uQ@nRJoH3LP{-mZl0qhM+$v>v)=Kt2$dNp$W3O^7cw6g6w-rB~R^-?>J)Vji$ zU-rvVT+T9KC^fvIYejDXlP|VOj!+|-*m!XM91O#*F(~tCWnlfelxK$V)|`S{dQb`} z1!dPbnrpfD4CqIq8BENNqTzrXLVMOF9e&h1Ed^MZ9CAiFBYznM+%BfoKl8qQ=iqyK zWsNGL7C(#zz^3IOa@@|fmGsi9pnr^i@HtsOR(>(M!2 z{J`d@EPG4GJ*xOuGfsKA*>$3!c+mJaZSM|#uRYEu5ZA{~SY>K26N~s?Hj;8mOMc#q z)5RCmg*|&)GL=@}_K>2ht{p+GWqDe=N2(A%|3cWXA{OPrw-r6{^vok=lv7^NZz5O>;aVHmzS50`U<=qGDfnm+kre5?wli0fDhk0UvfH}|H`|&JUT2h zNjoSnCqQ_fEca*eU;d3$#P24TnrhhaE&#u0(Z!(~Q(dr>w9bOV1?Vx0hly=#rOfvK5=b5C1`S@1qNTfD{jw@`ZYm|?Bfnwr3P zkHIObb9*LwUTnJ2cN(YC%yKN)viVTbzu%jBW(T%;`})?VCJ++g9^|@=HtO{~ zFO+}*k$1x2=r;0N`p)5Yu>m^2_M6keYtS96z7E?LzS;w%tP2(^=y%W^PJZwoF7)P^ z<}&Oo8E|RK%~R86(O!BvECVb*dW3Iw)QQc28Ka6-^d&2mDP5WRv(f67%L#l^3kK!` z(=X$8O#o8IqNdH;?P$)J_m;o2t!_?=O6HSpRJ7#W%zh8jHZET46qI0f{`@F_e z=qQ`P6L?E;upj7c51LiGv_CR^B6axdHmhZe2^yJ>kh)wY98jRYREgZ*4TPT<{}gK&%dXxK$kAVmlfrySQJKc*{)?LJ;px z6DPEZi(ftZ+(-bBd+#!+N3D{Jn4|u?@?8cuB2c7id(PONJ4FzKRJNqp+Y8Jx6hEG_ zLB;}M21^*fzmHj&bkG4h^h%!qk?gB>h@F(I71{;5q4kH9 zk!L@ApCJ^Z*6arMw#Bc^om)>^K{vgWpqoyAW8DSOyJiL??9vxKmrOy&i3HfS|BgZA zZl>PNcjx8Cb?0rP)ZMm-?`o6A;pmoWi&(tY_Egh6#ePs2<-)2DMX}w^@R`3@`zBD318N(y7+D$%O+j zOzRElK%s)kh@85~|x_z+uJ6{(&VrU#V=6wMWbj#p; z{2#qTgQc@Fck??1xv@Lv9^%iy6{A)MdBs66T?C zG?HwTDRF>NoFxLo=1r&ZATO&Qm-Lo&K#zAb&rk;sk<)Pzpz;=;=Y=;m*4;6B84e!<8?M^wXLQ z^_$S+Jjx$NhU*qhIT0s^^%mDL_`Qq!CsB)CB{x2@{|vNf@=DK;@Y)<{K@BzEoX)NY zf~vuw4oSf7WY2XwL@0{Br5`F6^!kL%VIx*;zvW<|`yqUk(jIsTTF8Gn=CdnCaW|Ob z;5*b=(t05O5!o_2ryW z67UexhikK^de+BaXM8=fb>c>Uk&6hw{Ty>|7M+y9mgA0K$n_uc@Zr1foye>FQSQ6K zwtd^HMu5W{s%3n~PI7S!ktjvsf81Omb$6q5cln@R>MZV7d%^KI3}3gfu2pmeYgD>! z{c!Cqd0kO8WgAB*B>PcE2;QOU`d zt*Gx4!Yy)?nwA#m1WM+tNLK|_M}Lvf@Lb}0>Ppvl=On`-XPs{T`1W?kL{zed!Qu1p z#eBCo42V>A_~p4)!ZAh!xGSKHYCXE}$O_K7Iv?9H;cqz!PZ{)_hoJtJuz zdrDD6mtHRum0h18BOl*XA=Wx47H%&Rh0*$OLiLZGo@3rE&C!sf%X*<;t`QYS?BXJA zelA>r#QjiX;cq9rXlN*ldQFithL4st_WRM;_c?0u}Lehz`g z=md#eG(J%^6K3#xQNcep!#fXqam-(}zxv~HvmVEm0mAbeIHdLje!LGR_YabNO*YCI z=(CUNa<^fZ0YwVa2=~8oK;2#Dugfm{oKDQUMc#G{{4$I-M)plOP#gJ{@veH#k>~6` zvp$I0aI>PnINC7yEM!55TwEt2l*$t__!@mR0nO;Ar_Ehi>%2`j5q6%{h3`49pt7jY z-(J)UY)f%0`aW=dfg$Inz_1VlvkmDFMv0RV)3fXw4;Al;A)wexXLJr=6@ONa!fdPE zhhEQFjw4<`^0`6b^-oj7deiDp2Gz2*iel+*#tYLNov%Y#0Pv-Lb6Kate&#m%ltPBhG9@w0m{0~qNp zYe`bS?|s+a0bJKd4#*PO?N4Muaz4|yY^X)I0zJkz<%vn`X1n2)XhFHpYrmBSLjQWE zav}6%S<96`^KgtN8iFd!%4P*Khlo&Xu-SNkGJ@S(K z5`tRHNX>AVJKGT#5xD#t+#O6b3Ei2Ty}V}as%MC6aU2?e1GP}6cgw=v^$YnIC_u{9 zF!G1@4TEdzUNcSeS%xhv1BiN%ye!>?HVXHx)2)+9=&NOc@Oq^z<4pu|#}t;~>BGI0 zCSK#ajxU^L276Iex3&_lyBMY$dLTp#kNQL7`8A^8{EL8GteTUW)NzEH#3d`{{rVsa0Th(q@DWCe<_h_|P8^KfVncs;f4*dVi0gWkbDQjN`sQdZYIQ4jse zuHp~8y^7KOI8-_;>bzLWR1eju6&n(I6Mr^8At1E@c=KHkWz80F915)1x|4_7?us}5 zugl!~9p1MC0_}k>4BMKqPQmMiZ(qVgM9gTRYiry<1Y-Ob-=_|5*Dq2wGoBnw^Jm@@f+I7Ywcj&2E^ z{h-{LIQ_#U297(S3BV`;llv@tBeuJR-T#z0Hi`#~FZ^MCmTgF*sO8ri@sroTXT-R* zSkb8gDk4px`Zzv-+PgC?Ql|nr`}8@55pi%RBgxmRp+#P&E#n?`iTY^VGL594G>I%i zAEGMm!)r2e^6_e?Dv$|W&j5G{fPDOB3Lje>f9aZ1`99fJ;C_?2`OP|a_U?Sxx8COvck3h)Gx70y>f@#&UGDl z!wIfI!p9daHoSr;V6^Yu(0VLZC1O+XT{f?xXvnCV77Ol6) zWZ!ecXvwSFeu(GoCVrNdLe8|$T(tojJ?$KSnW5RTU0Jy6?Ays~J!+!lf}QrQ!HpV^ zXEsP{JI-e|1af-eu#d;p3(eQJHlJYuYQ9XE-CU8wq`S`gIS>6>Iz7xemusY2)+<|| zJjDjyP|Wuog;}wp8?4{g%rq5>H%duLkLo|vo$}J%y*ygV}YvF zfj>e(^OC|uKFs!oUw(K-Pr{Adv%PuRlL+^#JJbd|`xs38>12hjH?0G^S9D5XRZV!$ z%bTj~j^~Kg7!#*HtQV8m886vwlHtrTa-12zE}ASLA;bIOQd2!2nE@{ue++hB(L zVa7c*I-V)FX8l2#a!=u>{DXM$z-!+;{;_?}rb$l@ux_&M-8N|1K6nxfVCORn>UG6L ztiNNJzi#S(^^Op3B9{BU%>6Szw%MTAwUlnRh5{e7sTc*~+P_iQ`{QY=F&w)1V4&2{VWr1^Dfl)D+&I+yv$8_W{R)0Z$i`xr zY=rP=%cEV`xaDS`TUc)mskBksLC?Lol{{Ndt41j^zOG+Cq9mK6{<4TXz>!4j&UEygl6ucnvR|rt;qIIwa0Auk$q7NYC{6aZ(lIY4o)3e57op z^JTl( zpJC5nz+vc?8LX=_B%<2V91M0fUz>w@64Af@SsKqByP4 ze)Zrh7by^%;|^H5yXlN~AHI_h(0LkaR~gs@1ZvEmC83TuGY8i?T@5DDcs015f&R9y zWLfQ8XnlC==1;nq?(OEl^**ixI$9rVuKOIOO=5XV?*DAPtTUna*{Zeyud!pQbc$7b z)!a>H(E_g2WW^808nbQ#ZsFpNRfvm=!+R(@TEdRgwz&d7gWL|Lfv!`1pUofCD^7iJ zGdWn9-+-B}z9YhO0M*?|e{+}S^a&KGulJq%HEs2y+m>)tymPlf{#k3`Lby|!M8%}3ob1TfeyWWC|=`Fj|q@XHzy%1jkrfMv(@Vq`24vuoAr zty9;fG+Ga3_B`6AE#&dv(Br(?o*mqa<2-!`++Dm}-=bc)AkMgEa`6ls$GqQ;pWK?? z1wmRNX4{AESr=fdK}CCZ;g@?~Ik0)MMOJN4}N8MRU`<|fX^(m(|EO<@ z{b~;Ur{480%fw+<6s{MObGQ@`foC!$V0H57=62S{>caQ-)%Gg~_y<9(T< zBy}2*I_r>rFcvIvlQ-XF!h~vvMA=__S()>E#naHhSN|~q!q|G+*Ipn+W1hU}jO4r0 zY&D^=H**Ca4`)s6J*5=?2}WLxUUeNG#4{M&_HuRw6R~kHzVO~sb8T6<+QbVQ`T8V6 z62-R$Lo!D?4@X}dF2_z}d2VfD!BvsYS6hHB?*%ou5LE|w?%vw<2{%y)Ou zK6WQ?A4W{poe4O*k5?*HOrVxE`!ty0a>qg!yqwLE%dB%IMdpUWe3Y-6+*O|!H2yRo zRL?yd=v{cbIm>*?VYjK^p4e07kka|{@089fjqXn4us54F)I~2jo={$nAT`xDLDXQ( zoVmLl02)IG7na7_gQHH`7%!VPzf8cQRmpX$jUV{{u++c0v|WmD@pvXsCpsFLRcB{y z{coaYH{>}Qz~Ft z-r8}PLGP3}TaRCs_+Iar>37fi{2?`LdGOKefb*vHGGnqrYAH_wtv!!uJ)U0wO`r3w zyGOjf1l%qg>3wGH@>dcMv~mZ$j2@=*K1@2rG1B*<{dR_QJ>=(*791i31jI2DR$ISQJ98w;L~ zER@Y|9I`r4(Vc(Ysp=M-yCRXC4n8dOoo9%U^zq(_3+DW-0w*fJ+i`_{$T;fO?F~6$ zHZ*7b5jFfI{QWQ1+_BpxJucVmBO0y?Q z+B0jR9=Kz~dH%zkqtBPJa5sgK;v)B2gMX{%Zp?t}R|OHtY;u^<{P00V~$v*Z5EaLM4=pG1or7m z^$A&JxO%E{n=bG&H(^_Dp2?4)8%)yXCj`>w`1tsbiJtw`VcGIH%K#zP)Z8a)9j*vB z%C~WdBfnDYvja|RhNvu_2bHzyt^SNqZ7#b~HQ=_GemRdGjl0mM8HQ)X1m^tjkM0AD zuA;(`4sh2hgKyvs3(|PSyMr9ivQOu*?i%l?+(vS@3{^f<*6WbWfg7%+xmOmrcJX4R zLM=rBJc3p8`^Ce%_<3dT+8&WpC_IpVO?7w_;m8H$?FPZ`AI*k-5oG6q> z`r^Uu}ZAh|02I$)R zBieG)sKyi_Q(k{SJ_@fBYcDJw(bbH6peZQih8g-!Y$B-tMljXl`{dQn?wuIONdq}?&Vc&}PFG~1(N`xRbvuTFH zZm-P@I&(l*O#pGw*_gBJU?ZRYZu_T`m~zQK=3ZfAOcNkNak#27V8f*E5oK$x(fAz< zUlfhp#pdmwSug@k=E`PwdRPiG@wdMUnoN``yOhZ_w=Uj06BS^7Hwdv2GKwgY5Uc{M|hpg!@Kg3R~x!|Nk4>$&sz75^OnGI^< zWievoFuv=X_P9?j9gY~$?m;Y$vfa$=5iy1HMmb!(*VFAVtZ|9f?e|j$EZ~fST<7l{ zPxIbTc+EsCogb&bH*$sv-J-=R1ExZD4MBBAV8{hi^@w{3|KH1`J69{$CW$Y*Nk2z= z_^TTldJG?QO*e`dxRS}GE$TFvRe4dT#&X~`9=s)LUi-`t;W!pf&Vn?`P3-v{Tyo6Q z+~;T|q%o?h=_fbi&VUKG-Rfxms$EIUmnaG@`0=kJ>utVq2YB?XWi@WSb9~X@p676- zH8QxK_#^5>G49NEc_L8M49j}_uKER|T)47{!;|>ysEPM&RQc+*IE@KIBH)%yx5xGC z#QjVs&8CUJ+HgAE7#woWiJ4jJ#z%1-Z+x;eK1`8aA88f+&Xsw1>A;M&Zj6cNK#3FD zMk7x1jjq$0y$wk@#f6MK!xCtd!4-`XTF|zFAuw{$FA97;sVrIH6X;?YY6>fh<+!hO zB))PKAjo}quG zg4~R_6aXB~(+=;x*sh24=vAwYtduA)-P$ux5x(B^< z%^^c`Mi2e~Ii;d24?}L2^P+;vXXh?~IBXx4QZDlq#JKo=%T!PNc{kfHlalj`c8}d_ z^%Lw9SkB-){kNF&|524iETdIr2DTq-rg%pq1%6*W9^A<>AkpL@ib%L$*1vq+Fbxpu zLW{!%jXSz*7KCDFCY`V#r@Q*OxNO`r#G4QbLu$9%VeaoqFzGYQBFgG$)U%(JI~<1c zq+Gg6yQ0eUo|nzoF>5H7YIg+UnLRA8;L$e|Khu*^lXb&>My-ZsO#V}ivDi{PO>mhb zYwzIw4)y{5o5`X%aWY8F=b`?E_8k>qmp~fmH5DdWg!SpWMVjNmbH2C99owzF%Wkys z`&#)AnW%BzvZmvmVk!)TB%^!&W$Uvfp0j%68yogk-Qm0PSRV-CL81+HqpK`)B? z-aRCrEe9LjPDlGv1zqFdK`Jur#n95UdRBmOsr|$KO&lPjsBy;UlDZMXS4D8L_1m~N z%vsbcn&y4ELUd*iX2TU5lw(!I)`$YyOJY4|xC9O4$vECd7R_)KG0r4mOo8^Hh$)DB zvR^ngcz(U4P~lmTtfnpX#G^_!Fbcg8SBnnx;S8cPndaYMV&JRK-(vNEzRp=_e74uy zuRtO=a=p0S@rA*e_t_&V3{3V=ws(~&W*pqL<4svQktu(_03J{+=B*?e5^rM5SjbVb zg_=G3P*FO(YvaDA@9io_3JZ0p^zM$d-E-UYaVmpL@HfKf2S@y`^6 zf6w%O2YcL>x#^v@m6@o(H-p})z}~u5JHf<2J&(6E(i&x_S5I+1s`D(Wl2pfvD-uAq zr2&O;)a(lSj~c4j-t8-Hr;2Kmi^k5BzWe-rFl6-wy299%^$gK6Rvf){tI>Pj<_4n|h$qigZ@csQB~ zM++XB1HjbB#oKT@IX3tE%|O`oD`^#!2!OyPa@As+J35c~wFWLRi?uWo4fH3rlK5Yi z;R{H{H7iBw`PS!fg^0M;%Q_!BF}Haorg54jmJS@)R+D2+CWD$`jp&;lPOm8LYJ;rz z>ehz0+z4+QbKys&^#z9&TK2sCcrPZEjjKO0RojX9^oal7=JNu7SV7gUhmx-c8E(~J zX~KPW2^p%vMra`+=d=&>`X`A}b@L1|;1@1SXw!DXCPyjn12VHAia}vcLmkKxfxXQM%hMYq?z0?k|V=(OK zD4v}q3oe#p$db_ak;W85F|Sxlr({B|z$EHNZm@bUdz=-Eo0QZ*op}oHWnpq!~L|pma{Fc1yr3FjusbwUqAqLk6yM@7O zL*c#ArUix>@EvE{S?<~(Mh)YAQ*%8U0jCCtL{s_PiQOL_9h2hW4uVAOOS1=knt~(W zZN6scTXQ8G8GQI$EYvBK*G~WnA}DML)_qvnqqjkq`Hx;F&-umbc(zf|)VJ5e!%9Hh zCG<9}qsw*@O5o9G34kxYJL*sc5s%)pz^s9M-_Xb?p|5GWu~D443e9D$O_M* zh0ys2W7TpT9&bI&H9kqdpv*bwDt@AJs(a=4_{L{xkJIfnn;p}~qhOvg4gIGY#n~a& zZ(pcW;oW|)w&kwXzn)Mg=cx5cPs1B^`#Zqnk+X3^Lg|1>Rz$1b_bG6(RxFAp(wjNu zagam9t{d)J>%SZpM1s=|{BmHz~a>n+J94nwuL4Yf-`niT5m7{BUxYqfV(6`IoW>XVA% zl@QJ|+tB0k2Iy)k50hbd1f9tqb66@Y)~4Spm1iY8wOBbw>gZofhUc-m{f`ydm>n@% zvI2%a5C0oM+lR4%tXnZJd;%hEMO%`;Yy0L&BgYAZs`33OvsDWYzEAJD{Lp1!20tw! z*a}Oala-vxT*k6bRomCDuY$I=1>)ktlNCL9*e~+lF z-rr$n*7Z(VByIinw=EaZ8y^u!GDS>kZ>OmUD$;L(D z8WF{vFQ5GUMeRUevuZwUHP*l-630S$+K|aYEAt^8fF$3CE_&^d;!{N>%Hw_D&x#kj z{FqdlNUZyy{;w!f1+j9NJ)#%mc!@4MZ>*Z%9v|_)XDBob%*aAOCMF$#97$TQ0tYE7 zJ7%ycj2)O*b?5{zJ8WW#IiPHy2#(jv6Tcp+DtiX<2w1DVt1P#v_a~^9HjQocWB=jt z^y5GeE8IgGFBb?=;J`8znwQ*@Z{}d@H7* zIDOOA!wN?TD`5PiH@Vr&YTDn6HSj~Yd32d8Y=^0`wGvGWitx3@G1XE7e}&|^O|!Q? zHD|2q)p=7kD`OT+(T?|_aK_^;HOEK3T9eU-AouRY0N$9*!{410@)#WiEO;1!7t-SK z=<5Rs{D*hG7bzoYfV>{w#-3=Ag!7U8W8m>uDJ-E>#=21%W}URCE$&M94CR1>Cy%k> z;!<6SN3rq4*y+jH8VCe(nsGe$;^co#)osp~I5LBb7O^50BRjv9fPb?p`7dkx41NKs zi6duov7UV4P8s*xjK(4@cWaIu@+4jtTt}aX&3mAl?mrRRQrMyGUG}3c?nT0KM$2|d zR>0Q+_uha%HImwa_%CR)K3&-x)c(;n*^zk?s@D}JQH<9=6pFJ~q`)Qn@hV}E#DA@y z1mhqxwZg`N+p)uN`28OmmsjJjMo0Ur3U*oWSe%Xnb1DrXeC9`!qt%|BErU(^MONq@mjq>#dV15^+dv0;Vl=B5TT8T(udrm)vw15-I* z4%`K%@SHg2WT0MhCkPH(QMm^W6z>sz;S&FYmR1uZ=t=NW*DS*cqUe>+S$>L-`l z<#CFBbC&7o{++>f?sc-10UYSDyYl!1e{sE#hDt?~l)ut*lKjs6kulyfvC5SjSQXO_ z^l4~b?xDDbiY&j{L7u;;iXl`X#h<|44F3}?@(&mW-NOjQ~ke7nUdh27@-SQOq?>s>*-#5@jrwf}U1wwPM>A$o%pmN1VrLYlvXe$tFl& zZl5q!{Im;|^+)#tJR%8Nk^$*>ax1F8FC2Q+zL{?|Griw6v@@|45Gm)<>kejm)8$5l zx)x{p54y#lxkJCcg`vx<+=~*%JLqvowJ~^ zaFqjvgW^mBq2M!@GGXvejcnZm$d_zDnL^?h@$tQrW%q!^&IlIXw)~)wM+StZ8S`4q z+GbcPd~99#zZl#x^)r6%f5+N-)b!_w+f=r|ypNE`M#IlKA=IK!FQ7hba=&KrBu`Ji zL=4c+ee#Gz^CQ8G<*yQ#fsffA_%t44AZl&k{x|o%2-Q_kXj7FmsnUKXI35W@{p^mHcS|JzA+lnengS>l$yeeOENPnmdD8M z&Z_?ZL2;j7MnEd%5sc&HBg&tzh&ix?8s#5ld72jIJVk4D;~sX1AZ7(&{0UB`!+t3fAj2 z9yjYJcZU_jVc6EsCo(-E&0c0QoTpXFXtO9`g~4STNrGoXZksCpVzNPB{|=TNe12m8 z>oUH7z-9q2T1K5@t0^|wv9w81`J0uO6GRN6t2_~BZDwYAH&QFjYWnEeXF?0ohmYhP z%E0u@txG@YuMx2roD|eocs0f|E?y_!BL70A|0OWcKZE9mplmf{E&|ZZBfNg5p8w3j zuBSiZ=bG=i`FFLjd~EG?>e`^AHZAh^EYt~01F@PxuVvixb7y$jSaOr!xs6UR_pdSc z>@fFi6`Oun7w9mwEygTTq;2n$;VRO1!qF@r-~ekSy4pnzRwDBb625VN%KqXowN-@j zs6h#{9USm=)N&mCBt<#py|@NJ58d9$-qFV2WOz%{p5#OG zBHRCa6#$>F#f;u)Q#YwPbaYXq>paJ&OLc zUKUa3tc7b^(XrWwJWTE%|Mo@p+@;Y#c%&Np>Gn3WB4=*yRHRO`ji(Ac{OL0Rp3;Hm zP&H#cz1QxGZ|dQnHpLSK=|%2HC#D}eI^f%1oP3Kp>^OPBhm<(@qTT{I8WCPu z!h?-JGf@16C#wVmWN-f@16!Ggi)&zL2+!&TQSV8Nj7kfoq4w&(8D%y3yjak6_vocM8!H0J{= zhUsX~Z|3ac!8}{y^fpF_WTJk)C(vAm;J|}+yS#Q4vu@#xZ@i{th569$S%-BcuV!7i zi;!CZTIL;M9u~1T#%Ec!IEv7Qd*>)p_@cXVU0|g#)KIn?9|orW=FRrx`LE-I6>&iF zYTevCqi`H+^$V|xkClHA-&vEC-T&`q%d>$E*yfAmg`-N^z*@giW>#U&2XBM|K#Z8- zww6egOdN>0d3eXFj$galOn^;@{k zE4^=I^Zq!4!kQf#Q(9}v4QeNAW{U>?lWev8Shh4<(u$0=-cPh|NC6~{qKhMZHJ~bs zt{EpUAElpX*s%o5E17WoM;MWS4uK>PL7@Ck#*+T6(!h%z0>jtDWP7&e{Ri2C>Ky%O zm#Qo6juxToL@*;cI zEmuNySL@3|Tc-c7t+Nb>vg_9HP)hfJbk`6wl2VGuAPn6-AX3sGjVRqHHKZWjFmw(` zr%1OTEg>BW)_L%}@AsV_=lM7Po|)Nu?X}i*uX~Fo!x^QfEIo(tS?z@evEv6jsbTI0 z!MVl#xGd~y1+#*$JxDSpUI>^=Z`J0a07_lI*tT19E_eArHv5hyvDxn20aDlBIPR|Th%fte63L&+1LGx2F488mUb?adqd zEI515351|DDa^d3o4lOAUY2=xIq>C#ASWX|CdRsdRY_uMlL_=$+y@B-*O>?UdIxte zQOmPe->TEWcJN#}XO!;ahIaf@<1Gs#&3~1dTVeI?qjPR1bFVOardh7+oMMJgyeJr4 zDU3SfC9s{IeQdcfvGzC|F8|Y}NkWLbo5wqqu7{IXkARz&Vwr%S){)xU)E1mN!+4-S zrgEgMhqUr(IbrX%GX&U#&WF*E(EcISv=x$1_jHA&+k?*hzI|PIlosE^mig$Y`~@o1 zxyYU%uXcp0YMfF_uCLgAvo=0yGt=+2*t7^YN~|%|!Q$=b!AG(xbOENot&FFcz+o_Ho~{lZ=Ee*Nk%ztF4a=$cFa z54_kVo4Hr&Aaj#fD?QLZ0teFqOxfpD&y{Priuzi+S4#&J;<6q|rSRDPU2s4d=nUdzhm6|6vP zQ*b~7I~_C^i6c`T4OUz0T z`eGgX4Kq)B->cbbQVT~ye#fnUgCG#G9ehtFomi`n5ySgOv&WP^#G2BPbe=oByG>U%ZmH{|@zC6l+J!|G9t0N^M_w&&i z2=;Mo?CI&-g5H)ENqb{sWBT(S1y43$3#6*{X<1oZ6Hl|ftgTd)|2~pcrr%ymoYB)W z^;p2hN6rlYyx+U8@F(*_Nw|;b^a$p+3eE8cS5~w!sOXc|;CX3zEXN-sf$e4Rv0oKc zK0*UGAp`V{_Wch9M#$hn1zBNl7q#Ew2>G)NdG7u91R z3hDq+-qRJYRLY1=l$=)*T4rGjr0Y?EfDon!;q|Lo)tx=F6oa}$g@#;{b;POy52=t8 z-xb@YmH<%(kSqJw)#U(5&*kBgH(-*vXx^w?fhf1&I&0^1nQRJET76ufUOb6?(83{&TDd;8%Tlu*SYQCI8vCS6>^ z3b|@O{?UbB=X@MJ;~KxpNba1{uR;Zo_Z|kR4P$ZW?~BFUPs{fTip?Om$s+|Rxr$(` z|4aUF`b0?Xra%d73hW_Od5`Acuzip(c}4n z$HF-GEkpQ)^KmSAr+cq|f#kF05~C?Zgj4HR;*J#sR>q%s*(z?_Lk0P2H|XpC0NQw| zX*VG>Esc!cLcVobar~q^2sv;oEnV7E-L;o}I1}h}!ZmJQ#2ToQ8aSbTr`hpMdlU(s z(&^22df>+WX=q!}05Rftozhy21tYq!$;B7Qn|Yb>-4II2M!o?*?*G|Z#_szeo`jPy z%b`tY&znZ;sc=6!FSj=w#46(Cyzs8M#Zpv}4J@K&kIiY`An%s_9fJg&AaRR2{v0zE z*+&nI!C^+WJu1|t>=-~pgSa^bgr!9PsW~MQBzOnIvBlO@sYr!Q*>=MB?S7>9V7e5Z(|uyUdj-hJT^vZP_yvjsX}+E8R!Xld$Eu2RlJYQ2O4?z|$4 zD8hWo<1~>Dc$#u&HqD4=lf6efI#pwA(|B-dXp|sGh7LLcSJv`oK3VDx>jj^;IH2Q3Ga%zkK z^Kf>X69hOt#7KH;KYMX%wz?@bynZlzryskM%bT{BJK?T6cEPdVi$6;U!J zvB0%g1$s76;^+716`2b1$R~waMu=in3$>ZC?{2vpucX=KH{7efSwYgHBMB20IwoAO^Ejs()Od@5Jc{yEMEfbIe#@|D z^W60gm+CB0@ub_kv)gxfbl(C?Hwa#eVPt^ltrG}F>w|khaL9ORRCemCQVEux0wPLT2(DJ*fDMSt#7NrGi)zE{A5K9`pF7q zOqA4yC#XNYe3~<(zu%C#s&4QK6 zEjn!=+KxFRe`m2;USCPmr+kJP@<=~zAKDikNZ4Es$FwgCnAEo{hV?ZdkhRoZGw;PYT4Ql z^buE==692~fCb~PZ9`-YwAqrocPeR$FZKOn4NM|5vO&@*%Mb9r43(0Drhiwx3HUcyM{uRyPOy zT@KkIA>LbQXQoZz5-gwVqG^4OqbC(e!4y(uRFW-qaO0q`N}sJn8qKS`vXUpm3Rcuf z8lN34bVLL`ANt)&*iKglL|gWXwu@XNVW3H*TF@4;4%Sx@88t?M`L|^p_d1jLyDC1% zwmLlA*|Q?-%HqeR&6B;z@1{a2>#eOG=e<$9-cmr%u2UyK7Omr)knsVInSWAwn8OEY zD5z$YI)gXdjze@ABV}qh`)(RSF1?BhQ?G_(LmdZUzlHZm&5m^UHnZHhj~X|#vNDe< zWXDj=k#Uh~>i`ld`N)m*tjB#ETHDglU~GLkhJ;%k>(b35sA{mf9aije@cLt=N%k%m zVZPRFCQI{c%pUMt=NLKY&Pe(QUm^k$+)^FHw! zwoc@}Y8p#=1mi$R6va!4zk!^9*H5$M&K9wjy$&8LMN#i_!6B<0VoR-V3{&7bR%Y-~ zN7CcQo1{8xn~Cx4=Q2I8M1cR}C~fZVm^Ux~&6qa|QyiUYVU9ifCf#Qs8f9=OrHP6h z#?-!z)Ox2FHTR$f60Ix5flZ;;RU9oOB6o*x66;prfVNGgwr3f+UY>fxTDRiU=w41L zOKvzMW-ZVvU0<69f&XWkAzj~ZXLvjKa2 z>D{;aGgI$NKLE9y(BDEYc1PO85+b69r-3^r?|lWO4G_VCp`)?M;(j{bWul|p+7V7{ z!BT>&HNi!yMwssI*U9WmVT24?32J8_b-tY2fFbF_RAIz8Sh~xiYSn~U@k`oX_A^(+ zcTR-qqQ)PwQ4QBisB)f1GLhU)-Xi-@(i8TVGr0a2mSLnZqxx57dgngBUk^ylaAB-6 zXXzYLssS7%;Tz+K?b0MM!oPj)d$ln!K0dlNI$*#DaZRX;qQwYmMWnv#vAlMWs^hQ< zk9lZkOGt&>r+l=GECPMXaNU-l;iGva5^CmcGZB z?KpnLAh{obO4=_+%A9@1!??_4Z-%zcVI^DA%HE^$O1(xqdOqV-uRx#wA&5ENVw$cYggY8~nw;8JLdMk8e?u^pSdr(#Pgr zyurxR;h5Cj+fiB%2$9GN93G-sjo@wi4zGg?{|jWWxA;vG!@r_l+;n)gbcEi#&*K6x zrj@HOGgTo$!INMWR-s?7cDK*AH)7t(Vh;3);H{^tb3{RDJD;YHQ??T^*wdIpHRY;q z$chwZdUu#ZvlW8E-{T*Te$LD#NR+Iq%0Z&(^8~0V%7HOdike$Q|(lm3JLyI|@i2YWWIa*F_I|U>h924t3O`_99 zTlX+*YfUC>~q&K}LG9H}*!bK+;=}}5^+Kc56 zR6fljlHt0GGhJCBZm&ox6Hw`i9$^B+N;TxR* z0PbYlF$1rDJKu-88_xpmzte0!%zpr0wmVYQQmfbg4tGl$K6B2nV{KXuq-KabTdLm2 zn!4#h?6{qrfOxzQo?t0rku?QsvsvL`T4UgqS>nz>F2+%jIx(at?r=V7rdB{WcNY`1 z8uKOldTw6&pp*sGS_+5t#Jo=RF4;*SC4g1=w9Eh~`oG%AHc8AT8%~n&&!6xmY$S1Y zUy$RB-_5pKQf`z+_uw#2V5$&f0i?<+I$beAG^Lx>KK&$xYA6cV_o~UlZyy#>d+uS! zM+)aHzqNP5VO+>r4-t-5F@kS8B3Lb`pIH*$H|_A0HjpEm(FE^yn=jQ#?L-lhB7n4gtv zvP+j&0$;$d$*?Hgq6S5Z1et6(9|s%EMFD7#7DEZdUrIhnZTYS?%DGaSi6Cr+gghNy zlA6PBn)AlELE3uBDwb%=pkzi7@sT`J(db4Vo9=0JZPaZuv2_bsZ*lA&( zK+@@mp%>(BN76kj#U>)>22$)?|TWS`3K&FjY4$Kmj}?-8V8trRu8orn$g{ z9-4dg9pHu?Q@*>`cQ~YMOvihkZ3lb$`(%c{S1tQi zZ~UvuUiLysLy=$_K05MJq%PN8LAtT}pS0xpe1)H#u5t*jrxOj$J?(jpJUn9`VYDqz z>+22J7aPo=luEc(vias&BLF>ZO8Jj4;S=$SzKOw$1RuXVRp8ok5#OGW|3JjLw@u4l zb(U1HVb^iAJ4zRO^ZpVb)?6_{5}U4}wh(304qY^@t(x}8(P@L=a^2=-WU2}4o&eYU zoE;8iF4;unqp3YUfgB%Upra0WB_2Prtf(Y3mb`DT^EP6((A<)bib<4)CDSqK@^3r<=H-vfR+(PUW~CnW z$lYiJbWhh=`SNSyRV1x$*I+#aJPZBe>>?$)N#a+DX<(y(-hf^OH8GMQh2etfEAm)Rxh6>=p_q&*@??8gIauU|ByzH(uUZV+@wX_>R)#c-b3?Z^Jh&LjbpuA91a)3H5b zF&&YIUO8lV1jKV5ba{H>5?xgbUXR9)8;w`UBaP7JS<|^?AeY#q1=svxB@)Ls5Pdxi z7P$+#bb0PI>vLTSPho^LBH{P12^$lB?gI-^$9n1Zz~}*MLbu>EKe}BHz(*;-;?M7u zuL9e9!^0~9KS-HcNnECLsXuPm*K>s;`0$t>hw2m>w|&dIqn!t1p18ptN!~b^N`2eq zGYQgPE2V&vm2b#D{J3$E$@hRTs+gy?6w~~6`(7f(mdVBX%nYMGe{f;+CocGe zJ)2K2+RzK7eCv6E<%YN)61r;E<~4C~_;>a%JwOup79qDukK+S1g=#72j&Smh45}zc zLbHY$J=YX^8T2Cfil6Egw);AppGt|W4f(qx6%74(#y)4YA^U;cNhD0-ka9DCFBrS_ z|I$nbBn4ZCxFbWz%TzCQ3=Ys@dzz@DMJTjJA4jJBg~AABC=$B^dfSqbP&erYAH_30 zg`jMPL-lprQ`A&%FuuNBYN749GtAzx#o?rw#Biy^{88A8Kp&*-(JlC6p#{ z#g8j-y*chnc9zM|Ay~!6i>xQ^!bP*Yq2c7b;4C2;S~341Y~IRGcgXvQ<&*Vw2}F!L z?B4QpB+IE6=Rx#Je%eq8y(rN8x@?p^quh!AjC*Dn_Kkh&4#iQtfwW)0U>bw!~lILb0;>gWzEMoXY^ zjiv&5jY&;mmr`b^vYiPz19e}~F8ZtmDt!HU{Ckv1uZ9`Lj1Q`Y4VNz1YhH#jmD-Z8 z6a&nQQN}fAY09M!Smn}3m?cu?$octad~C^UzG&Y#T7P3(Vv+c6eG371O~o6O^snl* zGUcVe4NwGM{wZ`8clloiBTJA3r76(a3t(%VXXgc#^$3 zn81PIh|<~G{_=%v*~_H4v+1>@#%sjmoBhdsq<^xvpwd|S<%kz)1`4n zP}rXLsXT49d(=FMD5S)KO?Z~Mn-hea#U7IKFgX%%@7aCGFyu>=o6a2`Xq~B7peYjf ZhlM#`EFb^? literal 0 HcmV?d00001 diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/doc/ChargingImage.png b/bundles/org.openhab.binding.bmwconnecteddrive/doc/ChargingImage.png new file mode 100644 index 0000000000000000000000000000000000000000..09a132f25550cdb6bab08d3db67047a881c882b4 GIT binary patch literal 192764 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⪻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þv*A~i-0QHNSw0U*`{VQ~)8*L` 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%0AD(X|3m;w+ap; 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

Khlf}^UBU}~-q#8ToH3~~n$k?xW}tE$2&5iT~m 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

_ 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

E3ufPx~=;5T?2+&<%fTv(yUbZyb5m#qwae- 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

?sGQ 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 z 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�rF#n& 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

Xhd=wf{YexXQXwb4@zqb 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�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ÐP3tJqqXKW_B3#I%-0n;8Uis>G)M^)=2FSv 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 org.openhab.addons.bundles org.openhab.addons.reactor.bundles - 2.5.8-SNAPSHOT + 2.5.9-SNAPSHOT org.openhab.binding.bmwconnecteddrive diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 180f0a636f0db..4db186fef7de9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -166,7 +166,9 @@ public String toString() { public static final String HEADING = "heading"; // Image - public static final String IMAGE = "png"; + public static final String IMAGE_FORMAT = "png"; + public static final String IMAGE_VIEWPORT = "view"; + public static final String IMAGE_SIZE = "size"; // Remote Services public static final String REMOTE_SERVICE_LIGHT_FLASH = "light"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java index e4d4a308a6c2d..d7b22d44ece8d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java @@ -121,14 +121,6 @@ public CBSMessage getNextService(boolean imperial) { return cbs; } - private Object getUnit(boolean imperial) { - if (imperial) { - return MILES_SHORT; - } else { - return KM_SHORT; - } - } - public String getCheckControl() { if (checkControlMessages == null) { return Converter.toTitleCase(UNKNOWN); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index 7802be4ac8a3a..548e1f32e1f7b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -38,6 +38,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; import org.openhab.binding.bmwconnecteddrive.internal.utils.BimmerConstants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; +import org.openhab.binding.bmwconnecteddrive.internal.utils.ImageProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -97,13 +98,7 @@ public synchronized void request(String url, Optional> params, if (params.isPresent()) { String urlEncodedData = UrlEncoded.encode(params.get(), Charset.defaultCharset(), false); completeUrl.append("?").append(urlEncodedData); - // req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); - // req.header(CONTENT_LENGTH, Integer.toString(urlEncodedData.length())); - // req.content(new StringContentProvider(urlEncodedData)); - // logger.info("URL has parameters {}", urlEncodedData); - // logger.info("Params for request: {}", urlEncodedData); } - logger.info("Complete URL {}", completeUrl.toString()); Request req = httpClient.newRequest(completeUrl.toString()); req.header(HttpHeader.CONNECTION, KEEP_ALIVE); req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); @@ -163,18 +158,12 @@ public void requestRangeMap(VehicleConfiguration config, Optional vehicleStatusCache = Optional.empty(); + protected Optional lastTripCache = Optional.empty(); + protected Optional allTripsCache = Optional.empty(); + protected Optional chargeProfileCache = Optional.empty(); + protected Optional rangeMapCache = Optional.empty(); + protected Optional destinationCache = Optional.empty(); + protected Optional imageCache = Optional.empty(); public VehicleChannelHandler(Thing thing) { super(thing); @@ -185,7 +198,9 @@ public VehicleChannelHandler(Thing thing) { destinationLat3 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_LAT_3); destinationLon3 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_LON_3); - imageChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE); + imageChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_FORMAT); + imageViewportChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_VIEWPORT); + imageSizeChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_SIZE); vehicleFingerPrint = new ChannelUID(thing.getUID(), CHANNEL_GROUP_TROUBLESHOOT, VEHICLE_FINGERPRINT); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 2a51ba1ebc27a..f390aa615c1d4 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -64,6 +64,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.handler.RemoteServiceHandler.RemoteService; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; +import org.openhab.binding.bmwconnecteddrive.internal.utils.ImageProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -89,6 +90,7 @@ public class VehicleHandler extends VehicleChannelHandler { private boolean isHybrid = false; private Position currentPosition = new Position(); + private ImageProperties imageProperties = new ImageProperties(); StringResponseCallback vehicleStatusCallback = new VehicleStatusCallback(); StringResponseCallback lastTripCallback = new LastTripCallback(); @@ -98,16 +100,6 @@ public class VehicleHandler extends VehicleChannelHandler { StringResponseCallback destinationCallback = new DestinationsCallback(); ByteResponseCallback imageCallback = new ImageCallback(); - private Optional vehicleStatusCache = Optional.empty(); - private Optional lastTripCache = Optional.empty(); - private Optional allTripsCache = Optional.empty(); - private Optional chargeProfileCache = Optional.empty(); - private Optional rangeMapCache = Optional.empty(); - private Optional destinationCache = Optional.empty(); - private Optional imageCache = Optional.empty(); - private int imageFailCounter = 0; - private final int imageFailConuterMax = 5; - public VehicleHandler(Thing thing, HttpClient hc, String type, boolean imperial) { super(thing); this.imperial = imperial; @@ -139,127 +131,150 @@ public void handleCommand(ChannelUID channelUID, Command command) { } else if (CHANNEL_GROUP_TROUBLESHOOT.equals(group)) { imageCallback.onResponse(imageCache); } - } else { + } + + // Check for Channel Group and corresponding Actions + if (CHANNEL_GROUP_REMOTE.equals(group)) { // Executing Remote Services - if (CHANNEL_GROUP_REMOTE.equals(channelUID.getGroupId())) { - logger.info("Remote Command {}", CHANNEL_GROUP_REMOTE); - if (command instanceof OnOffType) { - if (command.equals(OnOffType.ON)) { - if (remote.isPresent()) { - switch (channelUID.getIdWithoutGroup()) { - case REMOTE_SERVICE_LIGHT_FLASH: - updateState(remoteLightChannel, - OnOffType.from(remote.get().execute(RemoteService.LIGHT_FLASH))); - break; - case REMOTE_SERVICE_AIR_CONDITIONING: - updateState(remoteClimateChannel, - OnOffType.from(remote.get().execute(RemoteService.AIR_CONDITIONING))); - break; - case REMOTE_SERVICE_DOOR_LOCK: - updateState(remoteLockChannel, - OnOffType.from(remote.get().execute(RemoteService.DOOR_LOCK))); - break; - case REMOTE_SERVICE_DOOR_UNLOCK: - updateState(remoteUnlockChannel, - OnOffType.from(remote.get().execute(RemoteService.DOOR_UNLOCK))); - break; - case REMOTE_SERVICE_HORN: - updateState(remoteHornChannel, - OnOffType.from(remote.get().execute(RemoteService.HORN))); - break; - case REMOTE_SERVICE_VEHICLE_FINDER: - updateState(remoteFinderChannel, - OnOffType.from(remote.get().execute(RemoteService.VEHICLE_FINDER))); - break; - } + if (command instanceof OnOffType) { + if (command.equals(OnOffType.ON)) { + if (remote.isPresent()) { + switch (channelUID.getIdWithoutGroup()) { + case REMOTE_SERVICE_LIGHT_FLASH: + updateState(remoteLightChannel, + OnOffType.from(remote.get().execute(RemoteService.LIGHT_FLASH))); + break; + case REMOTE_SERVICE_AIR_CONDITIONING: + updateState(remoteClimateChannel, + OnOffType.from(remote.get().execute(RemoteService.AIR_CONDITIONING))); + break; + case REMOTE_SERVICE_DOOR_LOCK: + updateState(remoteLockChannel, + OnOffType.from(remote.get().execute(RemoteService.DOOR_LOCK))); + break; + case REMOTE_SERVICE_DOOR_UNLOCK: + updateState(remoteUnlockChannel, + OnOffType.from(remote.get().execute(RemoteService.DOOR_UNLOCK))); + break; + case REMOTE_SERVICE_HORN: + updateState(remoteHornChannel, + OnOffType.from(remote.get().execute(RemoteService.HORN))); + break; + case REMOTE_SERVICE_VEHICLE_FINDER: + updateState(remoteFinderChannel, + OnOffType.from(remote.get().execute(RemoteService.VEHICLE_FINDER))); + break; } - updateState(vehicleFingerPrint, OnOffType.OFF); } + updateState(vehicleFingerPrint, OnOffType.OFF); } } - - // Log Troubleshoot data - if (channelUID.getIdWithoutGroup().equals(VEHICLE_FINGERPRINT)) { - logger.info("Trigger Vehicle Fingerprint"); - if (command instanceof OnOffType) { - if (command.equals(OnOffType.ON)) { - logger.warn( - "###### BMW ConnectedDrive Binding - Vehicle Troubleshoot Fingerprint Data - BEGIN ######"); - logger.warn("### Discovery Result ###"); - logger.warn("{}", bridgeHandler.get().getDiscoveryFingerprint()); - if (vehicleStatusCache.isPresent()) { - logger.warn("### Vehicle Status ###"); - - // Anonymous data for VIN and Position - VehicleStatusContainer container = Converter.getGson().fromJson(vehicleStatusCache.get(), - VehicleStatusContainer.class); - VehicleStatus status = container.vehicleStatus; - status.vin = Constants.ANONYMOUS; - if (status.position != null) { - status.position.lat = -1; - status.position.lon = -1; - status.position.heading = -1; - logger.warn("{}", Converter.getGson().toJson(container)); - } - } else { - logger.warn("### Vehicle Status Empty ###"); - } - if (lastTripCache.isPresent()) { - logger.warn("### Last Trip ###"); - logger.warn("{}", - lastTripCache.get().replaceAll(configuration.get().vin, Constants.ANONYMOUS)); - } else { - logger.warn("### Last Trip Empty ###"); - } - if (allTripsCache.isPresent()) { - logger.warn("### All Trips ###"); - logger.warn("{}", - allTripsCache.get().replaceAll(configuration.get().vin, Constants.ANONYMOUS)); - } else { - logger.warn("### All Trips Empty ###"); + } else if (CHANNEL_GROUP_VEHICLE_IMAGE.equals(group)) { + // Image Change + if (configuration.isPresent()) { + if (command instanceof StringType) { + if (channelUID.getIdWithoutGroup().equals(IMAGE_VIEWPORT)) { + String newViewport = command.toString(); + synchronized (imageProperties) { + imageProperties = new ImageProperties(newViewport, imageProperties.size); + imageCache = Optional.empty(); + proxy.get().requestImage(configuration.get(), imageProperties, imageCallback); } - if (isElectric) { - if (chargeProfileCache.isPresent()) { - logger.warn("### Charge Profile ###"); - logger.warn("{}", chargeProfileCache.get().replaceAll(configuration.get().vin, - Constants.ANONYMOUS)); - } else { - logger.warn("### Charge Profile Empty ###"); + updateState(imageViewportChannel, StringType.valueOf(newViewport)); + } + } + if (command instanceof DecimalType) { + if (command instanceof DecimalType) { + int newImageSize = ((DecimalType) command).intValue(); + if (channelUID.getIdWithoutGroup().equals(IMAGE_SIZE)) { + synchronized (imageProperties) { + imageProperties = new ImageProperties(imageProperties.viewport, newImageSize); + imageCache = Optional.empty(); + proxy.get().requestImage(configuration.get(), imageProperties, imageCallback); } } - if (destinationCache.isPresent()) { + updateState(imageSizeChannel, new DecimalType(newImageSize)); + } + } + } + } + if (channelUID.getIdWithoutGroup().equals(VEHICLE_FINGERPRINT)) { + // Log Troubleshoot data + if (command instanceof OnOffType) { + if (command.equals(OnOffType.ON)) { + logger.warn( + "###### BMW ConnectedDrive Binding - Vehicle Troubleshoot Fingerprint Data - BEGIN ######"); + logger.warn("### Discovery Result ###"); + logger.warn("{}", bridgeHandler.get().getDiscoveryFingerprint()); + if (vehicleStatusCache.isPresent()) { + logger.warn("### Vehicle Status ###"); + + // Anonymous data for VIN and Position + VehicleStatusContainer container = Converter.getGson().fromJson(vehicleStatusCache.get(), + VehicleStatusContainer.class); + VehicleStatus status = container.vehicleStatus; + status.vin = Constants.ANONYMOUS; + if (status.position != null) { + status.position.lat = -1; + status.position.lon = -1; + status.position.heading = -1; + logger.warn("{}", Converter.getGson().toJson(container)); + } + } else { + logger.warn("### Vehicle Status Empty ###"); + } + if (lastTripCache.isPresent()) { + logger.warn("### Last Trip ###"); + logger.warn("{}", lastTripCache.get().replaceAll(configuration.get().vin, Constants.ANONYMOUS)); + } else { + logger.warn("### Last Trip Empty ###"); + } + if (allTripsCache.isPresent()) { + logger.warn("### All Trips ###"); + logger.warn("{}", allTripsCache.get().replaceAll(configuration.get().vin, Constants.ANONYMOUS)); + } else { + logger.warn("### All Trips Empty ###"); + } + if (isElectric) { + if (chargeProfileCache.isPresent()) { logger.warn("### Charge Profile ###"); - DestinationContainer container = Converter.getGson().fromJson(destinationCache.get(), - DestinationContainer.class); - if (container.destinations != null) { - container.destinations.forEach(entry -> { - entry.lat = 0; - entry.lon = 0; - entry.city = Constants.ANONYMOUS; - entry.street = Constants.ANONYMOUS; - entry.streetNumber = Constants.ANONYMOUS; - entry.country = Constants.ANONYMOUS; - }); - logger.warn("{}", Converter.getGson().toJson(container)); - } else { - logger.warn("### Destinations Empty ###"); - } + logger.warn("{}", + chargeProfileCache.get().replaceAll(configuration.get().vin, Constants.ANONYMOUS)); } else { logger.warn("### Charge Profile Empty ###"); } - if (rangeMapCache.isPresent()) { - logger.warn("### Range Map ###"); - logger.warn("{}", - rangeMapCache.get().replaceAll(configuration.get().vin, Constants.ANONYMOUS)); + } + if (destinationCache.isPresent()) { + logger.warn("### Charge Profile ###"); + DestinationContainer container = Converter.getGson().fromJson(destinationCache.get(), + DestinationContainer.class); + if (container.destinations != null) { + container.destinations.forEach(entry -> { + entry.lat = 0; + entry.lon = 0; + entry.city = Constants.ANONYMOUS; + entry.street = Constants.ANONYMOUS; + entry.streetNumber = Constants.ANONYMOUS; + entry.country = Constants.ANONYMOUS; + }); + logger.warn("{}", Converter.getGson().toJson(container)); } else { - logger.warn("### Range Map Empty ###"); + logger.warn("### Destinations Empty ###"); } - logger.warn( - "###### BMW ConnectedDrive Binding - Vehicle Troubleshoot Fingerprint Data - END ######"); + } else { + logger.warn("### Charge Profile Empty ###"); + } + if (rangeMapCache.isPresent()) { + logger.warn("### Range Map ###"); + logger.warn("{}", rangeMapCache.get().replaceAll(configuration.get().vin, Constants.ANONYMOUS)); + } else { + logger.warn("### Range Map Empty ###"); } - // Switch back to off immediately - updateState(channelUID, OnOffType.OFF); + logger.warn( + "###### BMW ConnectedDrive Binding - Vehicle Troubleshoot Fingerprint Data - END ######"); } + // Switch back to off immediately + updateState(channelUID, OnOffType.OFF); } } } @@ -299,18 +314,23 @@ public void initialize() { remote = Optional.of(proxy.get().getRemoteServiceHandler(this)); } } else { - logger.warn("Brdige Handler null"); + logger.debug("Brdige Handler null"); } } else { - logger.warn("Bridge null"); + logger.debug("Bridge null"); } // Switch all Remote Service Channels Off switchRemoteServicesOff(); updateState(vehicleFingerPrint, OnOffType.OFF); - // get Vehicle Image - if not successful 5 times retry is established - proxy.get().requestImage(configuration.get(), imageCallback); + // get Image after init with config values + synchronized (imageProperties) { + imageProperties = new ImageProperties(configuration.get().imageViewport, + configuration.get().imageSize); + } + updateState(imageViewportChannel, StringType.valueOf((configuration.get().imageViewport))); + updateState(imageSizeChannel, new DecimalType((configuration.get().imageSize))); // check imperial setting is different to AutoDetect if (!UNITS_AUTODETECT.equals(configuration.get().units)) { @@ -325,7 +345,7 @@ public void initialize() { } } - private void switchRemoteServicesOff() { + public void switchRemoteServicesOff() { updateState(remoteLightChannel, OnOffType.from(false)); updateState(remoteFinderChannel, OnOffType.from(false)); updateState(remoteLockChannel, OnOffType.from(false)); @@ -347,7 +367,6 @@ private void startSchedule(int interval) { @Override public void dispose() { - logger.info("Dispose Thing {}", thing.getUID()); if (refreshJob.isPresent()) { refreshJob.get().cancel(true); } @@ -366,9 +385,10 @@ public void getData() { if (isElectric) { proxy.get().requestChargingProfile(configuration.get(), chargeProfileCallback); } - if (imageFailCounter <= imageFailConuterMax) { - // get Vehicle Image a few times - then refuse - proxy.get().requestImage(configuration.get(), imageCallback); + synchronized (imageProperties) { + if (!imageCache.isPresent() && !imageProperties.failLimitReached()) { + proxy.get().requestImage(configuration.get(), imageProperties, imageCallback); + } } } else { logger.warn("ConnectedDrive Proxy isn't present"); @@ -405,8 +425,6 @@ private void requestRangeMap(Position p) { // } double diff = Converter.measureDistance(p.lat, p.lon, currentPosition.lat, currentPosition.lon); if (diff > 1000) { - logger.info("Difference between old {} and new Position {} = {}", currentPosition.toString(), p.toString(), - diff); LocalDateTime ldt = LocalDateTime.now(); MultiMap dataMap = new MultiMap(); dataMap.add("deviceTime", ldt.format(Converter.DATE_INPUT_PATTERN)); @@ -547,7 +565,9 @@ public void onResponse(Optional content) { String contentType = HttpUtil.guessContentTypeFromData(content.get()); updateState(imageChannel, new RawType(content.get(), contentType)); } else { - imageFailCounter++; + synchronized (imageProperties) { + imageProperties.failed(); + } } } @@ -557,7 +577,9 @@ public void onResponse(Optional content) { @Override public void onError(NetworkError error) { logger.debug("{}", error.toString()); - imageFailCounter++; + synchronized (imageProperties) { + imageProperties.failed(); + } } } @@ -650,7 +672,6 @@ private void setThingStatus(ThingStatus status, ThingStatusDetail detail, String @Override public void onResponse(Optional content) { - logger.info("Update Thing {}", thing.getUID()); if (content.isPresent()) { setThingStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE, Constants.EMPTY); vehicleStatusCache = content; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java index 65479f9ddcb27..09619e440c7d8 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -33,8 +33,6 @@ public class Constants { public static final String NO_SERVICE_REQUEST = "No Service Requests"; public static final String UTC_APPENDIX = "-01T12:00:00"; public static final String NULL_DATE = "1900-01-01T00:00:00"; - public static final String MILES_SHORT = "mi"; - public static final String KM_SHORT = "km"; // Services to query public static final String SERVICES_SUPPORTED = "Services Supported"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java index 2e6e285732a19..ed341eae6c96b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java @@ -95,8 +95,8 @@ public static Gson getGson() { * @param destinationLongitude * @return distance */ - public static double measureDistance(float sourceLatitude, float sourceLongitude, float destinationLatitude, - float destinationLongitude) { + public static double measureDistance(double sourceLatitude, double sourceLongitude, double destinationLatitude, + double destinationLongitude) { double earthRadius = 6378.137; // Radius of earth in KM double dLat = destinationLatitude * Math.PI / 180 - sourceLatitude * Math.PI / 180; double dLon = destinationLongitude * Math.PI / 180 - sourceLongitude * Math.PI / 180; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ImageProperties.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ImageProperties.java new file mode 100644 index 0000000000000..8028ad09ca73e --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ImageProperties.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.utils; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link ImageProperties} Properties of current Vehicle Image + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class ImageProperties { + public static final int RETRY_COUNTER = 5; + public int failCounter = 0; + public String viewport = Constants.EMPTY; + public int size = -1; + + public ImageProperties(String viewport, int size) { + this.viewport = viewport; + this.size = size; + } + + public ImageProperties() { + } + + public boolean isSame(String viewport, int size) { + return this.viewport.equals(viewport) && this.size == size; + } + + public void failed() { + failCounter++; + } + + public boolean failLimitReached() { + return failCounter > RETRY_COUNTER; + } + + @Override + public String toString() { + return new StringBuffer(viewport).append(Integer.toString(size)).toString(); + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_be.properties b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_be.properties index 6e4577565b06e..0eda6e90a9427 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_be.properties +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_be.properties @@ -132,6 +132,7 @@ channel-type.bmwconnecteddrive.service-date-channel.label = N channel-type.bmwconnecteddrive.service-milegae-channel.label = Nächster Service bei Kilometer channel-type.bmwconnecteddrive.service-name-channel.label = Nächster Service channel-type.bmwconnecteddrive.check-control-channel.label = Aktuelle Warnung +channel-type.bmwconnecteddrive.charging-status-channel.label = Ladezustand channel-type.bmwconnecteddrive.last-update-channel.label = Letzte Aktualisierung channel-type.bmwconnecteddrive.mileage-channel.label = Tachostand @@ -144,7 +145,6 @@ channel-type.bmwconnecteddrive.range-radius-electric-channel.label = Elektrische channel-type.bmwconnecteddrive.range-radius-fuel-channel.label = Verbrenner Reichweiten-Radius channel-type.bmwconnecteddrive.range-radius-hybrid-channel.label = Hybrider Reichweiten-Radius -channel-type.bmwconnecteddrive.charging-status-channel.label = Ladezustand channel-type.bmwconnecteddrive.profile-climate-channel.label = Klimatisierung bei Abfahrt channel-type.bmwconnecteddrive.profile-mode-channel.label = Ladeprofil Einstellung channel-type.bmwconnecteddrive.window-start-channel.label = Startzeit Ladefenster @@ -192,6 +192,8 @@ channel-type.bmwconnecteddrive.remote-climate-channel.label = Klimatisierung Aus channel-type.bmwconnecteddrive.remote-state-channel.label = Ausführungszustand channel-type.bmwconnecteddrive.png-channel.label = Fahrzeug Bild +channel-type.bmwconnecteddrive.image-view-channel.label = Fahrzeug Ansicht +channel-type.bmwconnecteddrive.image-size-channel.label = Fahrzeug Bildgöße channel-type.bmwconnecteddrive.vehicle-fingerprint-channel.label = Fahrzeug Fingerabdruck channel-type.bmwconnecteddrive.discovery-fingerprint-channel.label = Portal Fingerabdruck diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-group.xml index a802fcc6b89b3..88dc047f40f4c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-group.xml @@ -5,9 +5,11 @@ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - Provides an Image of your Vehicle based on the Configuration ViewPort + Provides an Image of your Vehicle + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml index 0c539f8d4c58e..3f8ad1b87524e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml @@ -7,4 +7,12 @@ Image + + String + + + + Number + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-group.xml index 6b966dd4ea00b..594999f51ed37 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-group.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - Generating Debug Data if a Problem Report shall be raised + Generates Debug Data diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java index b9d9eca63034c..1c216afa01ec9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java @@ -64,4 +64,13 @@ public void testTimeUTCToLocaleTime() { assertEquals("Output DateTime", "2020-08-24T17:55:32", localeTime); assertEquals("DateTimeType Value", "2020-08-24T17:55:32", dateTimeType); } + + @Test + public void testDistance() { + double lat = 50.5560; + double lon = 8.4956; + double distance = 0.005; + double dist = Converter.measureDistance(lat, lon, lat + distance, lon + distance); + assertTrue("Distance below 1 km", dist < 1); + } } From 581ac0f39ef680723b4ef4971b63e64e14a27c8c Mon Sep 17 00:00:00 2001 From: Bernd Date: Mon, 14 Sep 2020 20:13:22 +0200 Subject: [PATCH 029/176] token handling optimization Signed-off-by: Bernd (cherry picked from commit 84591625fbfe6740f76ebb32ff30ac7ff560f34f) Signed-off-by: Bernd --- .../README.md | 95 ++++++++--------- .../doc/properties.png | Bin 74860 -> 49353 bytes .../internal/ConnectedDriveConstants.java | 2 +- .../internal/VehicleConfiguration.java | 4 +- .../internal/discovery/VehicleDiscovery.java | 7 +- .../internal/dto/status/Position.java | 4 +- .../internal/dto/status/VehicleStatus.java | 7 ++ .../internal/handler/ConnectedDriveProxy.java | 96 ++++++++---------- .../handler/RemoteServiceHandler.java | 56 +++++----- .../internal/handler/VehicleHandler.java | 16 +-- .../internal/utils/HTTPConstants.java | 3 + .../internal/utils/ImageProperties.java | 4 - ...erties => bmwconnecteddrive_de.properties} | 34 +++---- .../ESH-INF/thing/charge-channel-groups.xml | 2 +- .../thing/ev-last-trip-channel-types.xml | 4 +- .../thing/ev-lifetime-channel-types.xml | 4 +- .../ESH-INF/thing/image-channel-types.xml | 2 +- .../ESH-INF/thing/loction-channel-types.xml | 10 +- .../ESH-INF/thing/range-channel-types.xml | 2 +- .../resources/ESH-INF/thing/thing-bev.xml | 3 + .../resources/ESH-INF/thing/thing-bev_rex.xml | 3 + .../resources/ESH-INF/thing/thing-conv.xml | 3 + .../resources/ESH-INF/thing/thing-phev.xml | 3 + .../thing/troubleshoot-channel-types.xml | 2 +- .../thing/vehicle-status-channel-types.xml | 2 +- .../internal/handler/AuthTest.java | 3 +- 26 files changed, 190 insertions(+), 181 deletions(-) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/{bmwconnecteddrive_be.properties => bmwconnecteddrive_de.properties} (90%) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 42372b3bef8ee..c404003da4222 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -31,9 +31,10 @@ The Bridge establishes the Connection between BMW ConnectedDrive Portal and open ### Things -Four different Vehicle Types are provided. They differ in the supported Channel Groups & Channels. -While Conventional Fuel Vehicles have no "Charging Profile" Electric Vehicles don't provide a _fuel range_. -For Hybrid Vehicles _fuel range_ and _electric range_ is provided and in addition a _combined range_ +Four different Vehicle Types are provided. +They differ in the supported Channel Groups & Channels. +Conventional Fuel Vehicles have no _Charging Profile_, Electric Vehicles don't provide a _Fuel Range_. +For Hybrid Vehicles in addition to _Fuel and Electric Range_ the _Hybrid Range_ is shown. | Name | Thing Type ID | Supported Channel Groups | |-------------------------------------|---------------|------------------------------------------------------------| @@ -47,11 +48,11 @@ For Hybrid Vehicles _fuel range_ and _electric range_ is provided and in additio -For each Vehicle Properties are set with various informations. -They are especially handy to figure out the provided Services of your Vehicle. +Each Vehicle contains Properties. +They are especially handy to figure out the provided Services. In the right picture you can see in _Activated Services_ e.g. the _DoorLock_ and _DoorUnlock_ Services are mentioned. -So you're sure that in Channel Group _Remote Services_ you are able to execute these commands. -Also _LastDestinations_ is mentioned in _Supported Services_ so it's valid to connect Channel Group _Last Destinations_ in order to display the last 3 Navigation Destinations. +So you're sure that in [Channel Group _Remote Services_](#channel-group-remote-services) you are able to execute these commands. +Also _LastDestinations_ is mentioned in _Supported Services_ so it's valid to connect Channel Group [Last Destinations](#channel-group-destinations) in order to display the last 3 Navigation Destinations. Basically 3 Types of Information are registered as Properties @@ -63,9 +64,9 @@ Basically 3 Types of Information are registered as Properties Auto Discovery is starting after you created the Bridge towards BMW ConnectedDrive. A list of your registered Vehicles is queried and all found Vehicles are added in Inbox. -As Unique Identifier the _Vehicle Identification Number_ (VIN) is used. -If you already predefined a Thing in *.things configuration with the same VIN the Discovery won't discover it again. -The Discovery still takes care updating the Properties of your Vehicle. +Unique Identifier is the _Vehicle Identification Number_ (VIN). +If a Thing is already declared in a _*.things configuration_ Discovery won't highlight it again. +But it takes care updating the correct Properties. ## Configuration @@ -85,14 +86,14 @@ The region Configuration has 3 different possibilities ### Things -All Things are needing the same Configuration Data +Same Configuration is needed for all Thingds | Parameter | Type | Description | |-----------------|---------|---------------------------------------| | vin | text | Vehicle Identification Number (VIN) | | refreshInterval | integer | Refresh Interval in Minutes | | units | text | Unit Selection | -| imageSize | integer | Image Picture Size | +| imageSize | integer | Image Size | | imageViewport | text | Image Viewport | The units can be configured in 3 ways @@ -118,7 +119,7 @@ The Channel Groups are different for the Vehicle Types, on the build in Sensors ### Bridge Channels -If your Vehicle isn't found in the Discovery force a log of Fingerprint Data which helps analyzing the problem. +If your Vehicle isn't found in the Discovery force a log of Fingerprint Data which helps to analyze the problem. Please check [TroubleShooting Section](#TroubleShooting) for further advice. | Channel Label | Channel ID | Type | Description | @@ -138,19 +139,19 @@ Available for all Vehicles, Read-only. | Window Status | status | windows | String | Closed if all closed, else reports the Window which is still open | | Doors Locked | status | lock | String | Status if Doors are locked or unlocked | | Next Service Date | status | service-date | DateTime | Date of Upcoming Service | -| Mileage till Next Service | status | service-mileage | Number:Length | Mileage till Upcoming Service | +| Mileage till Next Service | status | service-mileage | Number:Length | Mileage till Upcoming Service | | Next Service Description | status | service-name | String | Description of Upcoming Service | | Check Control | status | check-control | String | Description of actual Check Control message, Ok if none is activated | -| Charging Status | status | charge | String | Only available for PHEV, BEV_REX and BEV -| Last Status Update | status | last-update | DateTime | Date and Time of last status updateDescription of actual Check Control message, Ok if none is activated | +| Charging Status | status | charge | String | Only available for PHEV, BEV_REX and BEV | +| Last Status Timestamp | status | last-update | DateTime | Date and Time of last status update. | See [further details for DateTime](#last-status-update-timestamp) in case of wrong timestamp values #### Channel Group _Range Data_ Based on Vehicle Type (Thing Type ID) some Channels are presented or not. -For Conventional Fuel Vehicles the *Electric Range* isn't presented while for Battery Electric Vehicles *Range Fuel* isn't valid. -Hybrid Vehicles have both and in addition *Hybrid Range* +Conventional Fuel Vehicles don't provide *Electric Range* and Battery Electric Vehicles don't show *Range Fuel*. +Hybrid Vehicles have both and in addition *Hybrid Range*. These are Read-only values. | Channel Label | Channel Group ID | Channel ID | Type | CONV | PHEV | BEV_REX | BEV | @@ -165,7 +166,7 @@ These are Read-only values. | Electric Range Radius | range | range-radius-electric | Number:Length | | X | X | X | | Hybrid Range Radius | range | range-radius-hybrid | Number:Length | | X | X | | -See Description [Range vs. Range Radius](#range-vs.-range-radius) to get more information +See Description [Range vs Range Radius](#range-vs-range-radius) to get more information #### Channel Group _Charge Profile_ @@ -202,33 +203,33 @@ These are Read-only values. #### Channel Group _Last Trip_ -Check in your Vehicle Thing Properties if *Statistics* is present in *Services Supported* +Check in your [Vehicle Properties](#Properties) if *Statistics* is present in *Services Supported* These are Read-only values. -| Channel Label | Channel Group ID | Channel ID | Type | Description | -|-----------------------------|------------------|-------------------------|---------------|---------------------------------------------------| -| Distance Driven | last-trip | distance | Number:Length | Distance Driven on your Last Trip | -| Distance since Last Charge | last-trip | distance-since-charging | Number:Length | Distance Driven since Last Charge | -| Average Consumption | last-trip | average-consumption | Number:Power | Average Power Consumption on your Last Trip per 100 km | -| Average Recuperation | last-trip | average-recuperation | Number:Power | Average Power Recuperation on your Last Trip per 100 km | +| Channel Label | Channel Group ID | Channel ID | Type | +|---------------------------------------|------------------|-------------------------|---------------| +| Average Power Consumption per 100 km | last-trip | average-consumption | Number:Power | +| Average Power Recuperation per 100 km | last-trip | average-recuperation | Number:Power | +| Last Trip Distance | last-trip | distance | Number:Length | +| Distance since Last Charge | last-trip | distance-since-charging | Number:Length | #### Channel Group _Lifetime Statistics_ -Check in your Vehicle Thing Properties if *Statistics* is present in *Services Supported* +Check in your [Vehicle Properties](#Properties) if *Statistics* is present in *Services Supported* These are Read-only values. -| Channel Label | Channel Group ID | Channel ID | Type | Description | -|------------------------------------|------------------|--------------------------|---------------|---------------------------------------------------| -| Average Consumption | lifetime | average-consumption | Number:Power | Average Power Consumption on your Last Trip per 100 km | -| Distance since Last Charge | lifetime | average-recuperation | Number:Power | Average Power Recuperation on your Last Trip per 100 km | -| Cumulated Electric Driven Distance | lifetime | cumulated-driven-distance | Number:Length | Total Distance Driven with Electric Power | -| Longest Distance with one Charge | lifetime | single-longest-distance | Number:Length | Longest Distance Driven with one single Charge | +| Channel Label | Channel Group ID | Channel ID | Type | +|---------------------------------------|------------------|--------------------------|---------------| +| Average Power Consumption per 100 km | lifetime | average-consumption | Number:Power | +| Average Power Recuperation per 100 km | lifetime | average-recuperation | Number:Power | +| Cumulated Electric Driven Distance | lifetime | cumulated-driven-distance | Number:Length | +| Longest Distance with one Charge | lifetime | single-longest-distance | Number:Length | #### Channel Group _Remote Services_ -Check in your Vehicle Thing Properties *Services Activated* which Remote Services are available +Check in your [Vehicle Properties](#Properties) *Services Activated* which Remote Services are available Only one Remote Service can be executed each Time. Parallel execution isn't supported. The *Service Execution State* Channel is reporting the state. @@ -246,7 +247,7 @@ State *Executed* is the final State when Execution is finished. #### Channel Group _Destinations_ -Check in your Vehicle Thing Properties if *LastDestinations* is present in *Services Supported* +Check in your [Vehicle Properties](#Properties) if *LastDestinations* is present in *Services Supported* These are Read-only values. | Channel Label | Channel Group ID | Channel ID | Type | @@ -287,7 +288,7 @@ Please check [TroubleShooting Section](#TroubleShooting) for further advice. ## Further Descriptions -### Range vs. Range Radius +### Range vs Range Radius @@ -295,7 +296,7 @@ You will observe differences in the Vehicle Range and Range Radius values. While Range is indicating the possible distance to be driven on roads the range radius indicates the reachable range on the Map. The right picture shows the distance between Kassel and Frankfurt in Germany. -While the Air-line Distance is ~ 145 Kilometer the Route Distance is ~ 192 Kilometer. +While the Air-line Distance is ~145 Kilometer the Route Distance is ~192 Kilometer. So Range value is the normal remaining range. See the Section [OpenStreetMap](#openstreetMap-widget) how the Range Radius is used to indicate the reachable Range on Map. Please note this is just an indicator and the effective range, especially for Electric Vehicles, depends on many factors like driving style and electric consumers @@ -303,7 +304,7 @@ Please note this is just an indicator and the effective range, especially for El ### Last Status Update Timestamp There's a timestamp showing the last update of your Vehicle. If this isn't shown correctly please check the date settings. -In case of Raspberry Pi execute _raspi-cinfig_, select _Localization Options_, the _Change Time Zone_ +In case of Raspberry Pi execute _raspi-config_, select _Localization Options_, the _Change Time Zone_ Select your _Geaographical Area_ and afterwards the correct City. One restart of openHAB service with _systemctl restart openhab2_ is necessary in order to see the corrected Time Settings. @@ -614,6 +615,7 @@ The Range Radius is needed in Meters so a small conversion is needed. The rules file is performing the calculations on startup and if the values are changing. If the location of the Vehicle changes it will be shown in the Map +#### Additional Items ``` // Range Radius Items @@ -627,6 +629,8 @@ String i3Dest2LatLon "Second Last Destination" String i3Dest3LatLon "Third Last Destination" ``` +#### Rules + ``` // Hybrid and Electric Range Radius plus Vehicle Coordinates rule "LocationRangeChange" @@ -679,20 +683,17 @@ end ### Status Image - - - - - - - +Status ok, Location is Away from Home +Doors not locked, Car can be opened +CheckControl activate. Check Car Dashboard. +Charging This Rule is aimed to improve the visibility of the Vehicle Status. Therefore the Image is used to reflect _an overall status_ which can be identified at the first glance. As an example the Rule is reflecting the following status as Image * Side - Vehicle is charging -* Driver Door - Doors are not locked +* Driver Door - Doors are not locked => execute [Remote Service](#channel-group-remote-services) *Lock* * Dashboard - Check Control Message is available * Front - Vehicle is at the _Home_ Location * Rear - Vehicle is away from _Home_ Location @@ -721,7 +722,7 @@ rule "Image Status" val latitudeNumber = i3Latitude.state as Number val longitudeNumber = i3Longitude.state as Number // Home Location Range - if((50.55 < latitudeNumber.floatValue) && ( latitudeNumber.floatValue < 50.56) && (8.49 < longitudeNumber.floatValue) && (longitudeNumber.floatValue < 8.50) ) { + if((1.23 < latitudeNumber.floatValue) && ( latitudeNumber.floatValue < 1.24) && (3.21 < longitudeNumber.floatValue) && (longitudeNumber.floatValue < 3.22) ) { logInfo("Vehicle Image","Home Location") i3ImageViewport.sendCommand("FRONT") } else { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/doc/properties.png b/bundles/org.openhab.binding.bmwconnecteddrive/doc/properties.png index b2cc9998c3e4da609d2ca7b667c5bf4eccd0d126..04dfb6e8d2cea4c12c1f8d8efa74f519a6e1d382 100644 GIT binary patch literal 49353 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 l = ConnectedDriveHandlerFactory.getHandlerRegistry(); - logger.debug("Handler regsitry has {} entries", l.size()); l.forEach(handler -> { Thing vehicleThing = handler.getThing(); Configuration c = vehicleThing.getConfiguration(); if (c.containsKey("vin")) { String thingVIN = c.get("vin").toString(); - logger.debug("Found VIN {} ", thingVIN); if (vehicle.vin.equals(thingVIN)) { vehicleThing.setProperties(properties); - logger.debug("Vehicle {} updated", thingVIN); foundVehicle.set(true); } } @@ -136,13 +133,13 @@ public void onResponse(VehiclesContainer container) { if (!foundVehicle.get()) { // Properties needed for functional THing properties.put("vin", vehicle.vin); - properties.put("refreshInterval", Integer.toString(5)); + properties.put("refreshInterval", + Integer.toString(ConnectedDriveConstants.DEFAULT_REFRESH_INTERVAL)); properties.put("units", ConnectedDriveConstants.UNITS_AUTODETECT); properties.put("imageSize", Integer.toString(ConnectedDriveConstants.DEFAULT_IMAGE_SIZE)); properties.put("imageViewport", ConnectedDriveConstants.DEFAULT_IMAGE_VIEWPORT); String vehicleLabel = vehicle.brand + " " + vehicle.model; - logger.debug("Thing {} discovered", vehicleLabel); Map convertedProperties = new HashMap(properties); thingDiscovered(DiscoveryResultBuilder.create(uid).withBridge(bridgeUID) .withRepresentationProperty("vin").withLabel(vehicleLabel) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java index c23398eab3a18..5f081349a2c9f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java @@ -18,8 +18,8 @@ * @author Bernd Weymann - Initial contribution */ public class Position { - public float lat;// ": 50.55605, - public float lon;// ": 8.495669, + public float lat;// ": 46.55605, + public float lon;// ": 10.495669, public int heading;// ": 219, public String status;// ": "OK" diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java index d7b22d44ece8d..3b63468ba475f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java @@ -142,6 +142,13 @@ public String getUpdateTime() { } } + /** + * Check for certain Windows or Doors DTO object the "Closed" Status + * INVALID values will be ignored + * + * @param dto + * @return Closed if all "Closed", "Open" otherwise + */ public static String checkClosed(Object dto) { boolean validDoorFound = false; for (Field field : dto.getClass().getDeclaredFields()) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index 548e1f32e1f7b..2b5691b20aee7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -55,11 +55,10 @@ @NonNullByDefault public class ConnectedDriveProxy { private final Logger logger = LoggerFactory.getLogger(ConnectedDriveProxy.class); - private static final int TIMEOUT_SEC = 10; + private final Token token = new Token(); private HttpClient httpClient; private String authUri; private ConnectedDriveConfiguration configuration; - private Token token = new Token(); // Connected Drive APIs // Base URL without VIN @@ -80,7 +79,7 @@ public ConnectedDriveProxy(HttpClientFactory httpClientFactory, ConnectedDriveCo httpClient = httpClientFactory.getCommonHttpClient(); configuration = config; // generate URI for Authorization - // https://customer.bmwgroup.com/one/app/oauth.js + // see https://customer.bmwgroup.com/one/app/oauth.js StringBuffer uri = new StringBuffer(); uri.append("https://customer.bmwgroup.com"); if (BimmerConstants.SERVER_NORTH_AMERICA.equals(configuration.region)) { @@ -93,36 +92,34 @@ public ConnectedDriveProxy(HttpClientFactory httpClientFactory, ConnectedDriveCo } public synchronized void request(String url, Optional> params, ResponseCallback callback) { - if (tokenUpdate()) { - final StringBuffer completeUrl = new StringBuffer(url); - if (params.isPresent()) { - String urlEncodedData = UrlEncoded.encode(params.get(), Charset.defaultCharset(), false); - completeUrl.append("?").append(urlEncodedData); - } - Request req = httpClient.newRequest(completeUrl.toString()); - req.header(HttpHeader.CONNECTION, KEEP_ALIVE); - req.header(HttpHeader.AUTHORIZATION, token.getBearerToken()); - req.timeout(TIMEOUT_SEC, TimeUnit.SECONDS).send(new BufferingResponseListener() { - @NonNullByDefault({}) - @Override - public void onComplete(org.eclipse.jetty.client.api.Result result) { - if (result.getResponse().getStatus() != 200) { - NetworkError error = new NetworkError(); - error.url = completeUrl.toString(); - error.status = result.getResponse().getStatus(); - error.reason = result.getResponse().getReason(); - logger.warn("{}", error.toString()); - callback.onError(error); + final StringBuffer completeUrl = new StringBuffer(url); + if (params.isPresent()) { + String urlEncodedData = UrlEncoded.encode(params.get(), Charset.defaultCharset(), false); + completeUrl.append("?").append(urlEncodedData); + } + Request req = httpClient.newRequest(completeUrl.toString()); + req.header(HttpHeader.CONNECTION, KEEP_ALIVE); + req.header(HttpHeader.AUTHORIZATION, getToken().getBearerToken()); + req.timeout(HTTP_TIMEOUT_SEC, TimeUnit.SECONDS).send(new BufferingResponseListener() { + @NonNullByDefault({}) + @Override + public void onComplete(org.eclipse.jetty.client.api.Result result) { + if (result.getResponse().getStatus() != 200) { + NetworkError error = new NetworkError(); + error.url = completeUrl.toString(); + error.status = result.getResponse().getStatus(); + error.reason = result.getResponse().getReason(); + logger.warn("{}", error.toString()); + callback.onError(error); + } else { + if (callback instanceof StringResponseCallback) { + ((StringResponseCallback) callback).onResponse(Optional.of(getContentAsString())); } else { - if (callback instanceof StringResponseCallback) { - ((StringResponseCallback) callback).onResponse(Optional.of(getContentAsString())); - } else { - ((ByteResponseCallback) callback).onResponse(Optional.of(getContent())); - } + ((ByteResponseCallback) callback).onResponse(Optional.of(getContent())); } } - }); - } + } + }); } public void requestVehicles(StringResponseCallback callback) { @@ -181,20 +178,16 @@ RemoteServiceHandler getRemoteServiceHandler(VehicleHandler vehicleHandler) { // Token handling - public synchronized boolean tokenUpdate() { - if (token.isExpired() || !token.isValid()) { - token = getToken(); - if (token.isExpired() || !token.isValid()) { - logger.warn("Token update failed!"); - return false; - } - } - return true; - } - + /** + * Gets new token if old one is expired or invalid. In case of error the token remains. + * So if token refresh fails the corresponding requests will also fail and update the + * Thing status accordingly. + * + * @return token + */ public Token getToken() { if (token.isExpired() || !token.isValid()) { - token = getNewToken(); + updateToken(); } return token; } @@ -204,7 +197,7 @@ public Token getToken() { * * @return */ - public synchronized Token getNewToken() { + private synchronized void updateToken() { httpClient.setFollowRedirects(false); Request req = httpClient.POST(authUri); @@ -225,22 +218,22 @@ public synchronized Token getNewToken() { req.header(CONTENT_LENGTH, Integer.toString(urlEncodedData.length())); req.content(new StringContentProvider(urlEncodedData)); try { - ContentResponse contentResponse = req.timeout(TIMEOUT_SEC, TimeUnit.SECONDS).send(); - HttpFields fields = contentResponse.getHeaders(); - HttpField field = fields.getField(HttpHeader.LOCATION); - httpClient.setFollowRedirects(true); - return getTokenFromUrl(field.getValue()); + ContentResponse contentResponse = req.timeout(HTTP_TIMEOUT_SEC, TimeUnit.SECONDS).send(); + // Status needs to be 302 - Response is stored in Header + if (contentResponse.getStatus() == 302) { + HttpFields fields = contentResponse.getHeaders(); + HttpField field = fields.getField(HttpHeader.LOCATION); + tokenFromUrl(field.getValue()); + } } catch (InterruptedException | ExecutionException | TimeoutException e) { logger.warn("Auth Exception: {}", e.getMessage()); } httpClient.setFollowRedirects(true); - return new Token(); } - public Token getTokenFromUrl(String encodedUrl) { + void tokenFromUrl(String encodedUrl) { MultiMap tokenMap = new MultiMap(); UrlEncoded.decodeTo(encodedUrl, tokenMap, StandardCharsets.US_ASCII); - final Token token = new Token(); tokenMap.forEach((key, value) -> { if (value.size() > 0) { String val = value.get(0); @@ -253,6 +246,5 @@ public Token getTokenFromUrl(String encodedUrl) { } } }); - return token; } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java index edae9c2db9980..0e5ff49636f0b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -47,9 +47,10 @@ public class RemoteServiceHandler { private final Logger logger = LoggerFactory.getLogger(RemoteServiceHandler.class); // after 60 retries the state update will give up + private static final String SERVICE_TYPE = "serviceType"; + private static final int GIVEUP_COUNTER = 12; + private static final int STATE_UPDATE_SEC = 5; private int counter = 0; - private final int giveUpCounter = 120; - private static final int TIMEOUT_SEC = 10; public enum ExecutionState { READY("READY"), @@ -121,32 +122,27 @@ boolean execute(RemoteService service) { } serviceExecuting = Optional.of(service.toString()); } - if (proxy.tokenUpdate()) { - MultiMap dataMap = new MultiMap(); - dataMap.add("serviceType", service.toString()); - String urlEncodedData = UrlEncoded.encode(dataMap, Charset.defaultCharset(), false); - - Request req = httpClient.POST(serviceExecutionAPI); - req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); - req.header("Content-Length", urlEncodedData.length() + ""); - req.header(HttpHeader.AUTHORIZATION, proxy.getToken().getBearerToken()); - req.content(new StringContentProvider(urlEncodedData)); - - try { - ContentResponse contentResponse = req.timeout(TIMEOUT_SEC, TimeUnit.SECONDS).send(); - if (contentResponse.getStatus() != 200) { - reset(); - return false; - } else { - handler.getScheduler().schedule(this::getState, 1, TimeUnit.SECONDS); - return true; - } - } catch (InterruptedException | TimeoutException | ExecutionException e) { - logger.warn("Execute Service Exception {}", e.getMessage()); + MultiMap dataMap = new MultiMap(); + dataMap.add(SERVICE_TYPE, service.toString()); + String urlEncodedData = UrlEncoded.encode(dataMap, Charset.defaultCharset(), false); + + Request req = httpClient.POST(serviceExecutionAPI); + req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); + req.header(CONTENT_LENGTH, Integer.toString(urlEncodedData.length())); + req.header(HttpHeader.AUTHORIZATION, proxy.getToken().getBearerToken()); + req.content(new StringContentProvider(urlEncodedData)); + + try { + ContentResponse contentResponse = req.timeout(HTTP_TIMEOUT_SEC, TimeUnit.SECONDS).send(); + if (contentResponse.getStatus() != 200) { reset(); return false; + } else { + handler.getScheduler().schedule(this::getState, 1, TimeUnit.SECONDS); + return true; } - } else { + } catch (InterruptedException | TimeoutException | ExecutionException e) { + logger.warn("Execute Service Exception {}", e.getMessage()); reset(); return false; } @@ -157,8 +153,8 @@ public void getState() { logger.warn("No Service executed to get state"); return; } - if (counter >= giveUpCounter) { - logger.warn("Giving up updating state for {} after {} times", serviceExecuting, giveUpCounter); + if (counter >= GIVEUP_COUNTER) { + logger.warn("Giving up updating state for {} after {} times", serviceExecuting, GIVEUP_COUNTER); reset(); // immediately refresh data handler.getData(); @@ -166,10 +162,11 @@ public void getState() { counter++; Request req = httpClient.newRequest(serviceExecutionStateAPI + serviceExecuting.get()); req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); + req.header(HttpHeader.TRANSFER_ENCODING, CHUNKED); req.header(HttpHeader.AUTHORIZATION, proxy.getToken().getBearerToken()); try { - ContentResponse contentResponse = req.timeout(TIMEOUT_SEC, TimeUnit.SECONDS).send(); + ContentResponse contentResponse = req.timeout(HTTP_TIMEOUT_SEC, TimeUnit.SECONDS).send(); if (contentResponse.getStatus() == 200) { String state = contentResponse.getContentAsString(); ExecutionStatusContainer esc = Converter.getGson().fromJson(state, ExecutionStatusContainer.class); @@ -177,7 +174,7 @@ public void getState() { handler.updateRemoteExecutionStatus(serviceExecuting.get(), execStatus.status); if (!ExecutionState.EXECUTED.toString().equals(execStatus.status)) { - handler.getScheduler().schedule(this::getState, 5, TimeUnit.SECONDS); + handler.getScheduler().schedule(this::getState, STATE_UPDATE_SEC, TimeUnit.SECONDS); } else { reset(); // immediately refresh data @@ -186,6 +183,7 @@ public void getState() { } } catch (InterruptedException | TimeoutException | ExecutionException e) { logger.warn("Execute Service Exception {}", e.getMessage()); + handler.updateRemoteExecutionStatus(serviceExecuting.get(), e.getMessage()); reset(); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index f390aa615c1d4..948450049f490 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -176,9 +176,11 @@ public void handleCommand(ChannelUID channelUID, Command command) { if (channelUID.getIdWithoutGroup().equals(IMAGE_VIEWPORT)) { String newViewport = command.toString(); synchronized (imageProperties) { - imageProperties = new ImageProperties(newViewport, imageProperties.size); - imageCache = Optional.empty(); - proxy.get().requestImage(configuration.get(), imageProperties, imageCallback); + if (!imageProperties.viewport.equals(newViewport)) { + imageProperties = new ImageProperties(newViewport, imageProperties.size); + imageCache = Optional.empty(); + proxy.get().requestImage(configuration.get(), imageProperties, imageCallback); + } } updateState(imageViewportChannel, StringType.valueOf(newViewport)); } @@ -188,9 +190,11 @@ public void handleCommand(ChannelUID channelUID, Command command) { int newImageSize = ((DecimalType) command).intValue(); if (channelUID.getIdWithoutGroup().equals(IMAGE_SIZE)) { synchronized (imageProperties) { - imageProperties = new ImageProperties(imageProperties.viewport, newImageSize); - imageCache = Optional.empty(); - proxy.get().requestImage(configuration.get(), imageProperties, imageCallback); + if (imageProperties.size != newImageSize) { + imageProperties = new ImageProperties(imageProperties.viewport, newImageSize); + imageCache = Optional.empty(); + proxy.get().requestImage(configuration.get(), imageProperties, imageCallback); + } } } updateState(imageSizeChannel, new DecimalType(newImageSize)); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/HTTPConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/HTTPConstants.java index ba0496ad55ead..0b6b9280e084a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/HTTPConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/HTTPConstants.java @@ -21,6 +21,8 @@ */ @NonNullByDefault public class HTTPConstants { + public static final int HTTP_TIMEOUT_SEC = 10; + public static final String CONTENT_TYPE_URL_ENCODED = "application/x-www-form-urlencoded"; public static final String CONTENT_TYPE_JSON = "application/json"; public static final String KEEP_ALIVE = "Keep-Alive"; @@ -37,4 +39,5 @@ public class HTTPConstants { public static final String ACCESS_TOKEN = "access_token"; public static final String TOKEN_TYPE = "token_type"; public static final String EXPIRES_IN = "expires_in"; + public static final String CHUNKED = "chunked"; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ImageProperties.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ImageProperties.java index 8028ad09ca73e..2471efe61571d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ImageProperties.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ImageProperties.java @@ -34,10 +34,6 @@ public ImageProperties(String viewport, int size) { public ImageProperties() { } - public boolean isSame(String viewport, int size) { - return this.viewport.equals(viewport) && this.size == size; - } - public void failed() { failCounter++; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_be.properties b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_de.properties similarity index 90% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_be.properties rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_de.properties index 0eda6e90a9427..5626cb0ad3c26 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_be.properties +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_de.properties @@ -3,14 +3,14 @@ binding.bmwconnecteddrive.name = BMW ConnectedDrive binding.bmwconnecteddrive.description = Zeigt die Fahrzeugdaten über das BMW ConnectedDrive Portal # bridge types -bridge-type.bmwconnecteddrive.account.label = BMW ConnectedDrive Benutzerkonto -bridge-type.bmwconnecteddrive.account.description = Zugriff auf das BMW ConnectedDrive Portal für einen Benutzer -bridge-type.config.bmwconnecteddrive.account.userName = Benutzername für das ConnectedDrive Portal -bridge-type.config.bmwconnecteddrive.account.password = Passwort für das ConnectedDrive Portal -bridge-type.config.bmwconnecteddrive.account.region = Auswahl Ihrer Region zur Verbindung mit dem korrekten BMW Server -bridge-type.config.bmwconnecteddrive.account.region.option.NORTH_AMERICA = Nordamerika -bridge-type.config.bmwconnecteddrive.account.region.option.CHINA = China -bridge-type.config.bmwconnecteddrive.account.region.option.ROW = Rest der Welt +thing-type.bmwconnecteddrive.account.label = BMW ConnectedDrive Benutzerkonto +thing-type.bmwconnecteddrive.account.description = Zugriff auf das BMW ConnectedDrive Portal für einen Benutzer +thing-type.config.bmwconnecteddrive.account.userName = Benutzername für das ConnectedDrive Portal +thing-type.config.bmwconnecteddrive.account.password = Passwort für das ConnectedDrive Portal +thing-type.config.bmwconnecteddrive.account.region = Auswahl Ihrer Region zur Verbindung mit dem korrekten BMW Server +thing-type.config.bmwconnecteddrive.account.region.option.NORTH_AMERICA = Nordamerika +thing-type.config.bmwconnecteddrive.account.region.option.CHINA = China +thing-type.config.bmwconnecteddrive.account.region.option.ROW = Rest der Welt # thing types thing-type.bmwconnecteddrive.BEV_REX.label = BMW Elektrofahrzeug mit REX @@ -85,8 +85,7 @@ thing-type.config.bmwconnecteddrive.CONV.refreshInterval.description = Rate der thing-type.config.bmwconnecteddrive.CONV.units.label = Einheiten thing-type.config.bmwconnecteddrive.CONV.units.description = Automatische oder direkte Auswahl der Einheiten thing-type.config.bmwconnecteddrive.CONV.units.option.AUTODETECT = Automatische Auswahl -thing-type.config.bmwconnecteddrive.CON -V.units.option.IMPERIAL = Angloamerikanisches System +thing-type.config.bmwconnecteddrive.CONV.units.option.IMPERIAL = Angloamerikanisches System thing-type.config.bmwconnecteddrive.CONV.units.option.METRIC = Metrisches System thing-type.config.bmwconnecteddrive.CONV.imageSize.label = Bildgröße thing-type.config.bmwconnecteddrive.CONV.imageSize.description = Bildgröße des Fahrzeugs für Länge und Breite @@ -117,6 +116,8 @@ channel-group-type.bmwconnecteddrive.remote-services.label = Fahrzeug Fernsteuer channel-group-type.bmwconnecteddrive.remote-services.description = Fernsteuerung des Fahrzeugs über den BMW Server wie Türen schließen / öffnen, Klimasteuerung und mehr channel-group-type.bmwconnecteddrive.vehicle-status.label = Fahrzeug Zustand channel-group-type.bmwconnecteddrive.vehicle-status.description = Zustand des Fahrzeugs über Türen, Fenster, abgeschlossen, anstehende Wartung und aktive Warnungen +channel-group-type.bmwconnecteddrive.ev-vehicle-status.label = Fahrzeug Zustand +channel-group-type.bmwconnecteddrive.ev-vehicle-status.description = Zustand des Fahrzeugs über Türen, Fenster, abgeschlossen, anstehende Wartung und aktive Warnungen channel-group-type.bmwconnecteddrive.location-values.label = Fahrzeug Standort channel-group-type.bmwconnecteddrive.location-values.description = Koordinaten und Ausrichtung des Fahrzeugs channel-group-type.bmwconnecteddrive.destination-values.label = Ziele @@ -169,17 +170,14 @@ channel-type.bmwconnecteddrive.name-3-channel.label = Drittletztes Ziel channel-type.bmwconnecteddrive.lat-3-channel.label = Drittletztes Ziel Breitengrad channel-type.bmwconnecteddrive.lon-3-channel.label = Drittletztes Ziel Längengrad -channel-type.bmwconnecteddrive.longitude-channel.label = Fahrzeug Standort Längengrad -channel-type.bmwconnecteddrive.latitude-channel.label = Fahrzeug Standort Breitengrad -channel-type.bmwconnecteddrive.heading-channel.label = Fahrzeug Ausrichtung +channel-type.bmwconnecteddrive.longitude-channel.label = Längengrad +channel-type.bmwconnecteddrive.latitude-channel.label = Breitengrad +channel-type.bmwconnecteddrive.heading-channel.label = Ausrichtung channel-type.bmwconnecteddrive.distance-channel.label = Distanz der letzten Fahr channel-type.bmwconnecteddrive.distance-since-charging-channel.label = Distanz seit letzter Ladung -channel-type.bmwconnecteddrive.average-consumption-channel.label = kw/h Verbrauch über 100 km der letzten Fahrt -channel-type.bmwconnecteddrive.average-recuperation-channel.label = kw/h Rekuperation über 100 km der letzten Fahrt - -channel-type.bmwconnecteddrive.average-consumption-channel".label = kw/h Verbrauch über 100 km während der Gesamtlaufzeit -channel-type.bmwconnecteddrive.average-recuperation-channel.label = kw/h Rekuperation über 100 km während der Gesamtlaufzeit +channel-type.bmwconnecteddrive.average-consumption-channel.label = kw/h Verbrauch über 100 km +channel-type.bmwconnecteddrive.average-recuperation-channel.label = kw/h Rekuperation über 100 km channel-type.bmwconnecteddrive.cumulated-driven-distance-channel.label = Elektrisch gefahrene Distanz channel-type.bmwconnecteddrive.single-longest-distance-channel.label = Längste Fahrt mit einer Ladung diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-groups.xml index 11f659525b53c..837a8004d0544 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/charge-channel-groups.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - Charge Status and Charge Profiles of Vehicle + Charge Profiles of Vehicle diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-channel-types.xml index 969e75230bd8d..90b4092f31b51 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-channel-types.xml @@ -13,10 +13,10 @@ Number:Energy - + Number:Energy - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-channel-types.xml index 95d1458ae4cd8..84144a642b12d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-channel-types.xml @@ -5,11 +5,11 @@ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> Number:Energy - + Number:Energy - + Number:Length diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml index 3f8ad1b87524e..32c7838a9b8df 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml @@ -13,6 +13,6 @@ Number - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/loction-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/loction-channel-types.xml index f91bffe1d11ab..bac8b5441d712 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/loction-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/loction-channel-types.xml @@ -3,16 +3,16 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - + Number - + - + Number - + Number:Angle - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml index e7dc148223282..dede3c66e1630 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/range-channel-types.xml @@ -29,7 +29,7 @@ Number:Length - + Number:Length diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml index 3dfdb5ff5d98c..5e4c7e2219dca 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml @@ -43,10 +43,12 @@ + AUTODETECT Vehicle Image size for width and length + 1024 @@ -58,6 +60,7 @@ + FRONT diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml index a39d35606ebac..5994336075d93 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml @@ -43,10 +43,12 @@ + AUTODETECT Vehicle Image size for width and length + 1024 @@ -58,6 +60,7 @@ + FRONT diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml index b9de7d8c3e532..694995c4e4538 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml @@ -40,10 +40,12 @@ + AUTODETECT Vehicle Image size for width and length + 1024 @@ -55,6 +57,7 @@ + FRONT diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml index d207379963e70..f731b24a966a3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml @@ -41,10 +41,12 @@ + AUTODETECT Vehicle Image size for width and length + 1024 @@ -56,6 +58,7 @@ + FRONT diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml index 74bf579b6bc94..aee77d20f5c74 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/troubleshoot-channel-types.xml @@ -5,6 +5,6 @@ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> Switch - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml index 5c8e1f57336ee..39898db2f4a81 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml @@ -37,6 +37,6 @@ DateTime - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java index e2c65fb77b2b4..2b23b3730de0c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java @@ -39,7 +39,8 @@ public void testTokenDecoding() { HttpClientFactory hcf = mock(HttpClientFactory.class); when(hcf.getCommonHttpClient()).thenReturn(mock(HttpClient.class)); ConnectedDriveProxy dcp = new ConnectedDriveProxy(hcf, mock(ConnectedDriveConfiguration.class)); - Token t = dcp.getTokenFromUrl(headerValue); + dcp.tokenFromUrl(headerValue); + Token t = dcp.getToken(); assertEquals("Token", "Bearer SfXKgkEXeeFJkVqdD4XMmfUU224MRuyh", t.getBearerToken()); } } From cc86095dd3acc2b4e9192404df116614ee044cbc Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 15 Sep 2020 14:50:58 +0200 Subject: [PATCH 030/176] http request optimization Signed-off-by: Bernd (cherry picked from commit 054099758657c5fbd97998215a601699e22ebb5d) Signed-off-by: Bernd --- .../README.md | 57 ++++++----- .../internal/dto/NetworkError.java | 3 +- .../internal/handler/ConnectedDriveProxy.java | 55 +++++++---- .../handler/RemoteServiceHandler.java | 94 +++++++------------ .../internal/handler/VehicleHandler.java | 25 ----- .../internal/utils/Constants.java | 1 + .../internal/util/LocaleTest.java | 21 +++++ 7 files changed, 128 insertions(+), 128 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index c404003da4222..c33aba6258d00 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -2,20 +2,21 @@ -The Binding connects your Vehicles listed in BMWs ConnectedDrive Portal with openHAB. -Due to the high range of Vehicles BMW provides you need to check which Channels are applicable. -The Discovery Service recognizes your Vehicle with the correct type +The Binding provides a Connection between [BMWs ConnectedDrive Portal](https://www.bmw-connecteddrive.com/country-region-select/country-region-selection.html) and openHAB. +All Vehicles connected to an Account will be detected by the Discovery with the correct type * Conventional Fuel Vehicle * Plugin-Hybrid Electrical Vehicle * Battery Electric Vehicle with Range Extender * Battery Electric Vehicle -In addition Properties are attached to the Vehicle Thing to observe the Supported & Activated Services. -Different Channel Groups are available so you are able to cross-check which group is supported by your Vehicle. +In addition Properties are attached with Informations and Services. +The provided data depends on a) the [Type](#Thnigs) and b) the Services mentioned in [Properties](#properties) +Different Channel Groups are clustering all informations. +Check for each Group if it's supported for this Vehicle. -Please note **this isn't a _real-time_ Binding**. -If you open the Door the state isn't transmitted immediately and shown in your GUI. +Please note **this isn't a real-time Binding**. +If the Door is opened the state isn't transmitted immediately and changed immediately. This isn't a flaw in the Binding itself because the state in BMWs own ConnectedDrive App is also updated with some delay. ## Supported Things @@ -36,30 +37,44 @@ They differ in the supported Channel Groups & Channels. Conventional Fuel Vehicles have no _Charging Profile_, Electric Vehicles don't provide a _Fuel Range_. For Hybrid Vehicles in addition to _Fuel and Electric Range_ the _Hybrid Range_ is shown. -| Name | Thing Type ID | Supported Channel Groups | -|-------------------------------------|---------------|------------------------------------------------------------| -| BMW Electric Vehicle | BEV | status, range, remote, location, destination, image, troubleshoot, charge, last-trip, lifetime | -| BMW Electric Vehicle with REX | BEV_REX | status, range, remote, location, destination, image, troubleshoot, charge, last-trip, lifetime | -| BMW Plug-In-Hybrid Electric Vehicle | PHEV | status, range, remote, location, destination, image, troubleshoot, charge | -| BMW Conventional Vehicle | CONV | status, range, remote, location, destination, image, troubleshoot | +| Name | Thing Type ID | Supported Channel Groups | +|-------------------------------------|---------------|--------------------------------------------------------------| +| BMW Electric Vehicle | BEV | status, range, location, charge, image, troubleshoot | +| BMW Electric Vehicle with REX | BEV_REX | status, range, location, charge, image, troubleshoot | +| BMW Plug-In-Hybrid Electric Vehicle | PHEV | status, range, location, charge, image, troubleshoot | +| BMW Conventional Vehicle | CONV | status, range, location, image, troubleshoot | #### Properties -Each Vehicle contains Properties. -They are especially handy to figure out the provided Services. -In the right picture you can see in _Activated Services_ e.g. the _DoorLock_ and _DoorUnlock_ Services are mentioned. -So you're sure that in [Channel Group _Remote Services_](#channel-group-remote-services) you are able to execute these commands. -Also _LastDestinations_ is mentioned in _Supported Services_ so it's valid to connect Channel Group [Last Destinations](#channel-group-destinations) in order to display the last 3 Navigation Destinations. - +For each Vehicle Properties are available. Basically 3 Types of Information are registered as Properties * Informations regarding your Dealer with Address and Phone Number * Which services are available / not available * Vehicle Properties like Color, Model Type, Drive Train and Construction Year +In the right picture you can see in _Activated Services_ e.g. the _DoorLock_ and _DoorUnlock_ Services are mentioned. +So you're sure that in [Channel Group _Remote Services_](#channel-group-remote-services) you are able to execute these commands. +Also _LastDestinations_ is mentioned in _Supported Services_ so it's valid to connect Channel Group [Last Destinations](#channel-group-destinations) in order to display the last 3 Navigation Destinations. + +| Property Key | Property Value | Supported Channel Groups | +|--------------------|---------------------|------------------------------| +| Services Supported | Statistics | last-trip, Lifetime | +| Services Supported | LastDestinations | destinations | +| Services Activated | (list of services) | remote | + +Based on Proper + +| Name | Thing Type ID | Supported Channel Groups | +|-------------------------------------|---------------|--------------------------------------------------------------| +| BMW Electric Vehicle | BEV | status, range, remote, location, charge, image, troubleshoot | +| BMW Electric Vehicle with REX | BEV_REX | status, range, remote, location, charge, image, troubleshoot | +| BMW Plug-In-Hybrid Electric Vehicle | PHEV | status, range, remote, location, charge, image, troubleshoot | +| BMW Conventional Vehicle | CONV | status, range, remote, location, image, troubleshoot | + ## Discovery Auto Discovery is starting after you created the Bridge towards BMW ConnectedDrive. @@ -86,7 +101,7 @@ The region Configuration has 3 different possibilities ### Things -Same Configuration is needed for all Thingds +Same Configuration is needed for all Things | Parameter | Type | Description | |-----------------|---------|---------------------------------------| @@ -569,7 +584,7 @@ rule "CheckControl" System started or Item i3CheckControl changed then - if(i3CheckControl.state.toString != "Ok") { + if(i3CheckControl.state.toString != "Ok" && i3CheckControl.state.toString != "NULL") { sendNotification("YOUR_OPENHAB_CLOUD_EMAIL","BMW i3 Check Control: "+i3CheckControl.state) } end diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/NetworkError.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/NetworkError.java index 778f8ac00b637..8aff2306ef580 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/NetworkError.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/NetworkError.java @@ -24,11 +24,12 @@ public class NetworkError { public String url; public int status; public String reason; + public String params; @Override public String toString() { return new StringBuffer(url).append(Constants.HYPHEN).append(status).append(Constants.HYPHEN).append(reason) - .toString(); + .append(params).toString(); } public String toJson() { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index 2b5691b20aee7..c7fe9f0727453 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -91,14 +91,25 @@ public ConnectedDriveProxy(HttpClientFactory httpClientFactory, ConnectedDriveCo baseUrl = "https://" + getRegionServer() + "/webapi/v1/user/vehicles/"; } - public synchronized void request(String url, Optional> params, ResponseCallback callback) { + private synchronized void call(String url, boolean post, Optional> params, + ResponseCallback callback) { + Request req; final StringBuffer completeUrl = new StringBuffer(url); - if (params.isPresent()) { - String urlEncodedData = UrlEncoded.encode(params.get(), Charset.defaultCharset(), false); - completeUrl.append("?").append(urlEncodedData); + if (post) { + req = httpClient.POST(completeUrl.toString()); + if (params.isPresent()) { + String urlEncodedParameter = UrlEncoded.encode(params.get(), Charset.defaultCharset(), false); + req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); + req.header(CONTENT_LENGTH, Integer.toString(urlEncodedParameter.length())); + req.content(new StringContentProvider(urlEncodedParameter)); + } + } else { + if (params.isPresent()) { + completeUrl.append(Constants.QUESTION) + .append(UrlEncoded.encode(params.get(), Charset.defaultCharset(), false)).toString(); + } + req = httpClient.newRequest(completeUrl.toString()); } - Request req = httpClient.newRequest(completeUrl.toString()); - req.header(HttpHeader.CONNECTION, KEEP_ALIVE); req.header(HttpHeader.AUTHORIZATION, getToken().getBearerToken()); req.timeout(HTTP_TIMEOUT_SEC, TimeUnit.SECONDS).send(new BufferingResponseListener() { @NonNullByDefault({}) @@ -109,7 +120,8 @@ public void onComplete(org.eclipse.jetty.client.api.Result result) { error.url = completeUrl.toString(); error.status = result.getResponse().getStatus(); error.reason = result.getResponse().getReason(); - logger.warn("{}", error.toString()); + error.params = result.getRequest().getParams().toString(); + logger.info("HTTP Error {}", error.toString()); callback.onError(error); } else { if (callback instanceof StringResponseCallback) { @@ -122,37 +134,42 @@ public void onComplete(org.eclipse.jetty.client.api.Result result) { }); } + public void get(String url, Optional> params, ResponseCallback callback) { + call(url, false, params, callback); + } + + public void post(String url, Optional> params, ResponseCallback callback) { + call(url, true, params, callback); + } + public void requestVehicles(StringResponseCallback callback) { - request(baseUrl, Optional.empty(), callback); + get(baseUrl, Optional.empty(), callback); } public void requestVehcileStatus(VehicleConfiguration config, StringResponseCallback callback) { - request(new StringBuffer(baseUrl).append(config.vin).append(vehicleStatusAPI).toString(), Optional.empty(), + get(new StringBuffer(baseUrl).append(config.vin).append(vehicleStatusAPI).toString(), Optional.empty(), callback); } public void requestLastTrip(VehicleConfiguration config, StringResponseCallback callback) { - request(new StringBuffer(baseUrl).append(config.vin).append(lastTripAPI).toString(), Optional.empty(), - callback); + get(new StringBuffer(baseUrl).append(config.vin).append(lastTripAPI).toString(), Optional.empty(), callback); } public void requestAllTrips(VehicleConfiguration config, StringResponseCallback callback) { - request(new StringBuffer(baseUrl).append(config.vin).append(allTripsAPI).toString(), Optional.empty(), - callback); + get(new StringBuffer(baseUrl).append(config.vin).append(allTripsAPI).toString(), Optional.empty(), callback); } public void requestChargingProfile(VehicleConfiguration config, StringResponseCallback callback) { - request(new StringBuffer(baseUrl).append(config.vin).append(chargeAPI).toString(), Optional.empty(), callback); + get(new StringBuffer(baseUrl).append(config.vin).append(chargeAPI).toString(), Optional.empty(), callback); } public void requestDestinations(VehicleConfiguration config, StringResponseCallback callback) { - request(new StringBuffer(baseUrl).append(config.vin).append(destinationAPI).toString(), Optional.empty(), - callback); + get(new StringBuffer(baseUrl).append(config.vin).append(destinationAPI).toString(), Optional.empty(), callback); } public void requestRangeMap(VehicleConfiguration config, Optional> params, StringResponseCallback callback) { - request(new StringBuffer(baseUrl).append(config.vin).append(rangeMapAPI).toString(), params, callback); + get(new StringBuffer(baseUrl).append(config.vin).append(rangeMapAPI).toString(), params, callback); } public void requestImage(VehicleConfiguration config, ImageProperties props, ByteResponseCallback callback) { @@ -161,7 +178,7 @@ public void requestImage(VehicleConfiguration config, ImageProperties props, Byt dataMap.add("width", Integer.toString(props.size)); dataMap.add("height", Integer.toString(props.size)); dataMap.add("view", props.viewport); - request(localImageUrl, Optional.of(dataMap), callback); + get(localImageUrl, Optional.of(dataMap), callback); } private String getRegionServer() { @@ -173,7 +190,7 @@ private String getRegionServer() { } RemoteServiceHandler getRemoteServiceHandler(VehicleHandler vehicleHandler) { - return new RemoteServiceHandler(vehicleHandler, this, httpClient); + return new RemoteServiceHandler(vehicleHandler, this); } // Token handling diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java index 0e5ff49636f0b..c1825d7f92421 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -12,22 +12,12 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.handler; -import static org.openhab.binding.bmwconnecteddrive.internal.utils.HTTPConstants.*; - -import java.nio.charset.Charset; import java.util.Optional; -import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.client.api.Request; -import org.eclipse.jetty.client.util.StringContentProvider; -import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.util.MultiMap; -import org.eclipse.jetty.util.UrlEncoded; +import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; import org.openhab.binding.bmwconnecteddrive.internal.dto.remote.ExecutionStatus; import org.openhab.binding.bmwconnecteddrive.internal.dto.remote.ExecutionStatusContainer; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; @@ -43,7 +33,7 @@ * @author Bernd Weymann - Initial contribution */ @NonNullByDefault -public class RemoteServiceHandler { +public class RemoteServiceHandler implements StringResponseCallback { private final Logger logger = LoggerFactory.getLogger(RemoteServiceHandler.class); // after 60 retries the state update will give up @@ -57,7 +47,8 @@ public enum ExecutionState { INITIATED("INITIATED"), PENDING("PENDING"), DELIVERED("DELIVERED"), - EXECUTED("EXECUTED"); + EXECUTED("EXECUTED"), + ERROR("ERROR"); private final String state; @@ -93,16 +84,14 @@ public String toString() { private ConnectedDriveProxy proxy; private VehicleHandler handler; - private HttpClient httpClient; private Optional serviceExecuting = Optional.empty(); private String serviceExecutionAPI; private String serviceExecutionStateAPI; - public RemoteServiceHandler(VehicleHandler vehicleHandler, ConnectedDriveProxy connectedDriveProxy, HttpClient hc) { + public RemoteServiceHandler(VehicleHandler vehicleHandler, ConnectedDriveProxy connectedDriveProxy) { handler = vehicleHandler; proxy = connectedDriveProxy; - httpClient = hc; if (handler.getConfiguration().isPresent()) { serviceExecutionAPI = proxy.baseUrl + handler.getConfiguration().get().vin + proxy.serviceExecutionAPI; serviceExecutionStateAPI = proxy.baseUrl + handler.getConfiguration().get().vin @@ -124,28 +113,8 @@ boolean execute(RemoteService service) { } MultiMap dataMap = new MultiMap(); dataMap.add(SERVICE_TYPE, service.toString()); - String urlEncodedData = UrlEncoded.encode(dataMap, Charset.defaultCharset(), false); - - Request req = httpClient.POST(serviceExecutionAPI); - req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); - req.header(CONTENT_LENGTH, Integer.toString(urlEncodedData.length())); - req.header(HttpHeader.AUTHORIZATION, proxy.getToken().getBearerToken()); - req.content(new StringContentProvider(urlEncodedData)); - - try { - ContentResponse contentResponse = req.timeout(HTTP_TIMEOUT_SEC, TimeUnit.SECONDS).send(); - if (contentResponse.getStatus() != 200) { - reset(); - return false; - } else { - handler.getScheduler().schedule(this::getState, 1, TimeUnit.SECONDS); - return true; - } - } catch (InterruptedException | TimeoutException | ExecutionException e) { - logger.warn("Execute Service Exception {}", e.getMessage()); - reset(); - return false; - } + proxy.post(serviceExecutionAPI, Optional.of(dataMap), this); + return true; } public void getState() { @@ -160,34 +129,35 @@ public void getState() { handler.getData(); } counter++; - Request req = httpClient.newRequest(serviceExecutionStateAPI + serviceExecuting.get()); - req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_JSON); - req.header(HttpHeader.TRANSFER_ENCODING, CHUNKED); - req.header(HttpHeader.AUTHORIZATION, proxy.getToken().getBearerToken()); - - try { - ContentResponse contentResponse = req.timeout(HTTP_TIMEOUT_SEC, TimeUnit.SECONDS).send(); - if (contentResponse.getStatus() == 200) { - String state = contentResponse.getContentAsString(); - ExecutionStatusContainer esc = Converter.getGson().fromJson(state, ExecutionStatusContainer.class); - ExecutionStatus execStatus = esc.executionStatus; - - handler.updateRemoteExecutionStatus(serviceExecuting.get(), execStatus.status); - if (!ExecutionState.EXECUTED.toString().equals(execStatus.status)) { - handler.getScheduler().schedule(this::getState, STATE_UPDATE_SEC, TimeUnit.SECONDS); - } else { - reset(); - // immediately refresh data - handler.getData(); - } + proxy.get(serviceExecutionStateAPI + serviceExecuting.get(), Optional.empty(), this); + } + + @Override + public void onResponse(Optional result) { + if (result.isPresent()) { + ExecutionStatusContainer esc = Converter.getGson().fromJson(result.get(), ExecutionStatusContainer.class); + ExecutionStatus execStatus = esc.executionStatus; + handler.updateRemoteExecutionStatus(serviceExecuting.get(), execStatus.status); + if (!ExecutionState.EXECUTED.toString().equals(execStatus.status)) { + handler.getScheduler().schedule(this::getState, STATE_UPDATE_SEC, TimeUnit.SECONDS); + } else { + // refresh loop ends - refresh data + reset(); + handler.getData(); } - } catch (InterruptedException | TimeoutException | ExecutionException e) { - logger.warn("Execute Service Exception {}", e.getMessage()); - handler.updateRemoteExecutionStatus(serviceExecuting.get(), e.getMessage()); - reset(); + } else { + // schedule even if no result is present until retries exceeded + handler.getScheduler().schedule(this::getState, STATE_UPDATE_SEC, TimeUnit.SECONDS); } } + @Override + public void onError(NetworkError error) { + handler.updateRemoteExecutionStatus(serviceExecuting.get(), new StringBuffer(ExecutionState.ERROR.toString()) + .append(Constants.SPACE).append(Integer.toString(error.status)).toString()); + reset(); + } + private void reset() { synchronized (this) { serviceExecuting = Optional.empty(); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 948450049f490..1da0d07d05beb 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -14,7 +14,6 @@ import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; -import java.time.LocalDateTime; import java.util.Optional; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -22,7 +21,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.util.MultiMap; import org.eclipse.smarthome.core.library.types.DateTimeType; import org.eclipse.smarthome.core.library.types.DecimalType; import org.eclipse.smarthome.core.library.types.OnOffType; @@ -419,28 +417,6 @@ private boolean isSupported(String service) { } } - private void requestRangeMap(Position p) { - // format_string = '%Y-%m-%dT%H:%M:%S' - // timestamp = datetime.datetime.now().strftime(format_string) - // params = { - // 'deviceTime': timestamp, - // 'dlat': self._vehicle.observer_latitude, - // 'dlon': self._vehicle.observer_longitude, - // } - double diff = Converter.measureDistance(p.lat, p.lon, currentPosition.lat, currentPosition.lon); - if (diff > 1000) { - LocalDateTime ldt = LocalDateTime.now(); - MultiMap dataMap = new MultiMap(); - dataMap.add("deviceTime", ldt.format(Converter.DATE_INPUT_PATTERN)); - dataMap.add("lat", Float.toString(p.lat)); - dataMap.add("lon", Float.toString(p.lon)); - if (configuration.isPresent()) { - proxy.get().requestRangeMap(configuration.get(), Optional.of(dataMap), rangeMapCallback); - } - } - currentPosition = p; - } - public void updateRemoteExecutionStatus(String service, String status) { updateState(remoteStateChannel, StringType .valueOf(Converter.toTitleCase(new StringBuffer(service).append(" ").append(status).toString()))); @@ -783,7 +759,6 @@ public void onResponse(Optional content) { updateState(latitude, new DecimalType(p.lat)); updateState(longitude, new DecimalType(p.lon)); updateState(heading, QuantityType.valueOf(p.heading, SmartHomeUnits.DEGREE_ANGLE)); - requestRangeMap(p); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java index 09619e440c7d8..8ed0887fb5668 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -52,6 +52,7 @@ public class Constants { public static final String PLUS = "+"; public static final String EMPTY = ""; public static final String COMMA = ","; + public static final String QUESTION = "?"; public static final String ANONYMOUS = "ANONYMOUS"; public static final int MILES_TO_FEET_FACTOR = 5280; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java index 1c216afa01ec9..15c79c83f55f6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java @@ -14,11 +14,15 @@ import static org.junit.Assert.*; +import java.nio.charset.Charset; import java.util.Locale; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jetty.util.MultiMap; +import org.eclipse.jetty.util.UrlEncoded; import org.junit.Test; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Position; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; @@ -73,4 +77,21 @@ public void testDistance() { double dist = Converter.measureDistance(lat, lon, lat + distance, lon + distance); assertTrue("Distance below 1 km", dist < 1); } + + @Test + public void testLocation() { + MultiMap dataMap = new MultiMap(); + Position p = new Position(); + p.lat = (float) 50.32; + p.lon = (float) 8.32; + + // LocalDateTime ldt = LocalDateTime.now(); + // dataMap.add("deviceTime", ldt.format(Converter.DATE_INPUT_PATTERN)); + dataMap.add("dlat", Float.toString(p.lat)); + dataMap.add("dlon", Float.toString(p.lon)); + System.out.println("Map " + dataMap); + String urlEncodedParameter = UrlEncoded.encode(dataMap, Charset.defaultCharset(), false); + System.out.println("Encoded " + urlEncodedParameter); + + } } From 7ef14bb5977333f3bdb4a569e735d85ecbcbf601 Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 15 Sep 2020 19:01:16 +0200 Subject: [PATCH 031/176] translation corrections Signed-off-by: Bernd (cherry picked from commit 87a6a74964b14cf9178260a64e397b07981e1095) Signed-off-by: Bernd --- .../README.md | 142 +++++++++--------- .../doc/CarStatusImages.png | Bin 0 -> 471157 bytes .../internal/dto/status/VehicleStatus.java | 4 +- .../internal/handler/ConnectedDriveProxy.java | 27 +++- .../handler/RemoteServiceHandler.java | 4 +- .../internal/handler/VehicleHandler.java | 20 --- .../i18n/bmwconnecteddrive_de.properties | 6 +- .../ESH-INF/thing/bridge-connected-drive.xml | 2 +- .../ESH-INF/thing/ev-range-channel-group.xml | 2 +- .../ESH-INF/thing/image-channel-types.xml | 2 +- .../resources/ESH-INF/thing/thing-bev.xml | 2 +- .../resources/ESH-INF/thing/thing-conv.xml | 2 +- .../internal/util/LocaleTest.java | 21 --- .../resources/api/vehicle/webapi-status.json | 2 +- .../webapi/vehicle-status-charging.json | 2 +- .../test/resources/webapi/vehicle-status.json | 2 +- 16 files changed, 106 insertions(+), 134 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/doc/CarStatusImages.png diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index c33aba6258d00..368974a3fb0dd 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -10,13 +10,17 @@ All Vehicles connected to an Account will be detected by the Discovery with the * Battery Electric Vehicle with Range Extender * Battery Electric Vehicle -In addition Properties are attached with Informations and Services. -The provided data depends on a) the [Type](#Thnigs) and b) the Services mentioned in [Properties](#properties) +In addition Properties are attached with Information and Services provided by this Vehicle. +The provided data depends on + +1. the [Type](#Things) and +2. the Services mentioned in [Properties](#properties) + Different Channel Groups are clustering all informations. Check for each Group if it's supported for this Vehicle. Please note **this isn't a real-time Binding**. -If the Door is opened the state isn't transmitted immediately and changed immediately. +If the Door is opened the state isn't transmitted and changed immediately. This isn't a flaw in the Binding itself because the state in BMWs own ConnectedDrive App is also updated with some delay. ## Supported Things @@ -52,36 +56,30 @@ For Hybrid Vehicles in addition to _Fuel and Electric Range_ the _Hybrid Range_ For each Vehicle Properties are available. Basically 3 Types of Information are registered as Properties -* Informations regarding your Dealer with Address and Phone Number +* Informations regarding r Dealer with Address and Phone Number * Which services are available / not available * Vehicle Properties like Color, Model Type, Drive Train and Construction Year -In the right picture you can see in _Activated Services_ e.g. the _DoorLock_ and _DoorUnlock_ Services are mentioned. -So you're sure that in [Channel Group _Remote Services_](#channel-group-remote-services) you are able to execute these commands. -Also _LastDestinations_ is mentioned in _Supported Services_ so it's valid to connect Channel Group [Last Destinations](#channel-group-destinations) in order to display the last 3 Navigation Destinations. +In the right picture can see in *Services Activated* e.g. the *DoorLock* and *DoorUnlock* Services are mentioned. +This ensures [Channel Group _Remote Services_](#remote-services) is supporting Door lock and Door unlock. + +In *Services Supported* the entry *LastDestination* is mentioned. +So it's valid to connect Channel Group [Last Destinations](#destinations) in order to display the last 3 Navigation Destinations. | Property Key | Property Value | Supported Channel Groups | |--------------------|---------------------|------------------------------| -| Services Supported | Statistics | last-trip, Lifetime | +| Services Supported | Statistics | last-trip, lifetime | | Services Supported | LastDestinations | destinations | -| Services Activated | (list of services) | remote | +| Services Activated | list of services | remote | -Based on Proper - -| Name | Thing Type ID | Supported Channel Groups | -|-------------------------------------|---------------|--------------------------------------------------------------| -| BMW Electric Vehicle | BEV | status, range, remote, location, charge, image, troubleshoot | -| BMW Electric Vehicle with REX | BEV_REX | status, range, remote, location, charge, image, troubleshoot | -| BMW Plug-In-Hybrid Electric Vehicle | PHEV | status, range, remote, location, charge, image, troubleshoot | -| BMW Conventional Vehicle | CONV | status, range, remote, location, image, troubleshoot | ## Discovery -Auto Discovery is starting after you created the Bridge towards BMW ConnectedDrive. -A list of your registered Vehicles is queried and all found Vehicles are added in Inbox. -Unique Identifier is the _Vehicle Identification Number_ (VIN). -If a Thing is already declared in a _*.things configuration_ Discovery won't highlight it again. -But it takes care updating the correct Properties. +Auto Discovery is starting after creation of the Bridge towards BMW ConnectedDrive. +A list of r registered Vehicles is queried and all found Vehicles are added in Inbox. +Unique Identifier is the *Vehicle Identification Number* (VIN). +If a Thing is already declared in a *.things configuration* Discovery won't highlight it again. +Properties will be attached to predefined Vehicles if the VIN is matching. ## Configuration @@ -91,7 +89,7 @@ But it takes care updating the correct Properties. |-----------------|---------|-------------------------------------------------------------------------| | userName | text | BMW Connected Drive Username | | password | text | BMW Connected Drive Password | -| region | text | Select your Region in order to connect to the appropriate BMW Server. | +| region | text | Select Region in order to connect to the appropriate BMW Server. | The region Configuration has 3 different possibilities @@ -99,7 +97,7 @@ The region Configuration has 3 different possibilities * _CHINA_ * _ROW_ for Rest of World -### Things +### Thing Same Configuration is needed for all Things @@ -117,7 +115,7 @@ The units can be configured in 3 ways * _METRIC_ selects directly Kilometers * _IMPERIAL_ selects directly Miles -The imageVieport allows you to show your Vehicle from different angels. +The imageVieport allows to show the Vehicle from different angels. Possible values are * FRONT @@ -130,11 +128,11 @@ Possible values are There are many Channels available for each Vehicle. For better overview they are clustered in different Channel Groups. -The Channel Groups are different for the Vehicle Types, on the build in Sensors of your Vehicle and the activated Services. +The Channel Groups are different for the Vehicle Types, on the build-in Sensors of the Vehicle and the activated Services. ### Bridge Channels -If your Vehicle isn't found in the Discovery force a log of Fingerprint Data which helps to analyze the problem. +If the Vehicle isn't found in the Discovery force a log of Fingerprint Data which helps to analyze the problem. Please check [TroubleShooting Section](#TroubleShooting) for further advice. | Channel Label | Channel ID | Type | Description | @@ -143,9 +141,9 @@ Please check [TroubleShooting Section](#TroubleShooting) for further advice. ### Thing Channel Groups -#### Channel Group _Vehicle Status_ +#### Vehicle Status -Reflects Status of your Vehicle. +Reflects Status of the Vehicle. Available for all Vehicles, Read-only. | Channel Label | Channel Group ID | Channel ID | Type | Description | @@ -162,7 +160,7 @@ Available for all Vehicles, Read-only. See [further details for DateTime](#last-status-update-timestamp) in case of wrong timestamp values -#### Channel Group _Range Data_ +#### Range Data Based on Vehicle Type (Thing Type ID) some Channels are presented or not. Conventional Fuel Vehicles don't provide *Electric Range* and Battery Electric Vehicles don't show *Range Fuel*. @@ -183,7 +181,7 @@ These are Read-only values. See Description [Range vs Range Radius](#range-vs-range-radius) to get more information -#### Channel Group _Charge Profile_ +#### Charge Profile Valid for Electric and Hybrid Vehicles These are Read-only values. @@ -205,7 +203,7 @@ These are Read-only values. | Timer 3: Enabled | charge | timer3-enabled | Switch | -#### Channel Group _Location_ +#### Location Available for all Vehicles. These are Read-only values. @@ -216,9 +214,9 @@ These are Read-only values. | Longitude | location | longitude | Number | | Heading | location | heading | Number:Angle | -#### Channel Group _Last Trip_ +#### Last Trip -Check in your [Vehicle Properties](#Properties) if *Statistics* is present in *Services Supported* +Check [Vehicle Properties](#Properties) if *Statistics* is present in *Services Supported* These are Read-only values. | Channel Label | Channel Group ID | Channel ID | Type | @@ -229,9 +227,9 @@ These are Read-only values. | Distance since Last Charge | last-trip | distance-since-charging | Number:Length | -#### Channel Group _Lifetime Statistics_ +#### Lifetime Statistics -Check in your [Vehicle Properties](#Properties) if *Statistics* is present in *Services Supported* +Check [Vehicle Properties](#Properties) if *Statistics* is present in *Services Supported* These are Read-only values. | Channel Label | Channel Group ID | Channel ID | Type | @@ -242,9 +240,9 @@ These are Read-only values. | Longest Distance with one Charge | lifetime | single-longest-distance | Number:Length | -#### Channel Group _Remote Services_ +#### Remote Services -Check in your [Vehicle Properties](#Properties) *Services Activated* which Remote Services are available +Check [Vehicle Properties](#Properties) *Services Activated* which Remote Services are available Only one Remote Service can be executed each Time. Parallel execution isn't supported. The *Service Execution State* Channel is reporting the state. @@ -260,9 +258,9 @@ State *Executed* is the final State when Execution is finished. | Active Air Conditioning | remote | climate | Switch | | Service Execution State | remote | state | STring | -#### Channel Group _Destinations_ +#### Destinations -Check in your [Vehicle Properties](#Properties) if *LastDestinations* is present in *Services Supported* +Check [Vehicle Properties](#Properties) if *LastDestinations* is present in *Services Supported* These are Read-only values. | Channel Label | Channel Group ID | Channel ID | Type | @@ -278,20 +276,20 @@ These are Read-only values. | Third Last Destination Longitude | destination | lon-3 | Number | -#### Channel Group _Image_ +#### Image Available for all Vehicles. Picture can be modified regarding *Viewport* and *Size*. -See [Things Section](#Things) for Viewport possibilities and [Status Image](#status-image) for possible Use Cases. +See [Things Section](#thing) for Viewport possibilities and [Status Image](#status-image) for possible Use Cases. | Channel Label | Channel Group ID | Channel ID | Type | |-------------------------------|------------------|---------------------|--------| -| Rendered Image of your Vehicle| image | png | Image | +| Rendered Image of the Vehicle | image | png | Image | | Image Viewport | image | view | String | | Image Picture Size | image | size | Number | -#### Channel Group _Troubleshooting_ +#### Troubleshooting Available for all Vehicles! Switch will log a *Vehicle Data Fingerprint* into the openHAB log. @@ -307,33 +305,34 @@ Please check [TroubleShooting Section](#TroubleShooting) for further advice. -You will observe differences in the Vehicle Range and Range Radius values. + will observe differences in the Vehicle Range and Range Radius values. While Range is indicating the possible distance to be driven on roads the range radius indicates the reachable range on the Map. The right picture shows the distance between Kassel and Frankfurt in Germany. While the Air-line Distance is ~145 Kilometer the Route Distance is ~192 Kilometer. So Range value is the normal remaining range. See the Section [OpenStreetMap](#openstreetMap-widget) how the Range Radius is used to indicate the reachable Range on Map. -Please note this is just an indicator and the effective range, especially for Electric Vehicles, depends on many factors like driving style and electric consumers +Please note this is just an indicator and the effective range, especially for Electric Vehicles, +depends on many factors like driving style and electric consumers. ### Last Status Update Timestamp -There's a timestamp showing the last update of your Vehicle. If this isn't shown correctly please check the date settings. -In case of Raspberry Pi execute _raspi-config_, select _Localization Options_, the _Change Time Zone_ -Select your _Geaographical Area_ and afterwards the correct City. -One restart of openHAB service with _systemctl restart openhab2_ is necessary in order to see the corrected Time Settings. +A timestamp is showing the last Vehicle Status update. If this isn't shown correctly please check the date settings. +In case of Raspberry Pi execute *raspi-config*, select *Localization Options*, the *Change Time Zone* +Select r *Geaographical Area* and afterwards the correct City. +One restart of openHAB service with *systemctl restart openhab2* is necessary in order to see the corrected Time Settings. Correct TimeZone is crucial for handling all Time information in openHAB and it's discussed many times in the Forum. See [similar discussion in the openHAB Forum](https://community.openhab.org/t/solved-wrong-local-time-how-to-change/90938) which deals with the same problem. ### TroubleShooting -As stated at the beginning: BMW has a high range of Vehicles supported by BMWs ConnectedDrive. -In case of any issues you face with this Binding please help to resolve it! +BMW has a high range of Vehicles supported by BMWs ConnectedDrive. +In case of any issues with this Binding please help to resolve it! Please perform the following Steps: -* Can you login *[Here](https://www.bmw-connecteddrive.com/country-region-select/country-region-selection.html)* with your Credentials? _Please note this isn't the BMW Customer Portal - it's the ConnectedDrive Portal_ -* Is your Vehicle listed in your Account? _There's a one-to-one dependency from User to Vehicle_ +* Can you login [into ConnectedDrive](https://www.bmw-connecteddrive.com/country-region-select/country-region-selection.html) with your Credentials? _Please note this isn't the BMW Customer Portal - it's the ConnectedDrive Portal_ +* Is the Vehicle listed in your Account? _There's a one-to-one dependency from User to Vehicle_ If the access to the Portal and listing of the Vehicle is checked some debug data is needed in order to identify the issue. The [Example Sitemap](#Sitemap) contains the necessary items to generate Debug Data. @@ -341,15 +340,15 @@ The [Example Sitemap](#Sitemap) contains the necessary items to generate Debug D #### My Vehicle isn't found automatically! The Vehicle isn't recognized or a predefined Vehicle doesn't show the right properties? -For this the *Discovery Fingerprint* is needed. -Short press on the Switch will force some logging entries which can be [normally found in your logs here](http://openhab:9001/) +For this the [Discovery Fingerprint](#bridge-channels) is needed. +Short press on the Switch will force some logging entries which can be [normally found in the logs here](http://openhab:9001/) #### My Vehicle shows wrong data or data is missing! -Now the *Vehicle Fingerprint* is needed. +Now the [Vehicle Fingerprint](#troubleshooting) is needed. Proceed like before, shortly press the Switch and the log contains the data. -Personal Data is eliminated from thes log entries so it should be possible to share them in public. +Personal Data is eliminated from the log entries so it should be possible to share them in public. Data like * Dealer Properties @@ -358,8 +357,8 @@ Data like are anonymized. -After you've generated the corresponding Fingerprint please [follow the instructions to raise an Issue](https://community.openhab.org/t/how-to-file-an-issue/68464) and attach the Fingerprint data! -Your feedback is highly appreciated! +After the corresponding Fingerprint is generated please [follow the instructions to raise an Issue](https://community.openhab.org/t/how-to-file-an-issue/68464) and attach the Fingerprint data! +r feedback is highly appreciated! Here an example of Debug Fingerprint Data from a BEV_REX Vehicle @@ -389,12 +388,12 @@ Exchange the 3 configuration parameters in the Things section * YOUR_PASSWORD - with your ConnectedDrive Password Credentials * VEHICLE_VIN - the Vehicle Identification Number -In addition search for all occurences of *i3* and replace it with your Vehilce Identification like *x3* or *535d* and you're ready to go! +In addition search for all occurrences of *i3* and replace it with your Vehicle Identification like *x3* or *535d* and 're ready to go! ### Things ``` -Bridge bmwconnecteddrive:account:user "BMW ConnectedDrive Account" [userName="YOUR_USERNAME",password="YOUR_PASSWORD",region="ROW"] { +Bridge bmwconnecteddrive:account:user "BMW ConnectedDrive Account" [userName="R_USERNAME",password="R_PASSWORD",region="ROW"] { Thing BEV_REX i3 "BMW i3 94h REX" [ vin="VEHICLE_VIN",units="AUTODETECT",imageSize=600,imageViewport="FRONT",refreshInterval=5] } ``` @@ -568,14 +567,14 @@ sitemap BMW label="BMW" { ## Going further -You're now able to receive your Vehicle Data in openHAB. Continue the work and combine this data with other Powerful openHAB Features, Bindings and Widgets. +You're now able to receive the Vehicle Data in openHAB. Continue the work and combine this data with other Powerful openHAB Features, Bindings and Widgets. ### Notification -A quite handy rule if you aren't the _permanent Driver_ of the Car but you're somehow responsible for it for e.g one of your family Members. +A quite handy rule if you aren't the *permanent Driver* of the Car but 're somehow responsible for it e.g for one of your family Members. As soon as a check control message occurs a message notification is sent to the Android App. Below the rule as an example. -just insert your Mail Address which you are using for openHAB Cloud Connector. +Just insert the Mail Address used for openHAB Cloud Connector. ``` // App Notification if Check Control Message is active @@ -615,7 +614,7 @@ end -The [OpenStreetMap Widget](https://community.openhab.org/t/custom-widget-map/39225) can be used to display a Map on your Panel. +The [OpenStreetMap Widget](https://community.openhab.org/t/custom-widget-map/39225) can be used to display a Map on r Panel. It's configurable with *Markers* and *Accuracy Circles* which are quite handy to display several informations. See the HABPanel example with the OpenStreetMap Widget on the right side with @@ -698,20 +697,17 @@ end ### Status Image -Status ok, Location is Away from Home -Doors not locked, Car can be opened -CheckControl activate. Check Car Dashboard. -Charging + This Rule is aimed to improve the visibility of the Vehicle Status. Therefore the Image is used to reflect _an overall status_ which can be identified at the first glance. As an example the Rule is reflecting the following status as Image * Side - Vehicle is charging -* Driver Door - Doors are not locked => execute [Remote Service](#channel-group-remote-services) *Lock* +* Driver Door - Doors are not locked => execute [Remote Service](#remote-services) Lock * Dashboard - Check Control Message is available -* Front - Vehicle is at the _Home_ Location -* Rear - Vehicle is away from _Home_ Location +* Front - Vehicle is at the Home Location +* Rear - Vehicle is away from Home Location ``` // Change Image according to Vehicle Status diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/doc/CarStatusImages.png b/bundles/org.openhab.binding.bmwconnecteddrive/doc/CarStatusImages.png new file mode 100644 index 0000000000000000000000000000000000000000..b198ede53d566bf34194e2313291d5a9c617657d GIT binary patch literal 471157 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

w|JVaB%$0ez{PE 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�>)53On&WmogK;%Vno6ABOs6tbjtSgDt z+ABn#$KoQKFsC|e$(VDYDQAwiyVkx;>iwnI%kblI8qq4-I!=CB#a|`}U21L6s?Ipn_gWi2v35)YHOur}XA&yO zWeOz>OgZB+Od`q3S~!+u@9q^QP*|Vzha|3zm8X)^(m%|1US73=JFAao{!1W_Wa%3M zv=s=Uk5sB}`#oS}>1=(woe=WyJFz70Sd=`d0v9sN5(8b;jwhDspM6@kYNLoh+r8}0 zppp6AbU#BV5*G};jtVxwZ?-s~fqPhP7H@zy%R?{@^>||r>b!yx4S!?f?iJ#0HYd%bkWO*%tz$u@Hfnaz-^Pa4{FS+ zhzdZP0~}^eD60%ipF@t*xNR&ZQmHHvdW=U+cA@9Hs(RbRutuAmE&k(R-vi_qp)PXV zu)`Z9+?er7VYd$j5~)y$4g`Spus0j99|Anu&eyy2&iAuQztm<=oudDfA9SoP`R1OUosO{>s$bca6yk z;oL&mdmgb-B2Bv?Nf;dQg}2<0#Kk3W<6$XtI6b$F7nYoSAx@d@me$rds8O-}^Qs$- z3kwVWOVo{nr=c~==XmQ%XWsMQQpq6MWH+CMoStqNP4CwYNfKFM-oqEDtJIm}OfAUe z#fhB#)7m2Kdi(coGz~HmcigU%G17a1tEV`Gd1h^IxmQjygX`AD zrx#A%St)0M0h1sW;?Lo3>7jkWOC zvNMz8{SBg-`N(HoVv+W@+agM;JLHJx$F;G2%Jmd5h5`pm)_3u_Ewz+BS8 zoF(7Bv!9v_r}G|^G7Oj>dw6M8WX4`Y2v+pli?_AnULDa4E5aSw3u`Pp}|HDGun z3qW4~z`q!Dyj@#!ILUMY;24mdI9GI!a}jSq+VNT2)U*BBWl-*Lm@;+gB$_?i#ou~V zZZ5y?+0lFR`mV^(#;WiN^bq2p4Z=~OM4GdSi-x{Rr}wMJrW+W@6ORMw!T^+d=If~2 z#AB947SgmnF&`T{6qi+wyNy8`L* z-~XN45UeFFe4#P2s=mBC@Jge7yqSnNO($Tl8*K80ppkM0ezAm&(l^=GphMFNc=PC% zj=RiLTEX?}xJj*JvLD4$p+k-PN`bI11q$7YGb?;@8ApV58ACnHCezV78XX^HWTvA7 zMqL>hc4Cv4b^&$?nGpnYEU-}H%8mYm7+>>6SQIP&^oNR5u6x*Y50$!d&wNth!hHL~wzJYJfQmBkdhBerk=F zQ=zOPg-#|iceYlGvgyL}-Fo1zvIAJuj@^U-W*@KTYi42~or=C_yks2Gj7s%^2KJnU z|{Fhh{^=zE$1g$e+#a?HZ`DKm&ZsI zDhk;gceCJ;!LWy+X{vKgEyfpiZDPWE?|LPmMRRS1kBzpvO2(sruGwLj z#NjzE6F=uZw@Y_TZD*PG1FR907685Y*``McLRT+of$=O%9bk1p8?XBj8DVvbW_5a5 zYJZD%2WvQqftW?p2H)$M&)ij#jMfURLuzB~=2$LvkK zXCa{UuRua4$-5AV|DB|+rUE-SH?%Qmnxkx>p}9D<4054H41HYrULQ>+{05YwYPWlG zXCH+RlMdj5kI=`hJPvonMR8G%+#uw=^$!qT=q; zk0L;vdP?IUZv!wM%g5oz!>T_Shmrp)pF<94w-Od&b~C3wuqcAEwe_w8IfMuw*Pw>m{GstKCpT>JY*%qXRlWotw#YCKMu&F zLd3ZNzp}7>T^t926YmQ)cJzvr2Vft9F@n-pFtC^OFyoGBw1Z<0p=z6BXU_3S6E3z? z9E`Nt*72IY=5TVJR@K*(Q#T^F#h32F|8#5wuWOv#tIMY8|Lr1x$l-{L(8Q(Cv}{O# zA}S9HL)093>O;TaJ63j&Cv#)CUJWaQ5kr`RScLzumUoN#W5QqY%hK$_l*7OAv;uD{ zp$6ZcUzQKDeJ`77{oY?@Yz*B!*C5$mE^85hi{|{S(cpQry;1mex3@f<2l@|4ZK(uZV7GdKHOg^}Yl;I?+tlRF zx>d281Ox=o3P4zv-)K8Een2Tx z!1a!c*>Om>A7|jOfYv_hb1Wb(WxKY5H!k~=V%7~iZ)=qrY+uY~LNGpi-<(T9+8^Im zD%+pu86j;Q_OGR#e%FZv8{T`t3k!mc=l2tN&;f>q?sr23*nq^4%j1>_9={gvr9?XTGW^2wj0}<=AM|?a>+2P>*xg1S=v|4=v?O8vTr`c*$J1_| zcZqt*j6@&uVdD$I)ivOMYOMbUMK35t%O@}K3vW%OPPIaEOXs8_ZTO;|4oP__AM`SU z`s7Oq_#_EgxRC>K)ivmfFGA5^)sf1<+%O4|y!*16F*hVUPEMhrf14R{n6KDO5^^Ao`=m2FmHMl4s6`CI`Rm9_T7$)EQLTkj$h{*1^6!0 z5IheIbm2X3qG;TN_}g9bRJ^hgRsEBrXVoA_u1%ZM=1*!FOY)uQ zFxay4^04A!pcy_%)~sx^0^}VsQ{p8&yj>&sz1pVj%*%i7ICl8c7x=m9TdX)!hCjo& zw)_JKC-f}Xk>t@Vy1UcJZP;=H`&0-YsBnK%rF8BaHRCqR-Hk_x83^DwSROnQ^Lfvr%@!JFcJK#Vye<_UrQrKrIZciOCPRn2au_F(@#SfJ8e? z$nYz2hJ-H2H8qm`a|AstCmdlx8&_vZWaFb&;_*6zCbScjS0dg4)a&FUF42$(UriGY z{~n+a;o#sHbx)mtSpVuqnUa{zn#s)Got0pP5P1TS+fWk;<_GgW5CQ+P`B_a(K!w{eI4HEdTuMB(Uf*ZnGs%|R#Q;+ZFW2W%14`0$KXM9BaJWGNa2 z2|WKw>1gWge@F&vwPFEzS+6(Y#2>-FH<{Kp!T`ogH(u1=P%I+q{c^u=qn&5x^4_w& zX>Zuvjetk-qWw5vxJWql{cuHXW7X&EwKCG@s+aFf?G?_{aS2u(Ys%HD#{+p(m5q!b z5`8so7l!=5`@W?sA_yN*x)f}m0%BEOQ5U90g!ThiOL#o|#49*<@U`@mOsf+Mez<48 z7q^7{F=4O`Ux{ob49

ShHGPDskto8?F9LN?X%gLz^2w8KyR-9A#B=jkEbZtQdb+ zmI&VdiEErBDb}mSq3R=kv&nUgz-D>$_Y{E^7+-%pfVhPsb-}G=I z_9FO$aJ?Q22>kyUc$qVU`hbI?<}FHV!{fx|%j5Oh?bjcpU$Vt-FQp(p59^+fhf$Nj z(f|q-;pMWs6};xK#yvDd|6d4IfDS$~Zt=^FYotvIM@r$t!vnxF{0Oo-N{pa@L5WRE zON)(V172KQ@IhRu=sx*Ogy3cO6Y$Mm3vMghANEHkI;+o@78ZoAuOgH>ZdP|#ga;eEE(xZ$l~@3FRgApEvTx)d1<4WMn;v8V*> zSDQB8?%bHi#_H?cyDBBE*?ESfeBlwEF5Fqxkj7}yO2C@+#7#0s@M#$A6j%=T8HQ>U zslNq7H2{t;PE!8n$;hXU!ay(B_3aJX=&LKu@eQYq@lJM3fU|ay0Wy26LI~E}0#-nH}|{LU;C?Veevtl2a;F$<2!BMN7!A)51DCpOe zUsyhUO~vXjur#A?CfTET1jP3g^wyPh_MLf+WUT~TqrkGtO0gKJB9UQ$*ct8d3n;Y= zhQi)By0j8xb99>+O^)P`rXSN=6+{}zHHp+e$`z}v-AMI}vyo=ioO;)$2= zQ`6p^2o;_Fk3bg*+ZU?Y-=uwnwtDLnnpk@rUE%Z|RaC_VPLkr?0WgHAX}iT0n_3oa zT#GYv%L{As3ozdy5bFaGV(6e(eKD9dF&M!v4V-^>N+dkI)-RYZj$(*0sX%+@%cO`O z7-16rC#@18v_htMEDBe!byejG2>}82*CGfZs^n~QU^$CpF|wVHT{rzy8QToTcsb)n46X3jpD=J{wLKiCFxHP_vcwH4J}i2wsdBeWE8<#a^cFd{Hl_S zhQ;J76e*Ap=r0hoIgP{xRgQ9L)kKWjyDT#UB+%w1>)>VpH3Q*+8s~t4S=%T@7t{EL z&4#~fA!nKROWg~BXv-hYu-5TsqmH?cTmb8^NumgT2x~8leZut#!{`qbI+Hn=kN2Hl zTp`(6C-3hb&lm&JaXaG#V9**GCw|A)6dM`@5E)Egfa~{|CA4*Eb(iW)EQB}yRlL@xUZ>*ydjw{`7bKfdi-UoT2 zJFXYNzL4b48#k9>8&A)TYo20b2fm)~BYqdiApFVWh|cHH=gykYtH!shD6)s+bBy;D z{`LF4@?;@yU@+LiG9WytaB@6k{8Zm_JbzM>?QR;C%lLD_P))II>mtc+GI78PgNGXT%&3^qa&6mcK+)3&i4Ql?o(jIrjJsW#$UX*R}SE8|PIK zw$b#;TcAIBR^GIQ_BegM$#)OS`rub%Gz%Lw7?*f~-TFAe6{K#etc;U<%&jl_!7?$g zI@$|qGpUGd^}TOE=%v2W8_EhU584;W2cj$du-?e~v*SGz_`xe1Y|w)K?bL5~JRR5N zm5jX4%ZQ->dkIr}B-bvyHbii1z`1PEt{pXLvxQFzx&8?c9C)y&%|qhdA5!OxN(b zAx7{Sh0OP2JM_Hcl1i!V(zJ2?LTAZcPlb`kFc;7~-^X-_mqV0G@ zuJS2rj-aFYPA4~!prhlWq*7k^y}!E1xBmUSh#&l-x{`>|NYYkmeURzAu<`Ia#`^(b z<9Q77vcJ%IJywab`}Ed`=JNUw3aTV~*_G<#=HeBRv;Ocg1Z1eCb-zRQ{tznsMA3vv z>wLXG2Gk2zS637B*l)Tv-N$>Cm*IS9ho?N4)wj(v#^yUZA4VF>Jv0}I`@&x2~L5*xuUim7<9?5BhqGIyI}X z9(HA-+tnM}{h~b%np6MI(ABX~rg6IVA4%IFP3`ukky2w@?WjOw z8(Vv4E&8#JZra>}XJLgQzXiG_h;xQh8Hy*;S=QK=Go{(jL}1XGl@8RAPi*ttvWyGn zE+kgvt|9uVYk27%A!5I41f?6nJcJ+%_46A86b?Docz>2aUTgy1pO2)Xh%25M7)6y&|KMpUl=F% z?@Igdy>K9OKItGp5A=74-Q&z!WqmtMXFjS)Guc8!zf`UkM9Mbr;OAzj1n)ovkwd$U zj=E8bM2kedZKyZ5bC3nG5v_B`Z>+D6Tj%w)q?J_M-5hT-xy#+puEk|*mNAzxkJ*(~ zD#|N5Vb=?@22ttiuI%#hCLd0A?LHtTf)JhP6{AK9v4N)xrqBA+{OYvc#@x~ufk{q2 z4mR%3(&Y}5G=Yu0QBF&G(+~~kK@e6({WrSIhDD?aK0wcg7Wr_2sJ;3=A?Mwg+DURM-4dCAB^D(Hswn1s#Djp=$_pXg>-)()hk7YsC3=hErI`dMj^!>>_ogKe(N zTWT~?X?I`LF$qOhiMA^VljW&vRyDj0){_sshlnmR$uiLQ?2xM$@$(|(nK!vV8=3VO zg^gSx&3;{%>7$nWmDu^2JbRc%f_#Yt8b>((wRS@2xF2-jU zrt>P*@a^ir@Aky-75m}ndE*V9aGO^6fyIC5a6tG0eNe`~|GqYsD6NY_Bt3xo6&B(x zV72moyUu@5%)Iiw(vmb>2-rDSJqS5whDF|H&&btl78t(D$oCl6Ga zp=774Uf_ju{#MuZ_2ygEfq%sOS_Vta4xM)U7BdejuNRtj5GRd;ALh^Q<|oP$YG4na z!ny_;$J~4=S16scagwAUMzdI@6=OK)hWgTmj zau{i578c-21yq#yqX@r+#Y~KkQ?_~CvseZY*}1tTKmB2%RiEIcWj`4X%h-!=<6&p} z8Kwsx)3FGcRX?fJ>%sjl{#uvwE3A~ZJodJH)5F9l&^4bAqny}4E}M3EMGoGE#K8lW z9vgb{&~yNlovF;LfW2A!O9qttHEc)UyJ6@rwdS2WZl1o;-ym9>voU7Ge7JS&{DKKg z(nZxa?t1;MtyM)6N1l$lbnWFZR{MdlgU>t35$1v&>Rp-!dw(u9YX+ zgy-xj5)J#jh+GJKoIH=(_V97B$`ur-pKP-|xCF4lSjra-3FsAh;-%O!Ir3LU?bd4; zvFPen6i{U{E+q^jCoTx@`ynkME$S`R=v-`q+~{@C+PNV>)hiB5r1uZ&s_^Bc#36$E zY~LsA)eQupi-7yK13`%U0RQ^SesU9n&uyvU*xJEvU*F*1#p>zk@YOUBUcB5|pWbeR zQaDBx%dr=VO^5Sl>BcP!m{Qi)n3`G#8cckzmnqmvIpg7(#ucN-Cn6tdSOWASuKpl+ z#L>;pt9fJ+F|Duyy!w2jBhilaqdTOmwuC_VVnI)L6RcwHCT- zG{)Xo!|U2@`E9{%V)NOU#(91-;t|n}bwn;pg@I>EQ)7{r_YZe_3lm=pZwn_gryoWp z#cn1!mUTs@RRw=}W}tVWKSZB|+x_qv>FlIw4BHOt)9_HTble=D)eX}!ZNUpe0*22l z+7J}=B68Z_UMc3G=-GDJ&DGEJpK{1z=eKVO1u!iyb!@kEY|mVQv2XETd*5*R;_z6? zIT3|SarxTN0j5CR55Wcpys@@Hv0l1I)z#cyU0G0>Ze?l9bx1-$c_xCyf`NXBA}kn* zRKV-}0gvGRBkq}CYSUA=xEnZ+7hgC#8)Mpp?U`WL#hfwZpkzE^E~BBtJO&p98C#w@ zym6d+=uOut{DmIVpooAE#p%l`J<51O#%CF1#IV#sKD2nVVF4T&;)i*hGv|2Jn#xd- za}F#^+@DEF`0$W3em8V<^dv3KrscT^rxOM-BPWxL^wRS3sGXf&TKf&}r|wtas0%lA zzq|!|jihhfXSqR-2;GLo_}f*^+0PBL^E?Z)JO$rRO7})|=XjHjhp$S)r-#Ew68DmG7;;DE@Cu+3HMG9& z@s5@t+xN;{ww&3Olet4${UD8gFY#o)@4$JzuH;7@qvv7W6Id7+IB@bE=GbsEjus&%RSlb{fOfs>CLGsibh1 zTn0);G!4e}N`QUQ@T2@ra&llIb*NF#A`Fv;$QY}5CL7WtosOzdUMxyhjk9xsc$cPY zTwLnI9+zlY& zMeQurWm4G?<6@7;mZ2;o>H2i-AW}H75Su^Tjt4y60t$7eTiqvft3Av^_DtgR?tNUV_vM#F`g#<$AkyqGA@mFI zz2HXXp}F%VP>nFfOiige5cKH6>5}P)5*^!OxqnGaXmCu_t396)TP4_^_N}BLd&vRxTolnA{P5nng7` zY?_e_EMd8ZCg^^4p+H0trMAloN^mXpW>REfwvX+AG?&G3iD3bCvZPXKzV7LV*L1GX zlCrP2nURxT$A{Tv$_QQfZ9JP`44kc0_onK?2GIjO>_H9Pxutn|EQD5KgqG$Cravqb z%o9r35c^87ZCO;z2*O%b-W!(=TQd9;*~d+84h}A1ZeK1=N9P}hvPugox;BRT3Sabv zzsz!S%uWz>Pga8UnUW`B!xp9&6vzIEZWlotti`*tK>Ec$K6L~hW%jgN?&6GZ;x(G& zKhP6P!0|H?7P7zW#>rED`HuZD>pSHxb&2Uyo^5p+AzWLUdvl7_l!Z+Q)HiyiIBH=& z>UH4i*)10pIx!So*wEy1aq7{lO|jmRy%=~-(*U8lJEyJepj=wgS0)@`bX3AVgY#(o z1kNh`%sT(0$IlTT*7j%^Kfj|iKewDm$*}1+`ay+Y%2!^h7lQTi;4D(A@rZw}9qQdG zdh7O6BrizZ*ajA5%G=0J{h4f7Qhggt@x?Yh68S8s8zk ziK*;Df){}rSM+W6=aam=eA^x~_;Gom;|}Bf0t2{ax`9`lx}{A7SSri(y^iZ`_z_U9 zufbj`E518CzNR)dD7r7GpEj9q8T(f)KXV=GQXm&mSCmL=XlODPl$e8s;mqcsw(f!j zsML4x*PNjZey7d6Gx8mI{8!xQ0=3;mFn3L<-9k;Zi@^h~_W%_GQwRpp(ryA_})^5w0l+g<7D3?FI-a z-EC6cISo{(!D*VsBPCv3>(e}q7bciRxs-E+K7NcJlie0Yks@2H*sA)AgN#+F*+iE) z2u*!$n_@iNd_3NUx5nq6rlZdl9CnVkwsO7GNf}M(>zh)bdiA3MX#cgz$Nnvmm-F$m z@p1OyZj?Z!&9tG34QFL*gG=b%-3nktoivgjF~?$x`wi1fQS{^3ALje_@6a=`vTy36 zC83|#hZ9at$?({Ul;sf@DRYq$zGBVC-{8dtrl99rc_T-IaKc5<;EeDSMF%M=&@S?` za~}|Sl8Xa`FA`yE_9oZWUvon4+aW#;eYX{E?I#7v2GHOwQL9hf-Qn|CgYhE0W7RrZ z+BpsL+7o|FqryXgs?qtvmaTxSrJ<>@x&9TN3i&AXA8rluhx-~RPht|^_H{ z2^qbX`09Ik=Yzl7I(Rr*n7UY7JNlZr|C0Ho2=6>Ui@2SD!{DPm4m-IvBl!7?fY4_S z4%C{Hk3_MRlIUo6f0(iq^|7_4XvW1%i49Vg1h>~lH;}-)tEmOYi;kht%T30zO&hcp zP|1jX$b1>NK9-EIx)?=>PG82TMO2J4G*S@zvHT~tKl?(;S zF^!Q>;H9ne*WI_*zWReW(o8s{SNc5VEW@SY((s`gUix7(7oBmEwi#H#9ESR?&K0};F~HoFgm?weWt9!I>qT1!vT zCxFYSe3`yS|9@P+)7m;Xu^PC7tz?09Xy0xe#=tnE^N4w4ld)a453{{{@X7f3X%s>M zk}7mruk%qh*-w1~9ano3?@!4c7yn1mRfRR#hGDu(8fj_i?iLj3j?vxS9RkuN-6$X} zIbxJ_cf$zjW^|2z|Fx4H?b^Zje((L<^*l}m-NhBYE!Y(LjXq%qy}&uOd7Thb;p@g! z6}Nce(45LrL#H)W#TS<62@7~a_I~fa(@ivn1NZNy(tk~1jiw9P6S|)6C!!ZviHy=s z%+C9rn|GL-c{7Ix z%hGgA!-<IK3LlEX=3zw0{e@*@Wu!uM` z!)e*!;7Q}$Y{QBp`xzCDo{kZ|-+BXiAK53AN6S#2?0JzcMI;bh7Pwc*mJMH#l2Aw! zNH~owot=KyI4hRtkZatwZxQB0$ONMBxq3y_Ml>UQIG8`D5W`O)%NHY94isa{1dK-` zmb@3}0KBu!DUXmO@)M)aqJ=MTME?;9Y*>&M!LEz_=7^2B9dRgs?$)+qWN5g1{ztVh z4o1UdPX+G7j`GEc@x6!`52eb%oNiWD2Q2#_tz4|N00vVT|AQsO+k#)8FgZc4_vc1p zLS8*&>UhDigYO%D)pJp3pjLilrVkKLY5}+aJW7fgwO3Zad_2smn?eIiN%!|HOQNgE zH!2CZYjkpbfS^Dwfhbg8JjFZCx4bdlszETwp$*_(Jfc6 z&JkF&o4yrX+xO``e~VEZf4?8KhkS1N3;EzzSq9F?W-%p|t4yKPGg7eu-(*d$f<^urIe35$^6Lu@}U` zfe|EWxr0bw2G`e5tBkMPVg3OSw4YZqEiD5PgRoaBH#gV8*}3Id?ut0!FIjs^9_8;O z%xa&W{2ycnHH0{zxYEw~ zLzovyE|VfY#zK?x;8-sUqi1B`RC!wju^ZrTBpqYM@dASU0|8>#Snu5?##IJFrsnVn zWiUqJp%al(-C!B9#hhaOQTp#&PhWNII6wgdeDx(quKU?z~@D;2*ynWR=*oN+M(FW%!lG74V3R z-l6~N=bm3la9xh(*9+dJ-1oVyAIRRK+R?%r3GKLbxs%bbxIifNk+n)|{ljpYoCM1Y zKR1+Lzk^?z0-p-ADJ~$Er4(w4i?Ip`7pqfvAX4MHMlT znrr~k1y5lZ|6UH#Hao|-lMCC0Ge?SKCP8iVgNC1%vIoji_B87Gev%`OKqiUVdhyTi z2Rj08)Sx}7cy+>2QlgReA2QV4%%$=0lta62omDSkAUxsJt8}5f@V2tOJTYWx)WM3PBWju=_KA1jWmWQCu1wUp%9v3luRK{_+SORX;@#cd_BO4GsgDoI{6MQUO%}N&A=k$lzW(b51V-X@ zH@qHJrq16L>K+#q#WI-;HrIdCNdzd0 znlpN~MgpE$0oN}t<%Qwan|!b-oQ~LNf(MQ;$JW{G6vG|#acwkPLVjF(IHUEY2CW-h zc4ZA-Pl$coe4RgMaz5V#iKV}m1rnbv=RzPmpdkP>We4IN=)~03PFBb64x8rtGYIaZ z%O5z`iOaubh3TB%Z_dt1U93THr@yLaV4}3NdZWiP_(qtAGI8wGDv4fSH3ehi{o)tp z=i!^4TPVoDeG}y4is2cAqd4S6A#LXxZ^rr}rub9owLvwkmrzoI+l-mVaf_@__-9=4 z-(gF%cVCbdv)gcm*c?at_gxxphx-s3IT0m9I(XG)?qB{%ag6^IUZ&-**O`_QiLL!9 z^pz<_?5LAfx0Zr}V#}s2W_@{i%NhR-+2HB_$t=+a^pC&J4_oSZFoFDkrEl}T>%J3~ zDPBjS`{uV3!vyPQlVV2+belk$#JL};s;aV-tJ4q(k~^3tt_&M0wwY*as2 zo!-@UBqie99+4Zh1xV?^*}*r$oe#qsA1)tBu)?(&#K_ z^`vH1WE(o(+xiV@rn#yvc^2-aps>gvAx_DCJrg6ntXwK;@}tw!t>COlTGz+Kq$HXnlpPbT)#2Mr@-! z`MLG%YZJ7(XTSQzZGJ2tdOKe0u&pg>n(p8r6Pnxlp2P?)uKNew4o)l&CM-jF4-!qb ziQ82)aKQE#$+g0T*e#yQ5~?~aKl~NlyMY&G#O1O}z|`LRz2L$Ll~872jXHV!PP5h$&XXrz)Qzq$LVk)F$P?~JU)Hw~F#5yWS)CqIe-Ol(b24#ep7i#fnTc$gz*VZ)MEZL=#k9JA80Ih(-5S|CxGRGy+}i{HsFrN^_fySp(pN;P5}^*8fp4`Iml1iez$W4s1ow%lslI8Z ztxA}`z5rmHN2vl&AwOGpp?-@Ht{hET5k62 zMfF%>^)+Urro~TLi-zJ(q}Kvm8~|gB;vPioo$(TIJ|HKFF0ozC&GMs`ao$h#HopXJ z=hyo{vAqwpTxn}h+r}~}$}Qnr>>;G|e!iZ9^{>a3`S*#=;wJVvIOLHJEI=Vz)FY&E zr|veV`!n(LX%^Bnht?qKtn_vD;pS(pt27s9A^*Ge{oL6#my>qLsA7O>rsa0c^L8!( z&v%Sw>8f!=>2t6KIK@Zu3*VnoXV$1S`=o((f~(Rp`GfLsQ^DwUV_`=1!$lw=^@*_C zbsClYRH7(QVeXOgIR)oQyooJkRjGQh3HV3fvJe!h`l%)TKpqufi=nvdFe>2r>QwFm7n>%4=Tu#3s3&$W;#5OxM+@P;yVG6 zeD%F+n}i|j`LB+5ZMA!E(7DLXhsdL5v0jD4>QN7QztvU_YH=(Ybp*gS8D>Y;m(^I+ zpDo#_-)1%NH5KjU1{Tfd#{Nb>CPzs06OPDZ{n)QjlE5@#HF~LXIfEWYMAm>tYG4D8 zOWq^b%q6ku*gy833^AqkM3>Y4CBc8#a(>MXt?8MQQ!Y~>^VgrQ^}V~lbVonCphMGh zx%Q39Y&gE==Kky@mLW|;Vze_v5vuO&tm&?EuM!=R zF2Jn=Ph5oLcqP|`;ioJ{N7s;sgJg2Ac~`Y7G&im z6r+t|o(%L-ye;*ggzi0`m+|Bf{<#q;Tq1oOKOFeyYB7{R1CH)tClo2e3WYoGnda#G z*`wo2_?w;icpujEbG{LLqle+*X?4vE0*0Xp^IV~LA?oM z(~2@?fTKLLv`0qFkxoR2LU}d-7)VXu;`LM&7Xw?o+eH?1*t-coaAB+U*)lIE|KVZ3 zg)sC(os-kVHP-d=yFIRtk9U+*b#vM5C*yH%yl?Kkv2MJ*eU>wet;oM~U*5Zhz!uFE z^yK6^0d=i81m&Sh~%`J;i=_EDdYP97)1xG-3xppIp*Gc-9AZ#o_wzBf2pwlIEf94Oxp$5RfF=b zzH2`1nLzg>U*{w{z0X#kH{XH{t$bAPU!U*Y^f^J72o@OtX))4&BrbMTMDubJQ?-B4 zJZIa$g;**n6ql4+ShA}+pv`d^H1UpLOhmiAaRnYzGd4W>&Hk%F-tf-m-KenHzxR_pi?<)#xC&eIP}7Fp33*Usy=TmaBbtPH5sxyIL>>< zn~S_F7UXFLmDPoFovT7_tfS5iI6zUjF7$W5(|(BguzwaTgu#WOR1#Q879X3Ht2h=3bSRfS&Y} zF7U5KsM@+1;u6{i#0p^Cta^d{p9}3cpRGJ*@a&_mv!^2^<`SNq0de?ViKmT?we6pP zKf1x`i*qZhYPy>G`n|uF=NN|Jl%tq!BkaZ;|C8 zk!tj6@Yy&yO@M(}+1bUO_9`E1dTyurKv;kFC-X%KV%Z7#pLIlF|Q7hU23Z)K^g|uV8MzeZ{p%XDX5{LS^#>lR}COi{gpddub9WEO|tg zl~qgUI9q^k<}Mea(NSdp1CC=PDaj6wIXDOlCudcivR4!T2x>WMdlYJbwD8=&zA;Qq z2<=(lMsHVbTLt%4oMZFCk^J;If*RcTJYZ0FsRn1RE9aK!yPknk?sj|)@cKOBN zA#}JWnCoGt7#y*YaH5MVZKRv%y$xK-T+Fb<{qvZ8)x6i{^#}n5+POLVV{P$s3-qwV z^Pf68oFfEyHDllUBqZS^k1Ax)7C9?|H&Y8A3F$H81_Udjd3;zvPn-vp6x3X_g7C`87RHcjHhG4~vkb9F-TJ|+{r-mBjdinW6K#Lw<(QCAQ zcmG;_)vuD2(CgrK0cZ?pa}#g5@67xrK^Skm%-E~o918$>?X4jBV!EnV znpS-zu1eVBKg1d--4EH*56uh>i7!U3_8rfW^dBEVWZ(iV+vvWPvfr z^^>L_6W;I?FKPxJ$`dd3%l!j7vl#uC6`?1Z$@8#~<8gL|;!uWZ0skXWrbmrtD3!mBA*cjpP0TrQiZ>yjvO2aIZ zFujL7X1T^R-waNY1*M*6Q&do8b`!55WlB>2;k0piQX)WM%FGLb*dOqQysi$6; zv|;#Y(#oc!u*Up{ZMw<%*8l4d&Tdj(nLpVliT&7IvyB*KN3WR0GMng^=D!K3-wIiH^$ zQBWP4e}!ez9bD{w*Vg|2&4%c;u!JsQ@e!6pLq_6?A0Z1x5JULRrIzj4i+b6=#bk(E z(f@!DCX=%96@7~e_it8i_Ahwc`7nA8dTOWz_z;Hk(Jp9G)fveQ=0F zZ%UCt*Gk_4*!Q~Xy%*Cpdd*2pTvApsCZ{eWCmn8TF`l&&I~la)0xjt2&Mkl)H+So& zwv-aE*(X&_9cy76MH8Q-xH$LvX8!i+y_b!@h=IRll4fo6`HWeQzKL$MC!vtGx(?|f zu}rkH3W_YQ8~oPLS-d2VnqciO>&GmMd+6j-f&)TZE!D+H67imBL4)Yh%gw{_Z1q`} zsHnJzC_hH6dyj)B+^>a=nbnz9q`TuITXq%}9nMpjr_Uq0i=_@2Bf|W>guZtAI!u&z zDxJxf^{we1s6yvDGIxLrJ`|nBXYWIR zNTVtVjkpIzYPM7@Lpzgz7^faUX|=%Ccxwo&w!ix))hI`EC!J_Dm3J@1hm`g zl-&dJ5E0fr5N*4RJ-!XuKx5~=f9({#X)3U;lB3v7{kbyJ7tG+h0vRH zR^9)3=ba{YPOgla2}zjr2opWl19wt}@uKZ8V(sZ$WwCqB@S-d99~AaRTlJv6`L-H- zzx!`PKjFvI$~$vLAN^SXU+bzYuJ|3M|7%~(kKB5Bij%HU;f^sB{vwN9s#!}B|Ce=W zq_59*;{$fF6Upr>`)(}ogI7TH{_fZ_K<;t-iCAa^j|ff?XTw7z!Z7E(UoJ+xm#^D) zu8YYdP}1<}ALnGq{?W=ohgAi-LBd40N6=%)D|kI_PLub8{tNUu13GrFn_h={wD)$^ z_^7%8L=Ew{02@C_hH&5K6laTiN&Rl~aT-aY5WKc_*5Q1c@R73CY^;BrlIVa)hWMPH zu@YjK=LXF271={69p*ghv(uM%1i=k22PXL|EIEFaM9q&TLBaOyE;y&RiTr=IcA^uJ zV~z45`sgRv<3Zg$Sj4o+n652@x~GunBMU}neCbL2c{drN$nlxVrmbG4R3 z#vOK4NN>Hey=`V~9&4eM_EpJr$L2|}l|ZQ$LZgbOrv45iTL}d#nxqJ!hh_a6ExkG4 zM1MHEC|*n$F6Iv$2(L**j5IbDJAtgxj41~?t6I2kR94_iN(sy;R`IsDm~qAvOQGEM z?KWW95>w^ZVWJZ2Yafy%zXTuciMWw?eoelUvQf5mdsQQ)z4hpYt;LSZv8~got(~pv z60r0H#ycA1*yoTt*c&A{sxZ8Sf-&~Etbj8nCxM@6>qO*hVZ8v zR8rF3)zwl_QBqb`T^ajz7T7d=S$mu7MW-(3=jS1d&1_!;jL3P`-4Em0%KF!rUz1=} zln$cYT!Xhy5d_|_bNFcnx8kB~2D!V9A(Vq%^ zJ`O}6uh$$gfLJOu`zZNMJ9XBJD}JzDum;W2ub(g!^(Ay^xJRuJw58g%A1{;y5vT4{ zwhW~iDV`Sn_vb@5Ek<6ZF9%?AHGr|9i=p*%k?M_le!ppc`IImS8Na>UJ{+inO~mwqZ_Ye%mJ;7xgfQ`VHJEs+Zd#A4#s_FRWe9M>T!j zFKGH_Z;K8sCPvMEqAt%PyOSH?uO`MF5MZIu%d_gm>mb3iWYF9Ub+^rPu>19Sw(l6H z^U5>Ci1KlK5IVuW0{4M4X{|r;1q6OsRx@_|!07@-0{_*NGa~L`)u(@!<_fYe9K(7q z&N7I05pqTKE~;GNi%Rh@U8n+M!S}9r_8GYKmnrl!K>8TIJI2x6n2$(L5bu=JaJ1>| zzjRwRm*lo_Au&kwzuyf{Vi`FSUZU_2suX1q;l1|*hsLlx}d8B7e2(wg#7^UbwRG6OYpfzVPka6gBheatc;GfgRnGo#(-3R zPwbyB$=qNy-fz67$I&m{M<(VcW@k?R@}lfQKN|6ZFu@$SAykO+52u~@pGuhKNk?#t zjf6j@ET`|>$j%a=%2sE7%KE04dP5&;K(o{y$yj+*6X;z zXG*iR;TE4WgWq`PbUCKLzq5o}`R)ty|0i*>*DBg@ss0B@Wp(MQH3QZy7-jdd2O&p` zr@Z-%_c^d9DS+IUuM-~pmHqV$c+d;rt&g1Qwm(Xeki^!~-~v7*06AVqGHq&g(I|~` z0>*YAZx3fHOmo*4l6ue~>WTHQ6V*f3KnO`~W=(2ebe#(O5S;dj;8&Y_jH$nXQ1(8+ zQyFNB{hrHBw5yR|6X#MVSEyFcrT6D$#v|Kc$2!}7U|r7JRrPI6BLYTC?CjhE?1mqR zUxQu2tA-{<1C}NzLRq=_`(@G3v}J+0x9Hm_?UYK%D|3%4PaG=k zEB6?LfzhUxUao=EIh$qb{z!0)5dnrj3^t)lALT(N2DnPQNpc@G9uK7?JH^ZQvA zWf;0B-|`1-WY^p>&}6cC8VUcQW_PaTsO6X(y}Q5Ggc(#>F?nH@RjuWpwal08MbBfo zYYhi6?!SFmU0wCTUqS3$%ba6XCh|k`trWWf62d2d*m|0K^Ntw;WE__u!2h&61Ch(o z(;|5;Y@)(}9*Tc{yUKl*3_Lp@S_-rJ{C3dMK@C_J!MR%8*MGMD&7e1%$sK3xAyw53ic_Ge7Sd_fVCvRX)|4A zgxCDyaAt6F8@t;)J|8a6WQ_>QzS0j?4yKV5AdXW$*sB@%_rGd;Nz5@uq5DDou#joB zExBS~%Dy*ymM$Mm3hW)Hw;9bZ+YF-#?3<#VV86DRRn?QGCTLZAuyS2lusoQJM6;)(?6ZQ%urKUWcY--|Pf=yX1m9U;!Y!-buMeQXm?GaqO-TPhImy*xF zL-4dpo*RyZJ;_}|n|`y)DBvI{R1n%UR@ZavEdo*6djbFGUZa3I#AUtQ5s=A@E%xb_ zZFYK^n)>1{iNv|1Xf|guG}yhEr&cK)qCxO5Ye$kOJlt0MxGp);;13j-`CL3cwA1qg?ZW2qakm zRClRgmXgjwF48YWFADKMw=Eo(i_j$FkO#qTtY3&LQGWXGT!=16aF~9PZUSl zP)}e9Qc@ZGq)d;eoB4o2LWxYSoO}CA&;bBC&^hJAH4%)9BDzf1YGU zi=S4)Hr02;YD=Lj2LI zy?`{u`o{?KHFF6P$DMHu4`PtwA+*bR$G5eb}CswD1Ly16((~z&7Yi{T9ro)W7Tpo1tji6#j`!EIZuPT zpx<-sC|p1hOMjVMvv64mOX}Oa66(Z<$n)bx zJEm}rt)3O(TADZ3A&-S&kk0<)$HQ`bXB%fS32&2}uHCmsgs${rYrsS*6yY*mh@&Q$ z4ByMw=6vq>F(%iZExvk=I>zf=;|WdCF$GhQJwp14e&WSAeU9K zk%re*+e5apt?T0kS{_31LNkzbft9}pNLFgqh6&nZX78y&UR%|YRgT3;z2C1y4qiDX z(QY36xSVPwW*{xzIUSmKK@je3s;#VTCF|sMDOR8R^*uPJkSY_KWDvz)1fbCHc|_dE zDd-Nqu()fcx8P1-rF-Jv$8ehxnI7WM@ulQBv)Am1H!7;u<70;^QQn#p*6XD@m<`C= z^LlkV{io66a!KI2K>^d~ec4T80cPXBwqytY(;c~901uL9P*r;|Hg!MOJDXo%9G5+G z{)_T0b+tAhWA}1qU&Xr!t}Nu9+2t$v<#6}Qj9QnKk{QIu63`?`XtNWQga3i^=Bm&O+zX z;_2I1-R2|YD#0f9_uxLv!E$e051ZTGLHnNpcl7UmS#g`5TpI5@HO7DwU*ev)>UFv! zW~$==`R$C7hRK5YBmh`~Nx~@z(`JCsoFh(lEhO&RijpIUitF!KHrmeCuVEH~hYx9j zN_+|rj#h=ad4{~(YN|~m38&KoFEdp#%7!@J`M&(cj;6Fy{WD`2U|1tUbRK;;j{&h< z%ae-mb~X-Fq#s&p0Yu zODK*rZlpmol}b8dMdR+1_0u$3nk|!9X}%vLAyqR&(##{A3J>{-8e}CHd-ciE3~bIH z9q6G&v5(buTcf(4FFOf!X=84OWW z47rIsx_$UtPR;fPq#j?d&CdC*tUQ3E-dXA5&+l^A+y^mUTFWRuFo%&iD>kB;Z|5Bz zE?HR;UEiQDOc%<^Lp^$pb*CoK3(4G&&EUnSMIHEM730{q3(5ST42WEYOU}6n)>|#7<3lG%ns@LHC3ekrp(O|WM*hi>=-s?MytKNaK zSBqfhKp$SP@rN}YpZ$TSYlu8m4A4?pqN1>RFp{YM^`79YUn*XZ+;^r2X`KE{okU4i z_SH0mM6){3zP+?qKwIBf9f!xxzS^c5K>|)Gi_4R&FpH}KQ4z7p8|diDmrc$+M; zGC;wDRhII8wd0n5vcmH-dIb9EM*PFB39Ix^eM*5BOM zvDL*=sw=v&g)iVwhqLG}la2=5-FCm%!@CLAt%%qB1eiz!K38h5uPrXC>?&)hul=|| zqlclkP_W3)Uc71uDxF_-R3%6D;xE;>@ioF5JGYF@b1OQS9AR~s(LBA<@zhqh)bY~R z3{v)xRn`sg{{z&#+nk-)@j^sUxR4|s>Yys)ukF5ArAl4EJxps3;>AN*jWPlxJR@YV4h`FmuSP9G(3(Nc+E-H<@tNbc?PX7Kst z8+5YQByjh#JH+f>c5WERa?iWA>vxHIA@&gAbNbdRdLQye`P}`Sk&ml#*0~&bDcS9Q zkNK=iMK5@>_ZmSB+Ghhb2bq{=;Elib_jdNrboM9M5Cl;^W`;+{B>2@gIU~|KKpy>m zKKgk)KAt>YrTJoJY3phIb%n{FhI)Zr#Wf^Jd;Z2FlRrd}{Y3)tEp0}v8C56gv*x#* z1l$R8zNDt?;r(C$@y?8BSR{vO@+zlGaeVuOB=1KLA45)z5&7w_5Wmf~rpNGjAL$v* z2&4(`UAru%-vf6Z9274)w7bV>3zf9ShmV5d^ndf*!%p1)skQ$Vt@E?9?72bmI5+wS z|9vDPgg<-&7*C7TALT@ZzrQP(T?h+T?^pXK%sA-4qO$pgmz%XS_ygj47HnJV8%?4_ zWdub7?k%k-meRMW3iA3?=1(linAtIcKjw>QRN#Hbx(@odxXqUHLVp$U<`Bf~v4T@K znN|@$Md*)yey4|IC+uf#&n|G^K2zEa3+@&M+Cecn*#e;pFxZj37XlqQRm9X(tk166 zbARyJ%zspSPO-n80ZBq0inBZM-2o4S zfXuf&AL8IwY-YCC72RF&CtQlr3xbeWY{j?RlZGKAUx!B1{ljqa>R@S0yY;RMWMo&+QaVEhVqp<%5Ba9l`aE-F{;@K$+P1^jgv_SlHT#Cla z;iqOLfc4dse3}**-nkOL)T!U9IR`B#i*Uf~6UlKvM_#lmLkLs{)WCQWu#lIec||N^ zbnObizOX|3?Bio&AYwqCd#p)Bv}d&k!K)Nl4*Ky-RfO)VSoU1`QJ#l8BHJSX)&t`b ze4X3Z*H`mYJg3BnC?uO8#S;2UWn(P#D4Ud$r&z5Le!QU`yYI(%ztXVZ%O{*&#Nozt zc0_=V(>Eyw^PGRVcD8iyhY5;xFX7Q?Ld(mMHPo7{t zmZw-pC0L4tUt)H1GmVVu(4e4DWPJnVPM>`8q)oH5eMUay<7`Ze5(|$uID{hF`{%Z~ z`NpQQp|-5DzV7CRp+7>(QBgn2L8OQT zbF%PGvA|uw5|ho*;CRwu!9AN$1^wQqPT(m1d_Jg#2?DI`zw7dUz6=SpdrnV>z+I_s z0^d4yM~{~_TE(cbE;9g|{tip~6QEbg=N_o)CcQ9RlyiTJiKD~|urp-3P(5b>uXb?8!33`-Q3xk0E&9KpLoR>4yqgJ)CO@HG2Go~ql~dpt=?U2yII2k>>n-JuVG;?+JPVsy1KL7=3Wk~}ZU#+(pMiqiSNqw56H2wa z@GYT+?cz|4l*<1Ev#$HRjWK4UFdAa8kA{PZiO*$L7Fp{Da z;u&KDu>*5TZ!EXVItxl!0mU!Yj`y0m(f>2Vg)3nH zCowqNgHDUkf=(C7jv!W5;wI?LD+D0}w2|J}#ZS9@=(MrbxM5-}`qbUk`K%bXc8>up z; zjOgOzET<7;Irm)F|D!*ll0Xt=Gm$McNbO%W{YeAXTH8{x*DV&b#lj0HA7poGQb1bf-= zPL1eVXpV8iYoqM<$U8h`bY?s5b-V~(?+wLBJD2>)=JZ+~PID|3s)7?fh)Yb(8m_(h zh^o#$L@ZztxAr*X!wRe|C^Sr)0P55k8HkAl@uFQW;`=I^tbH(EQK-fo5cI|eh{oif zJwR0gH~-ZjTkr|T`KCT zDn2e`e#AVr~@r{!M*#ejdsF16K`#19PNbKE3riEHH-{7ZH8uqvwYD>eyG%T5~!W{+J{E*(_3m`=x5c6sQh@=%_ zMbTmZP{W%jeyVb@O>=6?QB|=B>tnq94#+J ziyFtwX;@kNN*U)Eu2LfIq)HMzNMtQHpkpn?r-^?Q)uWvkv89#YG!Ag~uy@$^3677O zbS#1wb&OnIm1d4KH_^T`<0G}-Z-G*py4QkMn-I@$I$$(%~hFo zodlc)IGIh5zhJ!Y4*Unh9!Hmjk|7VOg`zKoCMfHUk{;5=RqdH#4^>HLZ)GX9umacPfVAx+!n zXXXwr-cw%|yEdB$5M|?x%I*AZ$;Cw}vZm3(IEM=zw9_>Bs?_F4|3%KLeTiz}739}2 zbT-3ob}pl)Wkr+U`QD&VjgS-EK9W6=@(XT){K7p=D=}f)(2#BJelMHBL!iMgFKlZO z_!5kV5EWiS{o&aWIW_dEb?7>$iIN}v%iT{Py}P$eq-RDhY~Kl*5`rI};I;=2rAt)t z&j#z$N`z*fb>g%Ih!ehg_S#fVX4;=uvv} zS)sAvXN8vRv9uWOl}j$r&^)P+@p>qg%E$e%o2gTr5DRw?i69k`(U39TzU?>Pp%;tq zm|MD40XJ4+WB}4Pq>qT;ujO;QSi?Pr^*ZMmDD)o9t zdy14b%5;d3nR6Jo!4Qu>U`>KT!qo=}jVBdQ$jWFP`$VsXX7+MSIh z1zM$?|NVU3poG!0&7NM`R(_pMZ;w(Ex7FUthiJ{cQOfsog^4BQo#HC~J2{ z@oBq%q2@#K)b>vix4X?yrq*W}OJEccxue(({q7C+Biiku*bcRNx{a~(-Q%G#z-*#> zoBjtrP9ju%Y#}B|%uDI*4mrEo)f=JjaC6-c`R~`7_8G#)C*78(TMJ;W27lvsJG+4? zE)eqjK}dY}S8Dk7TTJJ^`1k*|a#-9Pwga6i%~`4R5!^KK2i6Y%f)uU}LXYl4kA9ir zHTk&nXqrLw30=LIufUJfGA5~o>=R~*#Li4Ni<>km*G6SYjPPrY?aLB7F~Mg<^#wMvpM!B&uv& zhco^`ee|#wfK`p?ZgtZ3+T$BfF1AwuKPFVSo`=CCe_b_671ROn@Tzqi;By;t* zbr`^uzgHhH%EwiR9MUl1<+A(yMX+V#L`r~j6a>YgqPHRPdGBrXf z*WwUzfGy%e{6#VY?GBRYdX6zQtn|Mk;o2;0o!k})&jYsPylFL_GC}yyFY(Ynm=3s< zs2wQh8oC&S>Uvx6q}c|~N=mWd9LI3_)Y3>VZL6Lxy8Tml>iWhB^ey1(ei6lmGJOu{ z=&!W0^^^%!Vd!Fp0j}**jHs57 z^b@}0tH@T43p~mIQB!W5MNy}hcN1~`T86jxJX;vCXct-&pP=BmMFygG7l?5#J%q;H zH})qnDhIk}iiv}vgNtf=@MfU%fxBBOR+`_BL|<5Ns#RpEwASkP+nJS-`I_G@Zcl5#856vzE z84@gnmRK-7_5JKRc%lf@$mcr?vW>rGu{t+D=nGi6R%)xqp2?6(`-6R?v!!)$jH`Z2 zc6m;cnm&hXh+xOQ7Kr&h`2e_`WT}==wvJcp$EjAj4+0>*7yw4&ASwTfuYb$nCYG6J z_BC@9FuG9hIkJ59As+ei_%#0XWH&bk_GbpXq@K85T6mL3WAXpQ7S+YQ`yLVBJRY$5 zH)ZD1n9ou1?r=fTUQpp+dR>|TOKB0+Y@)$`Mv{xwngL972fCZvHDtJo zQ$dgV>G%oBL{u^QZ-T2JvlmnWqzoxd_BeC2&CnKW*4VFLC-|JI_ znpA}Hye0CkiF8_0VV3!;XHpct|59f?d~jIwlSkDWlxnCjq&xw8>z(d&LP;7v*P=m| z{cbSyw2=6F|H)!foh;KWu9yT5*#{)aN@$0nq zZP2RkW6{v^OP)0xk|~Z+&WGPY+!QVe^{RY6)iqlA#re>N@NnfUTA@vP*wT$@aFt;V zELHZUI(U-?mG4yF)(~q@@tFQD7*S-I3i)I}V=_;d6z&ba=9(^KdX`d^|NPALkCl>T zIAKzFTQCf1m<&@+Pl^ypH1ndH!lh&Fd(YNbOgJrV%iw8Vcs(g1_$iDnsk4JWqhpO| z@#4l2IR?@E>em|P#QoagtW)xz-nlShgTtQS^tXe{^bjiIa|<7jioS9W`yxBPAi{Hg zJ~4#A={8=z)%A$x0We%|4MvbI%FE+GoB?WCc^o)O>3v%w$=Ui)`obo#slBvBvNm#GaE%b~Vhq2FRwO8@mA7)G&3PNo{sMejXrws>Dwy9k)4ykVyB2 zo^i~WYnAv=_n?UBUn}uD?Vmh2wWz$TnQ@D?Qwtf#kWcYq8k=IiB(|7t<8f=G_c3LT zYW)q-q(k{+?z*TM+9s_-&@ZfcHt&@ND8q$`Ox#a;Ho?(Z-VD zlS2BN?un#_+MpTs7{2^u3m$&%UWsE4wmkjMv~3*Pb#gAxXRe(h$E-Z5oQhuWlyiBg z)ZWKf-{f4SI)a1*m7BWLD$u#FGM;I<=_Xxv&S?f6w*NBr(Sh+q))Lw;smQ%2dP)2| z#Whl)+FFRZTjI1#R+tpN2yeg!dHNOIp?0;3dzHt}Dbzr!+5+41DJZQ^Y9zj6B_Hy* zPjTDOe`1Shp4AK_pGjQQi1xI4k5W{lMESK$QxYO2<**(QVyI=;3tLpwz>VA|R78k| zo5F0{N^-9Wu_~{ z9p+h7*}d6RCqJFAR4ydgr8T+x3n?(7EFy$p$>FgTERWjiCh}n1oG1xmIT^w_SwEuR zQ?bEO#n;(KARaS{)9;nQ=}@xxONZ*glF*08wk*wc*lylhI4hW@7Umn9X2Chvv)Qq^ z0^RKEnVoCICucFk|EuE~N8WzySWBoKLU3F=FF>w0QhI(oLm)mJiqSbLx!9haml z>3T@jPySSP@u9QpW=TbA#JFO}r5{IT7)Ns9SYr=>ZfvAGH2+nD1)sOIceHg(6@aPg zUtWA+*6#0{sM)|f(AVSN?}3r}r`?=tpCF6o%Em-pV_h)DLqDRHrunL;PRDYJ|GAp4 zon8*zu5G=H;ZdN_e-Si{NIGNSu=(6*)L&>&guP>CoUqbU5T~ILNe#t%7P4?qYdJlRtq8P za21GQt|d@m_jsOZR;V30J~$fUr4q419#W|?eFVW*J!(Oeyefc%xy!hb@LgHp&q*d}=B;AmXGs_@)y7 ztHZl#U`1v|e|k`#-#4;ndgLzd(M0PXcTp^$N#)Oy^6j%K`=00YV~-3r(aRNh?E*(3 zqPt%3cV^&>mwDpL+G)XD$BVa%S6}b19}j3#S)6>#G|Z~>sn-5#{rqN?zuj={D;W|Mcv>oA%LehzfXlZ0l%QeXs8|N`f6`GrcrFa@Pl~ z1g@wgG-PE%hr`W2yz~5HkN)2KlHZMX%alSXb4_iyf^WDz%#Do^uyq2KNNtGMg2Efi>$Lq0H|OW}E-r}9;casA^5KSJ zBzsGKJqT_-etz3MIX=(QaFyF8m>hQ64OD4p$BtDuR~H5agsfH>-&aPaNXd`xG9c;-eAR3ZI1{p_S1?eP-r zk?iSd3GuBS@r?oz*q~`Nkta1W9Bnf^=p8i1Q?oDqRkOK3N;{x0JCNDPMw^Si7w(Hj zgDcua_z~rJq+V#(!pND)LM<5Yc$toqy{+M19woxl&7g{Rtnn+aC!jXD`BV^*Z*g)d z7v=nco>^1cOkmzRr4h=(4qhfZ0y7ij2u>Q#KHLyK_OeWUDAY~s#&Bb~+V zE#I#_)j*miokdku^X6MfKIHpeko@-qb7vz^tE&cNKdAtl5F@$iSp1zLNB5qW6GnPS z#;0Vo`g?X(x_}27gK9)i0KUDW2<)Cwzb4w=R*%Wy!~ar+5h`dz^C02ubn@GRtKMCM6O(Ir$cKd>NYgYwzpR^9O~5t zIOC?V!2E_Kw(mvkxmbs=E-Lo}`S0(6K~a8sFz+z-6KMEB#uMeJ(o}^|DBk1iAQps) zg$ySm0mFQASz4;pRRs+t%p+QMXqX|$Nd9lWBS<3(8>V?Hr{-2A(7MXcQOeIGbF}^< zeKcFQvx^Q8W!8Wo8Ejp_(GW>be1~-A>8NLK$gM_zpkOFN)xHO146URC#Kfr(~ z>Jv;_FlBQ4m>T227XatGh|S!|+8Uur7UMEjOog{e7RIgk&#warPeW$bcG|S!N7^h` zmztLHYAl0ZL4irbjZFj11Cil3ya~Rudm>ZCos9nqlGtHH=1+n%x|!wUi8IR_)fkbF zw(iX&x+)TX&1pw>?`!EW!W%7}eUXaIqx=#?Zly8#VEAi>%`Y0Q@+89wZ&r0er3FLa zj?S-;St!`_er=c7i3`^D=9Aa$6z#p<(f#De^BI2bIAm+OW!6DgRGe_WG44!Y>}mPo zPlvyxooGKpig*?yNfPnQ7<$Ih10S#nyylpPFrxTkMxn*czdf@}Jol=p`3lFk{F0#I z#;^G<-YsY07}Xm=SjHewW1gBL(ndZrVn#?L&oh6@r-wh0s~{PUGu2S3Nb{xv8?WY~ zHYZz)25`|-c@;;fKju({?wl?#B?{FF;igJJSwtO50L zG#oV5r^xsqt^L-TiiIHWk~G}gT^a24*W7IV`267dXO&oX4qg+To9isHxU#nbdW4xt z-o@Pw$;S)i4~XYVW~;G9?D+4X5JOW+CbGS)O{2lyzVe65!-m89?TF6fS3gFSW8u9| zVjDtR`&+xFCg6fxvX3)uyy=;l<++zV+_M9TNEa9;KYN0^TS|Jn<@l5A8&U<%+j9{- z!zY1`Hx-`_0U%3DKORFbha7I4oq_bXsWjLYES6Oj2d0he3;C2?Q6cx<-`-A`#mCQY zn>-DmTjCCgJ5fG;`jj?88mw|ZGFm~L8C8hxnGPomCc6s!#*NPN1FhQ{Sts1sD>d#Z z_5HUDDcndVi`D^K-%ntn#4h(7cG;aL?Kh`PkT?IxzQmN}M7w@DHnOyOJowZCfB6C* zsRtJ?x+4@GB#H=gu7iK59#JD<61AQx3I4Pf^;xfr?jl(bRY8#OQukfijlm3z=j1(c;V1pnG122IYauSpC? zJP*H04(dmIj{r=sAnu;c2{9F;gZ*9m(-1{zKAE4dH@gP|ogm^@i@Z?IKFO-LS;P|0 zl&{2|47hv@#}eNu>$_#sK4p{Be3hxSSeH&7@kq{%1I&tke8eoZVOt1OxcI7cibn&- z*QbIZSxs={2(#3)QJS8Jim^&{`m3T72?VojjB2VQQ<)_MCHRoxQ$a?f1_=n>s8K|ib}f#my6 zx(ip*e{f=%m1Ng|umJrE-*s{-6$j4!@J%EKOy+dyqy?Bvf@5J8VBZB@FbAljzW7sq zuR|R2K>FbUX%MUX?B;Uv3;Ezu6N zhiRDXL=*wb#k^OX;0vTMKyK|Ip&rVEYwvhaU`5`bf^Lt2LfA{d(ddY}1eK07hU+Kr zr;xwT_|Dqj-`>~EE4r||SwIg2Isb#?0zM!*WJK!{uM>M@1K+mJ_Wp0*Tf5=PNG|Vc z8kp}c?ZJ7uc_b9)KvdtMuD%v`K}A3>BU51Y!msga2QRa4Mc2e+&j5Q5+NaW7a>_Z# zkK;hHdAH&MPi>~m+E``3fL#mQ8r(EmpNfqSWMeNR<|@X2CSkxh`Qb7idoE?-YpoJq zjBOP(ymVJL*SE_G+gZ7U+IR$p2L2g(tNYvOn9Fm|t+k>nG*8&2{H#C6hSnYaLzEbe zbFLZ^nOev~4@G3_+fhRe-VEuvKX@w%i)UaL^=JS3NgDe2dn{&Z4+I%1*7i?>tb5Q) z3`p2}FCD+ptR$Km2LJHMyzSTdyRz+=XsX%vs`BSo`e^5#yP>lBt$5~r+pDwXtEA&qA{)G80cMoFK5ao={fZqxAaSoC@mpsjaL4*zy(Cyw`XctW2L*Q} zoDL>l-*70QT5kRBQ6uCDP6H_oqL#-{}Wk$IVK*<8SyW-SyaqLTzAoadxlb49^EbL1Uymf0IvES{GANLtbvi0p`8J6Ymn@fz|_lKIZ)y-dqW)FY5R&M;Fca#madBB#unY^KDz#jmkWq> z0K(tn@YKjc*`t>(Wx&sece1 z38FE;FFp&rGxc`_s$nHeM9*S3^`DfFFt}x-1n70JLLMPm0dr`ZhT(rc!gZkN2`fzd z(#>w(@sa@rx?z@Oat}oAH(dH1C_v?|>T~s8Lx*OF*YsajkI+CLi$I?M+u6_zl0oo0 zU3T{cY}jl%Ik3-Sbeu2{<6pG32mx) z>#*UII-oCa?54@b;+Mid^R1Rj!(-p>_W1nu_j9rd4Ro%;{sl^|ZELIRY3bDtbUS@n5o(4ImaUoubrUl%>zoU_LdB`cQ=KF_`3wffwTSD zyU9e)w8D*Z%cUfw(FjnFB8TupC%dH{;)=JqfkP9=iz<{BwK0m{8HZj6n_gRn zUVDlTfG7P;xc3Z5+|-C*y00ml#YsOZj#Z|j-mfXqbf?TboB7(E8)vZ3FvNL_qtFjG z&9??_KS>>;g->xULR1w`NeFv%a0?82!!=Sjm9_g?Dz8C@(XDy;JFCkeHIk7b`|BK9 zLX7~BKnn75FH=l+v2FK*xP79sR>*jaWB05F8mw$;l&-}Fc_R_$7<#oumNkbEDKu63 zc*vlJW0WEXQf-L$U!>G0L`B2y{5^7P?qDdRGKS&Y#=GY*8iFSeYHFKMVAbO_7V0B5 zfQx^el_V%)R2NfRVFlNNb=YSVQzbSPR4fC42j25ANegG8jb+&vU&eS|28AO*d#vHk z8fq~=5_4ktTQ(Nt$g~#17RJ~hN>|S*qL-m_BmE+;h#3$xm)kH~9?j&NX^$U=&mZr| zzpS`V3Ara<`gm&@N6%iN=s{R+q{l|v>2wV@k;jASL*d>fV&Z#7X%htWJ+aU}*~w!0 zqx!tuQMCU3YE#Ug-&Adh*^Rr(I8^P7a<`U!68Ij=Ci%mtk{!b!Bu&v#7f*)@=%NS} z7M6+Q*%%;mrz^080L#x6i5i{L;#w+|ZF4GcSIhqR8|f!94f~Z{jYY}jj7`oMA;Ro@ zjN>p{!21wnMBFKdY+E7cE&WzaIIvd2>dLg&;`WObC$bNyh+MotV!(Vg`?Q59i?}ca z%dr53w}2&REpLQz>z<{0@mtFzuGj*9u%nkR1j;D2UtNE{o>1%wL!awufu)k(y8bB) z5vEUdN^$7@WG^Evfe0{99F=TtLj1!b@9Ox7E>PjTk+PN~Ij7 zBP5vCGif(2g^zz~U?_Qf;;+vVmp@cZZxJl#r7}3dRNHamoxV(t;i(kPi%-&i^4WNg z23u7sx(dRC+{@G-f2#1e_3BjRe;=LxC?dL;htEK;q(akCL(V5tp{I$j`y%Rigt3CK zM67=D8`9Dre1E8KhevYCfA%vx41slFtI$A@h#cRIvAHbxDK zp3dlcX`p8S2n`Q1+7>0{jEkme*R1T?GwXxfB)!YSaMjQ(zTPJO?mw+ zCIy?1YJ2sT4xc}2@oZwAunHaoAqL4CBQcLm1IA&~n)G2h;FlAc<3$NurS%l0VH0dwHU~Y zsE3OKk*$pf+1t>J;8Rbp|6c0m{w}ajeA&@ZOx8;yaHiPnW#5aA9UhW()wAt3 z^$Px;iTnm!Bj1C5zu$b&=hUPa1P`?Q7``d}>yp%2F&0C1r3D{i^1q8F=uG(WB>LhZ z<=;Qo&AM967fqJCyNkShvJZg0Xo@#-P-|899Zg@?%j&O$IuherzG7tC7o;8=NbUdZ zNc~RERRX&PgPgbj7lI7nJ5fOy~igIPKq(Kfxwd6_JfX1sm z+QLQCf63@IN)wPfV;-+XO{>pvl46#!E0ML%{;G}Sb^@3U0WJi?^jKrP*0w~3@#F~N zy`HIuXg^5&F8KRFecZc3Gfja$TXJm?HK`kO{Et@d=m(%s(oHiWXyl>f*xACfxyk(o zVUN3sZrTWlARMr5V@qAR>8{ec6s>JW`9`Fnf+}+m6s5u;zTf5??U78%Fa!sA`S|4m zB2vHF>Pcp~gF-$qMm_&bkI%8M*O=f!&ElM6rsKpw#jh{mW#E)&Fj|;jB*%L`m+_)0 zmoTJ2m7kn;((3R&VYour)(^ypZqY$~UQCITHGvV0sF$flWlHgm| zqD<%tesj~1BhJJ4fZC;J)?$pKcr}f z4R8Bz(t$GtgLp~IIUOX-!wYMnZs(+I#dg27)=75h zglPWk3v3?3DM!KiBv>y#SlHgnV~<*!RvndDB)YiaaLsgx55O@ z%RJ+b&r;Y$@I|7hN6;oD&U8QNycDSOMi>{w&EqC*3)Z92PCI8+^Cf0Lj!i9YVbTm zFyasy;Ysyp9hA2{&WKq}90>C-ta<)LZ7Rj$?;~>v%{-dL%ebbiaHc<;LE)2=Jty~$ zcxcpI5c1P9qkodSG_#XyD?d@xuT^mR>rN3?rOlYO@))y?^t@<%yr9=w5yRR!_#oL8 zHMc}@rFChPEv9`j6 z=(hpTjJ$}vDx6{wQS!qh8mus8w%~!oA)}CA(X<-u*OXsvqo6oxjN{b2Nkw4`ymsN# z6{So3Q9C7uOQgLVaYlY%Z0^j_gJ~tgQUc6#B}AiOxbBzKr{B?WzoS`@Wm$q0lh;lO z!;L@XBbL7f5Wc;&Px@PNFB+%WGch}JuwSz>U59}7T5@H*OcCD>pJYB`9nZcV9p%(K zc8rmQ#G^RZFtVjrV__?EmLdM5>JoaAF~{oAZ^tN1`OFK#LxmxF!+`;h-TpJ)ToTSM};sObvzr?qE@2IJi{+uBw z#`{T3lxs;`cw>8idvkYlD_zmAqmsu(mEy+Xt;yVP{M>ziXJ+K(G*+sLc32Cxft$P6 zCRtfwzjWSY2U;2R_+#V*k`n&1HufVj-;Q!8JVr;J{r3mnmKmw zY3?ZPJGs5Nl3+LApE_!DmTUB{EpM&>l<>ZG(iK5IegrvZ^>w}lF2HA}4~Fl#ye(q8 zp?!=VDH!~xcCfBtMw|s5^Mt$5Ez%`$OGrq-#KMxxY)1*JZ)ji-T5+0K_33E{6FY^_ zyAO6<(V`@M&X<8-w{ubTsVKK_u2O&5AL6?B2hN}8{&n~SN%553Vz)mr*XcDx@gNV%VX(Gyd{5xAwZJRMZg-K;}=rG;1 zpR>y^xv_m!?Kf*l9KF_q0tiK|7? zoWIMQ$XP6}j7-ZO(JL#qhvHZ)_|6(b^LBW02u|rku7tI{fcyprTuACy$b<=#l(0>~ zNS9u6mVzX65-57MSq07}m1OXYpP?!Yg-@XI!jrZ`i*k$H&ayiIzjWL_5#jOCCzW=6 zwc_-IEaq6H%{6H?PlA${0XpL0e_{}9Jc1i+)fD|1!$S2=cPNU+X8(%@rYFXBw z+@{FB0fu-mpkh(XU!iPs@S9a$;rH*L05L{x~w&=`MJ2i4R2<)e;iNW<+^D<8|c(kT{N^7S4^<d}eQ=(K)ZQF-l9oiUT~ zH>0+|L}X zGJFN_?)3r;9lT6b`>uu92T*yfIMK0xPw=tfK>BK;QSqtml4iW%r2e$mn{a6xafake znD`qe#X6VAz71rkf6ZRRRP&h7f!&j`SI0Z7M-@XdDYorG`?9dHVNVigZjj&|fR+Bg z+6ZKKj2EA9@uHOCy~*a{Nsj;zKt}d;u?e;FBJA=4Tt3hKX3Yc>4rYU?;Km3HWom(c zUtk++->bM}tSs@4fHvur@B%=UAi26=DC`Q7=g*WkTSdsowzUpH@8!eZb5vdLY_BNn z3V8mvn|s{aBFMufEV!_Z%INIUP+L=H?_34W%FfCrDb}PgU+hVvYDf$IuTo@rDcync z@~(wL3;V@qD{^%4a4+q;%xGeuU5- z^}l^v@T#65NyvZohNAeRsYZx63lSh54GhPEe%54V?P!n4c!^n9HZ$5U{rEdJt77c> zy+DqB9M}Db1pOCsAnFG>a*}EPO`@a$j}j_e4n{?KcF+;=5h5|#Bgg0y$M}=-kGGSD zKQ#!iUlB1QI=kdmraoDESg3m(ntOQGRoT~6*#q=LZgoVVMqLAPb)wBz{Q8bIedZ4< zYwgoTmF!A3d@-RD+$q_tTW&-#c2g>OEv4k3+0TddRw0s-{n_;_h!oV$J`@VGtttoe z_KB1QoRcnUGD3K{kYwhl)7yo!qzZ(?kGtgUO9p#JaRk=yB}kw3ykm9Nhwb)!$rG8ssSRR!rMmtGciMzonLBqIP-G* z@pAj=_t@0d@A*LiA9|y}Sfij=a8Rrfh~4#u*?E?Le~oT>p3rz=x<4z^EN6m4{aF9# zdzTf##3)5+FYcmg-Zg9J%5Oj{z2`uPEQ~*56G5K&RIQ_1uM+)uVpTymkQ~mIOQw!V z^+A-|ekP+mOzAXE9qAi&MrFoe3j$BMYDU`8sX8VHx|=5ZsyUiK@92(%N_y6MxDwDA zeywh@*|N$C7mqj$sN2Cs5SWFRj4yx}2;iIpTcz^u$<geVq*C?2RZD3qSSJp-K`TCfV4NlX?Ziy{{ z??v)zEJp|2Ln*^8yn~GS`ik-5yOsM06jT$l=T$CWm#z%d0aAoz5H#y)jtJPCZJe+g zG{SYC+xfx$eCL|EQ9F}{SJ*Y7NxAouU}s1AWw$&zBNG`DQw}3j4imd)C^Je&MRY4OD>Lpm;J9(MzbePnvfCdHBvL7fSwdS6 zFQIPEgZokMVCjUpBAp^wE1{~2kcz0cC$oG|kD@z0#jKGmNVE7oVT9doQUU$bCV4w% z?vE>aI$46_iS%1f97PQQ9@OJQ3%%W_hgq&}25nA!eI@h9rqiz@-f;MS=a1N{l&wMr zqOM*;Uu1G=b-mCkb7e4PB~xjlYeE8)Ee+$qy~glT|u zPN!%Jg&)@VuFrNi?NxgIvX2*=)fF*vnsyo$0~^4%09$HoHGe!(fKVuVJi@Rln$$8X z^k+MN2*7FlE&5pyJ4gKO-JRk41lsE0Qs_ zun2t&rkT7sI>4SZ&4j}K91%Up!8f5X(NO1@~nn7F2ivAuaPf}F2!=r%LStdsoOuR zy^ek$4TBLXfO&H1?k%hq18|-J@#3$XTjaJO(nb@g_ZwsbkFYE_B&v0_^|$s;WMt{`n1|cDy1oejMfbECYqNBN5cv7km<`FW)Z-23VHY7WQ*V zDN@*|fwl1$P)$b}^xFimdm*SH_dn4yJPjoTX&UvUHop1n_d)w&ow zRB`v1a!WCyDsv3}4Ov-Qqh0#Wb5bt}6(|LSeB#B|=JBL=wCa}qK=am>Elm(#LXWd6 zRS2IZv>WgJVfXZ-vvFh_Nk^0noce1=J;&hZ-NcI>i$WxXX8@UM84FwFUGG#GjB7D_hwlqR0 z!<@YadfARs?oP*Roh99xRVQPgoz$XO6&ZCz%4q z3l06&F@yE9r?0S8{3BlLYLvWjdg38qU(29!cUM@%qVUtZ^Jt?-h;Snm4Q);!N)FuDvjM0@QHDa3DJyA3}hnhNoe|iCO0BtKkUw35Y_?O?rwhY!+F$F3ypv{Iv7Dh%4=~oMGO8JpS$>BcBx3ZQt!C_}J<5g^m@si1*0CJ&ewjih2h$r|kf4krf zr+UK2M3a>B^-6P|hLYM6?-3U0XH72ln`7yRXzK$ts1=Z->;YsX3IojZyFDu=;WSChM<JO-;<-MLLW0tb$~xPfC4y6aGt*vb zJ#S*`!%!8(4iswd1%v=qX__6cEL{8Zx5#Hf1cCU_b8_2YdXEaqQ(`Ps6;l{Ik_8g; zIQN3j?>?tcXi40e65zYbBqGcpq)#6JKQI?ZTw056Y|*E%2e15lJnCPGCPia!be#zJ z9G7#bm5qzp-ZjaIr(y1hV7r-<5e~|c>}#j)h8_Qkj3gRhPvbf`#Z2+vyS6N$^jjO97mvlGZB4=~ky{uMaG@SFvb| zLA1@ipT*hNzE1;(RcX1{BPS=2laqgVZS%jI?h7BaRQFSTv_b2bOF=r zo|M$Jkprlt@U}4`yL4L0#5HEQcN>e+3|+^EENF(2$bOh8IJ zc;0Scof1xQsJodxp#h!9KCY1sa66)ir4$=Nh}LkW&ly#Gq?dH}L=&z}lfdK5v9&^5 zkv-e)vK>)eubwYCdoG)3G!^8clbwt^s4p2g8S;1FZU6?E9a=qlv>JTGP>u#~K;@PR zimUA}v+n}=g-qXK_@H?J#(h@Tv^!mG5&h2)_yThuUr(#5&j|9uCCdbM3NcQ|Qdvc; zpGvpbW5`)JP>(HXri3y7R9ZA^>+PZE?~ttOi7?=L=4|Cje1)v2=F;{qdsh!-wJ5@M zH$n-EAEq4=$3IEdoSE#dEL;vtj(`@#9ZG;$9X`LjDm>yOtJZwjP>%yHS)qL*XE?~Q z1Tm{vF{Y zXwd;^d3#XI)VJ7bMpkqReF3(y$A_G$xC*DldDT`PaFkJUn;LXw#8R8Tg*ia(M&q8I z%x+mRwFwTFZ-3Pr%S%a^?KL)x2skhw$4Zen!juInnaAStS;X|Uyx)u!4HX|wO00pK zgqNw-m=HClC(M{hL!ZX<- zERphpW-hX>5^7e?i*O;_&7_$$6NTn+rpKobL>TYl$a^&S+zje48D^U;1J>ABacVD` zP0z{ZRPkFG8Kw;lH7Wut-WO^*rIDY0(82?W&t?2!AY#muTH2ag+Cn-qvheF12FAv^ z$gZm2t4UqJ`Yr=g$|ZLpydZIKZ_Xm*Z*Xu~5_uE%LPrZHrtuS%vs;jlo1Kf9-q7*I z@!;*)`;@5r+2tZ-)5S{y%X%Xvz&|t3uxx>GzIe|#tj|xd(a>?z2U|(std{;|z;p|* zl|!=5L>>iWKErwUh-~WICufXr=pT&l#kLwUKte8`a~JW@i=cCRVfut=UQmeF}(1;9ou}vAr%X)3I+#SKBKHxBptQNW4VkX;i?Q)^s7&)-8theE-7xj2F1>!LJACi()g&V zqTsxlJ2Ar>Agbg#jyh+Q8}L%`=!#K$AQoC?4#hjKm5p|wOOeUQ{#2pT+E zfZfqN@la6_@PKj_bF^D!Q~F=a<9}WP@+w_oy7u0&s42_}bCQyqpOR(grn2)4I~h;1 ztP2;6+Zh3`b;~6YA1d8DhH#}&L(#P+sv(y6XD{9_l$+#ZMZNuW`|306DKzRYKDvUi zlL<;%V)HoaARpdIuYhMaJTEK783}1NLq_Qt?+HogbOGsEHirXPzHZ#5LTo2!vZDEj z3~3sl9s%QBfai3XBeWQ#8GCHoz9h(*vH@xk+Cr$C81XmDa4`DfX%HswCvI0^-m9&t zdHCngpP`|lmyK&hDD6{1a6a#OTn4QK3yxTSxVre zxS6G@gyme8n7=p2hOw{e|A4Z(yt%fxwzFiszoM~ikm*>Jo=+?2(*9_XSEJ)&<6{$G zBWvhmW2h_Z0N@<}rglY7O9z0N`(DxA+|XB!3PPr8jqy7uc*|}skFIVn-vlIvo9A*D zS+yUfkw5_~e20Y5<1S^0uJT8vDX+=WkRV+%&;c{xBbs!Spw!2mxDNl`-~N9jonw4l z-`B-sOl;e>t;V)(v#}a9wmq@Urg75PZfrD-o2JoofBz?M@@A5`GoO3z*=O&yzN?pA zghP;hzS7&p*-ooB!`>0{W=17(p7JJ#oCN?KF`pqi4mnpvo9Rx$0P1k7^EYc&^Z*?=f0x4kRN$($q|vIRq+C!)#K5B`R&yx_rbC zD6E9Y(9w!>hHG7t8g`bE$JIu00)G#+l;IGBh8d=i02K3XL2f5p07_Dcm`ZZ%yj{JHR45I$)^{YpYb- z!C+N|ox@tG_sn&#=+Z*E38l_MW%*m3a*q4tu=G<3YJ2P`npS7J@yK2-ZoL?dqk0-J zECh=0dYD0V$ls=fZEkv@qOxaO`^L!+O@fUs#24uG*rj1#TeA03bhtBViFO?1tPL*3 zDF8ys_ktF6Nq~){XldNj+*e;-&9$_-wj{v0EG8<*E+8r_A^;?oIdB8PWda<+0=(Qn zcbZp_ol`h;b6)(~EJQWL)mGOwpdz7F$t3~6t<)=A)w}rF1C~1_GE*P`JrVgatk$P< zwPQ7Fz}(PLQJmvRda<9W;yN1R`l`;^m9>#|E;Ly@Y_FB>dRuTS>oi8ovZ)ctXk}w{ zxz4wiXB(j~uYj~X{k;%bzPL@v5$mt3hg0%mn4LJQg&Y1o!x@n@QV*1CSld^`FJHa@ zc<1aDf(XC`+q0lDs6W`0W$fx>-<{^~!(R81eDgOs&Jd{3{~4s#yT<&qfbblq{%q62 z5#cMYAE;1;g}p<)=A`VQGu@MUn{vi42cNzD0OK zZVHSoRMyf>%ZkOK>$isc9cekR?kpLN!H(R+IekkuR(Ed7QptVnR>6q<0Vix>b~Nf8Mk{XIme-7w z9>lcr>fW(R?1-3U(0f}?!RE?r@?ZD7(rU>uX+sRN#HHL)93<4?@OZJ(+GdW451|>3 zoiqj{s{Nyk;oYSM;?kSRefHdEdv8zQTGnj_``98cZ5bVZY-eh#AVu7st#EWn0-cc# zmoi@n9)jy0(vx)PAfg}_cEP&C%n^F@opC2BJw^-4<{Q24o|58|GC0}}AMJ=?M5Tz& zGYc|ooVSyiF~`>mG2F7-x%Iy8LdI_A9vlD0R!5GwN0!Bt!j!UGvt{{(_*rTFUkwd9 z6T`F0v&O~>Poj3Bv{ao(&1x))4-VWmBKN0Gqu2_Fy0tiio2@PuOIJJFzy?IOCGO8A z?IEUxX=K8x)a=hOm&@%id6@`fKNrJi9FhpwOXRIg8pB?lp(?OBsrfXV-=^UO53EJB zM@DE}&C)1Xpn_!e5$gFZG%ySxY!+%kZ9{v_cwt)8)rj{9e^7X;Go!QuJe?gil{JmM zErXN;9Jxa61Fg(l9Gn2XoVUHt|4@kT0hWG%>eLkpqRpr2TW}ZM98A)m&P4CwuT1~q zMww)VbdT>BTPSH%k)3569KAiA?SWC0d9Z_vf1pDk{)0_G!XNL>$0r|%AS;>rMoT$T zg+CCXHdY)?#BI{&j(5@;J6n}dKZ(L80Nr1x<9S8T@b=8hXIH4vDmop&$sW}Sky;-t*yW^$$!ss&_uW!3EiPID+H z@5|q4qHY*VX&x4&RBqwoJMq!7U>X(BTGY2*6{L=)i#9Ss{1KnG+MlU!Lmv(v8c2}e6UgXMW$_Bu;o}-c}hh)BU8gt z1%w6CemNiE{0bGxjuzDzSSb_>+vZ<1^80Q!Xw|Ad1zHG(Xn8{MwBqPzO25lq*c{!( z=T_P1d5uV0$<5lS_~IXt)nFLDn<%3uWKpNU!yX?IZ+^)Nj_RlfSw7X(!8Hp;C{YVR&sfU0p%)7TU0Of=+E}KRPx9YX9dr}lR$DaQh#EY z)?}!XA}>SWOyrh5{*5YKI*<%~IDC@bl9CGp7z^bVQckLp|4NrgVx)!k8c_cM+VH$j zBjO04@;FAO+KWq~np(~B^4~rSW{Ak*Z2oC%Nv;o1Yvp*ex<)-}!6jt}f%4Y!?%M9= z+Ul4!Q6Q{p**+kzZ21J55pt)d&apzc7OM#h!fJkGAQO$8C7gn#!jP|0#DqPF5CTl; z3GE4ExI}4)ZATPIc?$^}OLd;2*$8_#7@;&?B(SrS(izG9R0H%xY&g<5zi^ zGziOL^r&1lzG5@wnjThdP2GZ;`i7eNY6ts<>#NisA*E7xI!k}$#K>*@1AT2gtb81n zgL@EK^i8sH@yo8q8ylxx>sXx{Hi-;C<6Dk*L_oB+EWBZh;mH2%O6hmU7M`qMv(~P5 zBxJvcf4g2?s-p6(;%4F5j)(YLWJ^ZBe1rGrd=nwqh-&M1v@3Qr!W*`!l*Kza8cx)* z3~cM?G4B7?{ytLg_|333t`!R(s>WZCWT%Fn&9SOhqK}z*3@E4KP&B6+Mz+D$p zQq2)&q!#21VwRc%1XRO@xUYGJ0&#{)y$@xf)jyE(X&XdTMDXH;+HGO5Nm08IlA?^t zd-}?$GQ-@uDYciDXTN%@4JW4^V8(4DXmF-~ArwXBO!GAw)2*s=Pfq&62^R!NO|Y#& z6_!yZsR;8)1Dq>(X@K<6fwGwxJBI-WmKOKL^>7^gook_j0WIZ7k>ZaC`M+DMiEgBy z-(HCFgqUhCt8)$RHGw#ue4d`9=IO4>`2oLE7g?R`pFg8H>#5FrQYvy|dTJ&v7SChj zT8~d{73O9#3JjS=`i=a9zdyX{Y&?H&LHd!A^NR#zgIqo74Vo4Ie!%!$A{(^ zESw5ty;<2uP@NV>#{G5oU3t(6?sHFzIOVBS;{sydJnW+Wi+O7xPqSl&mEqz@4X=YL zlequ@5GTHV9r7xkM)lmSbtmL2)biRTmJw^Q@(yL#rR03N$-3eeI)f#a9v3Iaw71olIUa9g*lc0pwE8;P+nb!6AmRtnNXGk_&qz*Y891JZV{(?8>i~GxVp`PNwqMDzJ?FGrnANjp?q$aYMzz)7d>>ScLc?2^P(oj4jNf#W~_PvHP*x)5SvK zE8(r%sa)Srsuw57J)KM&2&G~Xv!XujRe|L-0cjGro@ymW%k8m?#Yd)>%PG$#VB%ZT zSoMKYIjgh4Tsx?cpGQ;)nXnf4zUX=q?Y+&+ z%)m?ZTlb2{3U{g7F{eW0-h;-DQC!~diQ^>x66W|wHnX5t%x;RPa!?Lxbbtn(i zBW^yUC!-g_(k#Yq)gHT3|6uB6nq`U$Uxg=)Syl7Z<0ye|Q+QAflCpGlH3c>-XXEdJ z(9hO9e01zvgdBSKt@#ob-)t@9R<(e3LFP)9iBnHt^ZDZQL*&83Gx$NEs;RuJslKe~ z&`4cY-rP1OP-Ou)QutQETP9Dfc1}+zytQx44#&2-7xEpABEh=w{V&z*lc5luLwU2W zgJ~>Hx0WuY6>^Gq;}W(9Z8w&D8}e-n`Io*Cp_la9=+Y>c0h059cX<-$A* zrLjjZUD{B0>_~g@BXcF?>gj-SkC;E1qpED=Wvd-K9H1spc+BjJ!K;}a^lWmASVmry zELlA~Uu$z|B4_aElNqfK7W-T*!uutaq5)r4Nywf; zfM`c@h|nSO8ev-} z4MOh$KJ`6k!?;;fjM}Vva3}qg;0>hT`5IMnU3C-R{AyREc;Z@K3rP;BO5BGTy;TOnJ&Tf>2oyNtWKjCxB8zrKE1 z+zAH4-HV167K|a-4%Mnhxp`@fkwv z|JvjQuF|7SW;8>^SG3C};e*m6gg?D%1$@)wM8o9UT+G`^T*>(<> zzm^O5V`d!9SN8NU6xb!wQ)L29Kv{eWx+hwLPy)diyTTRXHp&?c65HeFXl{5FWz}UC z`q`Xf%Xp@7k8xgi*hp{Bc!%18G=%O~M7COiSw==YEcIY5Pq4Qp%^bQs4<+r8qweYG z-O)?Txe7V#q0D>-@bWVukCQ=?EKGg*?KXiSA?2)^UL5K`y|7{horp2IJS?@55st8! zw5pgJx<=v|N{a&zEYLFPB5?+K3{>jS5IE}7b0m)@@;wwQQW@;cfa2ic{EY#zfw;1} zuDyU+?SseTu_CGmB93km6PyQ72uCad__J(6ptCY~jYZ*r2nR;@%!0|AQ~Nsy)K6UK zr7S6k8Pn$|`CT)0EG#U5odP%wv4ljEUo*F4;q<#7FgMmXcV!NP)0pgbC2 zIG012T~tMr5SL`kh>+#e*4|K~YIIw{sMG*V9u+-Wtr`aVx;@Q3d?9AS^tw8U>$78s{@;i*iSVCOo9Qe-pcVt_c;f;2>^rdk@v}Lq-Xn9 z#X@p%sjr`(lSe>AbWTKg28Ynm$@}Qlk)W^uod!S~#-gMD^{|?x=RwSBeg4eHJ_Tfk zcUzk&7Sh?XpE>=VfbyLR7ZMe6TRroEK0`xH`qGJj7693=wc7dX-znpFJss_=%(=c3 zymbX_+zB((6E41Ss%EnN!e44|y%mDC``@8SkFWt>4#%;y#y*)vxRG+pD?_wx9zL79 zis#T4w|1n5++4b@)+!&jR!ymy+LC>|;}~8Ivehg?>DX8nQWjf=@d4?rhW0s)OVa~f zv)*qE#V%RqBhuyyetpgKI-JQMvZ3F|-=|{fQh_`<=Sts|;`e0RaH$1Ei?y~Yc^x(e z0qYr~g8}I@umi>pQ=E~7oYK}rMyXxu&BmlCUv*xNn_a77GR%fK{>#Z3%J>(HM@SfyEJkp!Z=7Zro4s#xoYQLR4Cqit+SSQSGJ*SnE3jckE2nXqr(}_xH~RT#`B_`c zpZbgFb))KB)zQ9?|5cu}X#kU+Xn)*?1&%KjBh!Pfl}@lBrQ-8(6O)nv6E$G>{L+)% zBw-v%S2sVM!?W--7{kq8@UsN~TJj%1sK6-7B#8e!ca*YUJ)Hgr2UAa=Q1~xQ%ahki^8q67Sn#( z?Ca(4Z$+%fKY{{>tpFfm04*os@qIf-$*`xBiHl2slaB`uOh|A+aF*gcym;ON$S9;?*Wz8kD1uU^BS!|0Jb1(Zbq;)a!pVGaw{m4Q5S zQmdT@LhsyjKyS4#eooxUwqYFD7@g?fB8eVht=S>b5x8)dvC zmOSSqqf7|=o}=|++m>{yvOz?tofP1KSV+RAR@b?Z$}8>NIO3*T)BwjHNA- z>5Gw>l8rRASzUX3`{?Lsbv46@$BAo&^QLQt1iX~P*NRaXSQS)(68lEm4Hz@=$?!pj zJVdota&q3kPAOLP!P!qB|0k|&)VZE7~ZE>CnBxXbCn3|HA#o@a#tD@sLohvTh^>|51LDv_X zZ&r(`4&*Ogss5fY!-LR`G^$7f*-EhX_l>>{jNa84yiJQ*Mo`q0YRT4(f=ew$@!7W8 zzKTn-4+)?uNy=veTmqWvlhk}ka=w`I9)7j7;XV1Z$^qVVaZ%e7UW=&>%{G1t24LHk zBPrq?v1V-`Pf~1Y=-W|Y6^wWMCTo?P3j3y%n!pBYj4Z(VQ{zUboq5XiAvrE!>Vf`+FUw;j&X|s ztN>5AyvIMaOWLKpENLW<$M{@5&oZFn7NL&in0T`j+h0M3YelQz^Hz295i)~#iOcc1 zj8?~d=#b}!KE}6Js*VkBEM5z!nBW2ai7AJ~wBnPx7NL3d5$PIg%>Dll?V(r%%~|CP zoUYCs6X(_crZ+9Xs9H z!r0mS5AbUSW5@88uhYc>(<@wb1VVtlpUZu(C6r9=<`n|E!T^5&F%7B^rQkwKS=$>F zN=^>>S;wRy`4Urw+50x|V&t6%fQ=I%9x=-OeIvK4+~Jt~Q?@)nE09;7JdVWr;R-`& zc@}G?l7l-$lnEy9fp`)Y68hHJ+1b<6)6~Sy!7&&=d!&qKrl^Vta5qCIM%?`^S+=!| zl|>&?ywWTfhE+#kgxVlNbegp4HS`lgS-uz*!_Tl=2jon8;BnL>hq2=iYp9QDB&eI{ zOhL>;H9j~C5X$J2DuAk%M~S{^M#=BUtV<&=Zlu>x<&!ZBR zdiraFti*9^E9f3dj_Te6J%T~p0H?Q1OwP&K)!r@xzSLr|(8bQNn(XWff7O+i(Yv#q zTMbuam;my>x_yBzCaUc#q}2mv0$4%7?awWA)R7w|-80g_zfhO`gN3OJ^Fh{MXDgC> z2))*LVp(UScNZ5?yiwN6&M9YdD_^CndMg;2rRWdE@Q+k}8+}T?c+DEu9(iBY_3f6 zzV9V<_=OX=4X$1Qp0$GNe14+8xjsk6wp82K(Pmy8$Zf00JR?l&jIXg6&H(Djdh*)V zlqoJipqVXSCV**}N)kIHm1haKZ~hC5Ax3B(qWnQEhq6NXtS4cCNlg$VIZxb-q?GK7 zC4yZ-;vdOA%Q}jW#YsG1Sp5koUbg5z)rAYIiU_f;T%1JKkf#EJ+n8al+%#_=D5fH* zw)C{<$~6|@XG?$F1OzweMDMQ+X(WkmBy|4{>+~p91St{9vQ(y+}b~Bni+mr($Gwsn&7> zLYlD$Up#VUF?k@A<}s#M0fLfv0}y1ahIixW<%LZ_tJ7&$JeBR9g0<(2I5LR8b&i2qOxE(Sw&OTiq3D}J6qcUz00DWrVi*&;ojgEDO+93wou#fOFGFE;#ytg?4u;sbnH`y}9E7BB|j{63_ zuXlNxVa7&}9n2xm8js~j{z-PpwFu)Gf>}TYV2~ohc)8>KC=DLrrhj$eD*HD+;;+k6 zSA3;)J733TEF=?TW+KJ{TzSDnjL4xyHHB`&bjhMMr zQrTAeZJ`UcK^x4Q)hgYtV~mXuXf^v8niHNL-V(9dDW<@4xTtO zErK%8kBM-Cp%90usu8|MK9Nl^3l$yKOY_*9xvCDfS<%fpU zrq7fb1Z5RMDX_v3&q;0=AU$oMB)uRaL`fAr9jjF}9UU5$ zRK5`qLW-QRj6lNN*+pJ&hw7|`AAAQZL^Co!h9aANaVfZ&Ljcmb4!PW3G?7BjB~t+k z^So9uYf?dxiE&bMCBwU28|9G)c%}oBxQ>&k4sNySs)o{fARh=Aey?rstfTO0( zQ*Nj^z+I{5$#yO=<4=LCo){~ga4tyt?Di9T>_7Go#90-FV5m%cLlr?QBg($r4uYTF zbk8u329DYKD-!)8Vpt*BapgrzpJHa#o0LZ0~}p{~a^kb>zME z@1$ftzB|;{YelsLp|o!{i1BosWapO>V<|7(r&=CptWeh|{Q_JiddYuMajdY9ifO@z zXVX17eq}C_8vizEQ%A= zN;AsJGt;x&NOiKwymIJbOyY_T%wn>VDpNe;Dq_jMHcAt8tlJlgcy47q6lty3-eE!* zWGf`4ytql>XG}dHB-1mpzN8u${)A9uVX4=GgR+4lo!7-WQTd1>SfyFs2$exc8cU{g z#$yZPZ(sj_6!+Mo%$wof>s=FiQLqvtZDIMSVIHW?OE)$PK}x+)jG zs!NDq^Ue4DwLI<spU2QEHDe3vy88aI^<&*}PBcCm~l^NHV^}E+OXON1C zPwv+^oO}63hyMJ>x8l&#{;coO&x4E@ratQKTg?b&JYu%;fm?R%bhO` ztCL2-@FEep-`9o)1-aFp$&Zk$?|!|Fm)dwfa{>YUFZti+gtwk|sQD(8yAZixFrz}r z(aFb)&D6-N^`Jf>5LzXxTW)8VK39uLL_tuyklNuj&{s zT{o@zuin4!?C!j5Q9FO|U)vTu8qWFm?eYj;zlgrPz5Njl*zNK^rro8wvwRLnV!aE9 zlf|)BLeOSl(1x2$0TGO9zn2h0OhIry#QO=ik_*@|P=Fm;x zy_1p4OKO`@6-fwz(F&)Mz`XwUeYPe#tj*S?1IyPheOyJO?D0aHuANGaV3HS1fSmLb zv7Z~IWK7!dYbuqq>#r`4+aB{29}BuKtQ+n>DajX74_IWzZOkV&0TzPq1hFg|)d~Co;b=OR|HoyrHt1j~(d^t_v$vkVa9B91UZG zd53^9#4Rkli5w8Z=jFaOyV={=|Cez2Bo->$08jCBZ)k|Odv>ia!(d0-c>N=Vy z<81Q!TyJ=LZ^$ee{*+Kfnk1``kh%<)RUE71nl@tL2MVVN?RR{kf&4^?*#CNNKaEj# zzTuP402&4vfm`r2qNAepxs~*?AfrAJQV)R`f-$3~hw~FG{$@!_MEsUpBaa_}YmpnH zQQY@Xe|<@}k4}?ntRGy(QA?HZ7-tsEa|g>z)SOT%dhmdsu#$@TEz4G+pO|M3346%} zoFWCV%h?6u8$1`h4jBrpEf>i3TK~$Rc_f0mX`i34Qo{Q~6ji2Ke;W$Y5LdwPdl%$l z@+VcYd)V5)@MlWSrPI5rLNi02AbFL_4f94;!OB<+V}}h()ql9e+qyXE`KAwvmTS(T zAV~?k4klgwI;qcl+72Q6Qy2JUoQ^GcEZ`n)hx|^A#iTFrg|n!~#r5?&5PbUel;w?* zb^LvBRJQQeD8E=IDqc9|S98q@LkG(CsF_Ev@{~S`#y=Cb37&Kn1$hivmjl zLWI;9;Y-gEAIj~MoXt&C2Gtr8&R=-(Jb26r58v1i1b7?{(|^Te-!g3%ud@loV@6Y2 zw~{1qP!?+vn|ewiPfdmTC{OsXxAOC}OT`H4f2t&2OHA{TXV;py&pEi%=>R&$qf#%j zLU)&`p<#Ky7u)lmMDLKD5?%wRj3CXL3esF*;2OOuoh#3Re1@ycN0S(i)R8c#@qV=a z*hZjhmzq4$_&G=6)Mw`P%=wYO7m0+|%yV@-r@SwK9Dv=?h=j*x)E9`DWP~PsGw=mX zBq9X+m-W`dUt14gw?opgaXcKZ=@cFJSs zLp{(V98FASnQS{!EXX3LGHkgsN9$x3Gx_SlcPXnAkKB&}?cvhVMK zR}oe>{|NtBv=;Ta<$8vve!Bli-b0~;NizDUjgjSIywHf%+xz;g`OZS+r0?(f)p%;o z@ZU#FjbPlDy;)cu<4k2zPC%K=8K z;Xa%Nakeao*)=r-*3FCLbc_-9p6G3Q6LLpY{nVi>m6A@)#qKuevv5sw;&3Q|LMXIA z3E5bb$qEE9$V~kc8Kg?18Wz0zIo37(JsRtOMY86NEQHtxntlu1);Z4h>f{n(LD6w= zls|LKh|>G){Cqmp72x)?;%Hg$uE1K!q3%C>0^e|VXe~fLb<`oE%#}?`$BR3RIp9ZC z6=lvl65QS4U^#~~v8RU!yejy&M+Kne?4@AKz6pCxt~j=0xgZCIMxU|-iy4qPUj4f1 z_dDnUf6#@=HVhBPWwDZNcliw$O&p?7hL9hK_Q{S&Ws!EXn)Z7zSI3eMMrTmPMtEt;EMvoOfytSvs)cD!5e89 zfUSkB3YJkl7sjqmin8EIOm{Qr%tqRnr+m;i+EY?$_xHRB(EBz}Q&J+w{Dr;%<6OIF zIf1F{2njoB%5xQWp)r_HW3@GfhQL6}5Nx*-;t<9A@&ZpG-3F6ERGlOvJhnS2HYXR~ zqoI3TUhe4w^I9?QQPGSaWA~Zwq*wai^+yV|Kg609+_~(ECnKpC({@!}%4sZ6Kt}%< zSoZ~R-p%<5mHgW3rZs{E>2z>1g9{L?rx~WDAv5E7L8WbMD$Bj8$S&A3I*{mUW1kyw zBkdQQ4y&qDU<+|43*{*E`1faIsH{V&I%*-q*9Xit4pKw=GpzMUPD%ufPw1j6qC#@BW0R_e-z;@x`%Xv+D8S$EW)K zr^#rRph=v5)54;0rhwYjq18?FwA{v$Hlwzcz4P7Xc_M6=OOZ#b${$9c+ry&@ue|Vy z8R;J#!(j}e37a01oIe-A;&9dt&Miw^2k5G+$Y}-bk(!|{I;yUaQ-9P*T&^d{&fxGo1NBcbGuL zchmIfMhbkmW}pr^WpfKyrn|2?nVfk!J*}rt@wQTK=XMxoDe)xpNnBiGh(U%{&4oj< zA0};*vrjdm&q$XefU=vla4APpFg2nkwl!eibfF8!7haY4WA_8Q@I_Oz*De9GeWpj# zt?a5)lha;eW@UQ?KY!2eER;`$8utgkWd>_<;bJA#2OkOcj_;mEZ-a*6A8ZdF z-`xV48$WypKRhsAv`D-79v`7?zlgy??$1qKe$eTlERZ`6hkAqM8b9F)(L_XI9kzdF z&Q}m$--p+8)W9PeGy49?oqI-y8^J6uX%tsOm`0DE#7|KO{RKyfG^4~KoU?*E-NY(p za>5((fSRA4T{w=xVWRnpI+$8R$nly^krKo2&R4sfMA;A9nHv_QzmmukC4uqd{4Dtg z54u2Snm%p6Nd6)`b;L$YR(q%O7!mr&jjT{1CNftuKQ3*`yx5x0D-q+Cc1J__TI8*9^uSL-?Y z>|5L0D<1`daRneDjW;`(SKqOr!l+7CC+jA2v#(c|N2m29Z=wjoPUas&g*<&lRSrf9 z+HmScxd&UlKHfEFNN6l932$XhwrD&n^dJGv3n?+QYL5kurUL92MVPPSGp+J5LWF&lDQ~ujx()yd_+Uc5%#g35{Lv$?DXg|nWk7)*k)=7ZPD?Jw1+>?KU$ppaW9F3 zM+qP za2oTL2}Ba@$BOPkt@o!pg6o(Kycm;ym93jD(rN^{s%cPgZzp7c1+R^+$%^%AKiX=ryNiN=l zP4B?wgdvxdl4XsBtY^He=3VM`p+bP*E>7EF;9qR;DOQ4%h&l%qUPVyT9R9pmod_?$~#8*3y;`fHlIx?V?jj^Gks;Zj+rpt0VF#r<1{Su zc5)rKmLfOh$C}OA2yt+C(!)hK$y@zvA$bGad{-aID1M^5yvn9I{p#urf+e+}3|4cK z$2VdoghDSVp~4%52vv1}|AdA)wepqeYW}~=ia}_3v@|hvg{kWGAUD79^cS-MlI*ub zKHl)yOqSt%&?;WhqeMW41gO6(`S)UgA|&IKMa)TpD)=q<*+ie9RJF@1VbismVY(Z| zAR*Nmc|&1BztLM2I~~Rlq%$64f#I$MOQWK}M*dcY?}UE+KWgED*^dCqu^3*@Z zDD&}$&O4*t^+<&bf;i`78v?GsdEfi|()9Cft#M_LoHgCsy&ps*thS%Ft?`f9+|0Pf zofi^x#2#8yEA1{M9?v8VwkMQ~!y{D~fLnmN(Nh(oTW#9y_JQG2Y%i!F8UIuHx&Vbr z;1HHCBLr>VW4)1h=EgN(BlJj5tWPQBJ6x!s2u8mngg8OFb4S{)>c~CrukRx7;Y2F#D*BkcJE#hm zJbY3cS}`Ir6m)Nk+%V{D`I8peUZoK62s^|V2%wb3R1+dvBRz-{pR&$QtafXZhY07v zFh3{#mw#Ut)?04)BY!Zjv(DvZ7j-t7n!gMIQeZ7oqB+COR%W@F)A~F#VT1ZHN`-HB z^4QMJtxlSP&CtvulIjP<)MgnLbk1tbD9P9=Ke0Ba5`h)Xm?Cx zoh3M?F|pmbxAfZnNM}$gpvEmeQY!jKUHui&h1c_k*+S5D+3LGasr)i@S`SmFL2N2A zgLle+SARp8YmrSu@7sMC*BW(+JqH{Mnyz0DA}0R^9vw7h+<(SwHXmHI!6BP^sYW8o zEb6(i^dt8D({tVTVhOZHu93f+j>6xcvI##t&^>HRq_@Iuo?}=ce-5uN9 zUYSplsaO;9SG5s6DZ=cv^RK%`#lsDxmz9}3zRMsgi1*@4$hU=DSyDghKh?s#!6qg} z)Aw1f=l$PyyPo!cz6Y%M3AU&IJ=k~f^|q)6L!MJeEa;wjc}Pqk&Jhjf~F(yLY$ z>#HT(jaUV<$f8jy5ausd8JkEDL`r~z3+)M~1vD1{0TV1^%es`jPz{c|+D)!MLh{Ae z^fG8@++CwwNpWc`n)qhgGIk7+*STgBTS*Z5;FWxT%R0GuMq!&BRAjSv0nI+~ZfGZk zNnFlD7hIWsQohVBJN0?&y-P2@JC#wN&resZTUgQ_O&wO1MNimCs!8_5Zhj(1u=wGw zl021&%z~=Iih8R|jDrlZKJflu6%D@g>&Mfx7Eh9kI)NdkWLdF2%leUiie)~9^o&{J zl6E)Q4pxyx4ZJ_je?bFk^XQ_s*KzBsUHE-3Rt=Pk+GI-97S_b{IYIj~2+K za9`X%J_?vACFP;KqYzUNKiKJw=hAPEn%WOL1${`@5><8sZ3b09r_2%3JJb@{~yNbFaienBWwGYZwT zpq}C?V5+M$QPZ`Tnya~aKHswlC)_Xv9I${=dAq<5-e>>4kfr#Rocq!C1)HP zn!M^6mhJV7?C*qW;1PrB%h+1b$7#@h*3Q#_6x+)y+v{J|cP}N8x18(SA11evWbf*1 zJ-)u@Y47u7ez%oDCtQV(BV?~sY%lA0A%unIW1s=G*X{!6_Q6D=K@B7q@%8u#zAeJS z?><+I9n4PF>l9fJ>2>5a8ND=6y= z230iS)f6M^Wx-m{wnTXU%s~4%Z$U^-Hwq(cunJ=oU+t)8M`Hk^^R{zQDE?~1VgFlD z%xu2>2bBKtfSvp2-X(rH69<&eEKu6vtj}Hc1LDGoPP0)C2!>#|2gUCd>@aj;G#K@- z6}j%i<+P%k<+O@FGDo86bs9h4xT^JF(j{EI#S);#=vF?A}a7u7+ml zm=JJFqYPB}U}Py%3}_pI^arPsbt(O2T1xh>hkR!2l)`yfaiXj?w!BGcvKA64la+pEd`a zr0HXP+?+Zrr~hSOeKMn$G5@4vQ4m^8Z!8$#y!5u`cO^B;m`9rlb@R#DVb%S5)##9ujc*NKl`s`&Gx!40zw{a`;WhcoOy~~BlVvP z?Y_#G{^8kuAL|S}QT+JpxcfJg?R8P?DXsst^QQMP_d0NiX!mYuK=^Ru`ShZ-@bIU4 z2TWC56<0ys6zN(fAv5v%4C`6atJ#;DkIt`$ug~{uji&!~Q|f_DQeQ&tz4!IY)dw9I zU8_`cl(6Qjja&<4h6;!g`HdHveS$w+{^*AyS|r4? zDTQ!biZt$?+Mj@$7Bx7TTWx&hL5tXYgEk6zf^ez|etz?Xzb;DbD!{RMn8B)LOmMv@ zGUlM1D80jOf5AzO+2GWOyXpoHUxvx!fF^;nf-$a(y_HwMoGO=tMlw}SeLy12QH>us zrn^n1oKMIw^_xq^YUA133?{hAhcxEC|7%?EtR!GTy8rbjj!Ssnx4TrvvJ%jpR4^jJ z>OXMVn!d2?KIX0k&EbVSubBnhk*WGWRI5TmXzDg>`<|%>hkox2dH)lHW+E&cF8ueV zG`=L1W&`z*YpOY}!_OTgr4nkrSAvA*$Kwyx zy0_S&q@&MIbN8p6#HQY#{4zzoZa=l?X**sqOjQ_Tx4}VU(@rLt@vJZ`it77ZXvHp? zD-!v0saGB?PlG^P^#y4TNFU28(Jao>K6FR;u~83J;MK&&uW(<4oWs6AJ(09Q+x}fa z@@lM)Gq3RKcOV)bWsbu3&uCj)P0n@Y_0lM`5=u_+u>m?i($VhM0X`&Gwn0lH5vKu2+CCC`s_@3v^D$tG2piMzvI@* z^uy*%bq+U(Grrv5W-f@r4+25Ht{>H&pWcZRIe;*d33GVVeo3E?#sZ2Kq?jtw zE(Ka{>tj*$UDYuIcbWb$o$z=Cm-CkEeKD~BCB&>V{9q{F;Y!_* zdecs}XZ3j&SGjOTM#`D~u@+c~rVsM3=207==lSFL6Bz8?&2?Sx^FHr$&W%k~Q$V$sqS7!5JMiYD zU1c=+iFy8DyPPzJ>*6HUh{2KE3L#*kY;W4YA6F(Fsw$3uXxzLZA;4u);U0@JU{d=! z9hqV7r>>7D`vR;<1K1TQYr~5A0#nw2x(+E4SM0DMg`Y@#Dfuk%Hx76F@L*u@VF-Zv zys~*FG1=OKGX*)k4s#(yVkC+H`il+o?;^;;KbJvhikp;z+rPC}2>8`2xvR8szcGJw z%*)Oj%zf^x_5YO=yrUNM<3rG2=dQJ;TJ(&>-7#4HOwze)YW0%R(P|BbtqH>$YS%>orb@!r66BKH#t~!r>@VFX{LKf z5eH^Fy(9jkvQi2%V&@xFcO!j3ir{8o*M4rQTkep4zK|@`ny3nP9@VF@$mmryG!0we z>$BD_nW(6$Y{)h|eixe?-pf8%tib80m1_Kf_U=)sS-u}rvjjyMSU7K4m zzj^FJD00m)&Ta{N&eFh|a-Lo8gBru_?QP4OrS`zv3k8&;F>}^m$ZScH?9FtA>{ATf zy+ci`=)GV5dBn@Fv-J|V9C0Fmi^2uqBFIl^MBJxL+{8);=>mF6jYJj%AE#7EqxwA)1z)Ldxyzo- z>n*ll2Eo35LtoM8nYH<`994gL4d*y)tB^w-m|n_SJc1~zs(e#k|hVx6nCD3y6)Mo^yKW)R#gzo{O`q{wnQA^(bjVktW>f}RKLg0I-WHXzRQ>d$+ zVFfn2K7^WA6HMA{P5fuhJ%r-7nT-CDFMOAcQOmPfAu0yJ4 zz<25fLWEJ*w>gCGkhDZv*0DfVo%pTSrt<_4d|00PuvE@(d@=?GVzxPeMZynXmfG(p ztdBvmnQU=0Mm$_4Is~Cy@rBhOM)@!(eQywH6@IgfMvdqn1hGYQHhitgE#R+2z^HxK z!P&{-Q4;E_kPi}rN`S#vNnNO)Zuc0xlHlWfmHMIcPUwD%&F|;_%AH8TRaFvv$n$!4 z);r(`^9`DVOVSk{BPk!FhKV#8MQ36m?8Nyu{5WFbj|bhpJ#0h^Gl*B;TyTMe+}|OR?iEci|PCdA>{K!{q+42oMPQ%7aV4;ot;K84=IXE$%+2 zibvs*<(~~ZAPo`gEZvc@j7`1zoKbo=EzRj6>ob1=d5QVJn2}G1{aX5Q?M?1do5xC@ z#QkkchgRZEfSg*4*C%~Mpn{HqwZ@wBGsl~lsq|=3J8Oq<3!UAX44|;sZyuP2 z3&Jq$iNB&fLmX^cF%%q8g)}e2ix)EZ@rbCIpgYX6gfA>ltOAt3?ousZLFuAX3S_7- zP}d8$&|`p71Bewa^f$Qqy=8QjD|(?n$cXLx=7DC|1_agnX4^QXxbgELDbI|$!`3+C z^4?qGr#?ybgJLyUR7BU}pJJxhRr+)QN zY~0K4D80To74q2~h3^!pT|xg21@u;Q++_scK=nH44)jpx<2Q>h?{*)s`ki+!qr+JP z5u&im3-dciq3i1L`^$p++)G%*)wbD>;#H~wqQT;?!nHPCEH9lN7BWUt&5hN`kf$Z>l~AB{d|?Rh%A!mE52+59ows&gp~M@YdVxDiU#?JpF7dE`^_F4!{=Y zJ9|F&+eEc)m@T{ST(qiWt$@?(1P~$Yo6d((<3LJFG5gL-!eQKv)atRxXBeimsrXYP zJ80YzDjn6p!jIJ%8YK{GE~+p}J>N_dBFxv?d%#wcpP6mV?r)lZLBrR#O@4l2VT{NH zW>bGHr-y2Ar&QV{w7k+)uO*X6LH$$bac& zVXkN4yQlKD2693dUREsfq%k@yf^3Nl(KYadr<`=G2yYNpwJpGWUHvri_r25oZ44l= zYoK5yc3Xf}#1A&q&JJZhzgWtChK!yY-~Fpl%1CTKP8R+nA0ffsCV42SmjvFnx<7zx{4D=y>{_ zk59DbYJA{hii4Lv_Jl|`9>XK^w!$^g8Kl%H(1X^N3%?@wdTn0 zMa-~-8;8m54RP8ucKtw%QNU|FwQr zbPB&u!IZlXaUaYJ>fcIv3sHNK^U9k@*u0W#41_oL%T{6j9}%^=@>zBiP1aI4TrNh8 z^Ip_859c~~fBif?DkuF5*&$S)*(>G_=Zt%QNbZYh6fIKICwj_gD^JVBlsf)zc*D)L zfV9gJX5u+hvoQNb03BSs!f-0WFPF7_1P(kPdL$q4ayWGlRENtb*}EZloa7otr{hac zUlXF|tnm|Jfz=0c1g9XgZC#m?2B?Dn$}klZu}~QqrxgIg=E-x5-%K|(*+ za1@#mAT1hTYAAJY4Y2M;9ConmWxz1-pFb^c}x~B!N1e%PLmeZyZy<1@K5GA z^yCv42AySY_%#qF)bh=~85nnKW6YrDo)Ol(tZ#3*!!8%h+In6BNNH$)ozO`CT{=7A z9fc0GgwU+LfYd`*;p55$%ZCB+zuGYk&RJ#Qosxl*79?^8pe?cZF*AFqXDu;$#LpCf zolPtehBntaDPIHe4NDq(ncVM+@hc2eX?3AEi(cl~bA-5kDFWC=0Tf^roditO$Ae|dVbyGVn%xXd73|^Y`-b&1=vSZ zHCbfh59rc_PgyL{;`6I66h9?pnyL^hEIr45-AhDb|Im*Wt;F@He>*YloUt(9a-Mz@3ZJ=ZJ4(x#t}bd7~7jb8yO?y_yGmN4%=G+&jc{ zEiTL^?1%^(TgN%;SXTiZQvYMJSmVYaI;Q;a7{!%B`Qax|q_v1$@`g|25sx>BZBuL; z)68D&f8RS#{#ak{Fl0D~FVpxyg_EldE9>_PC;KZB!3G1o!d14XzzXBWLUlLOMuB}7 zQ$KyP%|BAx)#b__?$`c<$(i^=h+MiL8somtTRQu4BTC;|p9(iWK7!Pf$R`cd%4V}*c!9a< zF~BVcGV@ymWl!U`_o&A3)z2+WpN}^E&i+jQa$i@VczA`c==vqQHI*g~>A)*i z9;*as!JV5RmpN zd||;OLRUGYcCc``1bTHMgh=st3(iolFUy+%b|)aF6GaR<%DTm44gDIqLKWna<$C@oRgAa-M87`xtoLlDWV~Bvu!VaR#z}(P%$Td#UJqIjnOgU&Jj1*(c_uRV zuPaM&$a}}=1a`g}NL(ZrI9>$|BPM#<0ElY0C9?la#!6}cnGf&_%j~9rU5$PW9R5SH z@;LvhBLew&8I-@EvKu$vVg{Z2M6gcYBsNGNvbX!E?vS=^Q$v&BtNWbz&2h9LRE*R} znSDUm(SR@f3H1xZ56`LlewYetwLBxu(=ElaZpfSPicAQF*tm+837EuUA6HTtAV9!a zjqRCtV=F%#i7gbqM){?uKzF9oqqyvLF{4TA{#_9n(!4RJAz{?=x(JvXp-M#L-)+I$ z-IS6FN#*tRSXXVuNS&Gm=8&%I!^M_$kHch&wu%5{+)nA*2rrGEI){lwv($92Cn_bS zAj>)tW3yZ`qFkJ5eaPE{;Zg_OR2qLU9OW2A9K7(U!S z(0VNUZSvWayZ)mmsiS~5mW`sAzOcUe5l>)EUS`DDvaX+>tBR0_3W0M;kEI&xN+Q&I zf*eUU(hQ4~!3dXZT(h|?CKID_ngpn!@N?n!v@3Fz0%9x^x{s|H!0yX$#0&52Undc9}t4C2U@DczWP-O0%&l=uFrDddHy zbh&$TsC6?QT0Jz$;@49ZxPBAD2VLFnjSal%Lw4t{f?wz7DHhG>w3fmmGII_K$( zijrlU!&4P!*{53-ypWKGPe&bN6?J@~^8k0aKXm8WqX$Ch7rGPNuWyhG6mpRZqk3Pn zUzz3NSs%>DLNAhkzY`qk7_)6<@f%J_aB`2j$)DwPUj{Q$7$(9cT?-4d8KF~9objw! z(C$gGZ8tsaTaQy3CiF+n;v|84Tgfe;Ys)(lrOs-uZe#9~1*ZtpY4uU|n0;;8oS7j1 zi&DPqX_9@KB5#1z!20G3%Nb(sS>a_ZfPCsxF_GpKdVp5$OgA-obP;n=UO4TigiE$SFT@G#EU7DPFJLj>m>P` zvCgw?IW$w^^2K=KGD?U&O70@*LUwJX@19~la3!hryr9eai0j%Po8f1Qqp=dOmF7F_ z#mp;J*XiBRuI>E1ZE5tB8|EcSuYc$~fHVQ-JX*apV^>5z&gB}SCQUPr5p5`Dw?G6cMF&8x1xIf`F$k#{SR{pnlHv*x(Z}&ASw7X) z5KPz9v>|(y!=0AhJDoYqIpSdN(5w`qVgb>7V2p*RhC?Ku)`R$7H>ys?8(ApC%$E{6 z&ZKgRsAQ2Y#A`FE>naqyoov>x|D>bYi1q3MFY>3=4pG~N3T`*#u_IH&MOueslk4@R zLhbop=n-}Z(7rC96_t6cgqM&dV zHkhfHrhv&_%0NT7RYj!VeBjvGweB>kP~HI2u|MtPJeJLr`F#Du%bvg3#s@nE_QS3H2iVD8zK2_wcStq( zh1-SfNm5?t--)(cRv9#YZQJ?&(cJxnT!@r+{%u%^`HdV*ZgZgHD5J?07g>{6eM%Fl zyZdsgmxhe}UTn)I(>}0!avVLnv>iw)()nDoKS|$7IDg-yRyEZ ze2-S19$fL>gBQ%z5)~Nu8*6eW8VZ*g=n~o0y}KcLjH~-poUi$#! zkdBhW$rP8c>t3()TTyMQZB zc5bJVPGd31syKH!0k_x93vEVsPR2KQDB0*M|KHbVrkG*YjVy?V0&9hYv>Fdf< z>pLW&WGg&Yt(O|XckABhKWpaq59n5|3Xs7!{Nsm*{(8@@rX-j<|FRW)bI0@7*X@uT z72nE=qoKK6^gQuL{UR~HwEj_v$D`;ppol=X(u82x`agQ;&p z%T`#k&t{VCCv>l0rACPtPFsAzdIU7V`yX5KO}u{US?j=Jp*w9Kw)iATnH8R$P3?t+ z#t`?*{zB#jayO|+V$Sj%w^YEONAYr^GgDp0k(J)+#P39B)8=29?Npwyl02%S-{oc9 z@%Qf|zJS)40rQ?;INS_gY zb}D0s!OLU|$7lZ|&+%&^)I}c~>eiluylo?zO-{H>k*k`< z(z40dBk*>B2)PsseHBm2d36vzAGdPy`9UozG<401V9G+G*Q5b;yz{D%H1ypd3Fzlb zA|2NE0xLo{d27#5Th8|n>+k$!!%FgDRh!>qui_8FL}JeblUzdDuxQFiE8E*~Ksxr9 z3zQ}u$ND%tnoW zxxia(wGPW5$EGAt-7?m4TE%f*Vu1mo+|E)~3BnPrpWw1%sGrw;7PrnH1)^}p1%jtu z6dUDOd`6xtUrgxZob)Pvzw(|)%x}564A|Rl`N5fZf^kDZT;GdmA&R|lV{KjZX`3P} zM`SJ!g8vjeySZKgdmoi7N|1ir&hMn~J-PnS#pr!CM#EM*-Xi-wXMA}Ge!f!!|9K>h z`XL9uiiEeFRZ~p7@%*!hj1s&XXkocuJo0lwi^AWZG({Z*&wOCJKR;sbLV6!7zdIgS z34$F-S5WS4$lmVA-4!GStp$SvM&&w=6Wqc(&#>VIlV+x0u=b(O6-JT5khjJ%FoXA= z{}W#HqPAQ~!pe_3-kpW2c{Kk>8pvpVwX3yB#Ot&NaK@F?CUW2T@dP)qOg@1|dlJD? zfbXZ-kIy}Tr4@3Gv&1)5*JAhtd_F?V_nZ!&Vez5nSSBDV+fn>q=S9{{lzz>R$C;~K z#Jl`D&S$asWT0=W*wQH_f|LU(q&b_NkVU(p*8WTj8}l}GVkk$E3f>QbVRGvfy%%561_d6wa{fchQNd57G4+HcO78sfu47;u;2`UB zG8x+|ul+uA)jj|>I_BykYvEoYo;trJSt{Sn&}@5{y3^rkrW%`;!Z()t{Cy%+ zmhX?tf6Tk(LOl$2d3D>8kHXW8mDCkL((WM&1d8hSJL;=Cgas?`;#QYY1A^Rt(7k(Q?XMU4`_C#~nh6P_j z*?e|iqLDoxIz6_#)V%X=`g>;4S7qk+aG2a`iO7q*`mCxvjyF+SUp>BRSP{ax(`-?)PB+v9GQ!5toMsE&Yq-I^e~pA(HaS~x(Lbwzc)hKlN}#Trk+>A6f8}JtGThTfHe>% zkYS>^7z5LOZj6P)B#$P)1`V$P;g^TPv;JRY%3Z2Gr5!aK`p1j>VH4kkg%U98G4Md# z9}awx2H~3Sv@Xf*(a3`~mir)2X*bJ--sH>Z1{+RHgl^@y;A%38UYh7thu29HyaT;!PI|kVu@ZEp6pTLTN%8*LnG{3>M_%;>v-!^) zKDY}qq$Ey{D)3$Vyn=&X%Rzs>AHNZhiCcXIRnu@2#JF!=$wiiB(poy7Wjwvh@llXws|6 zATJ`zy1B~)U-`4Yc? z@OE7Se!uR0Pe3}_cANipmk#|K#dfDSNB8=y0dp33-ycM*Evuo5^6Wb<=fmUXvdK}? z-o3jUt6E*R#|gnCA!p{t32JiJdSfiFLldmGcaH+kXHm9+awny*#J0KKi{#Y(a!Fnp zw}C%p6x-OfN4&ju4g-q7cd7#9GA<5nQf1{JjWw-`WAlplkn}eT6OYe9aR_nXaW|b; zoj6|(=N+E0oe29&_FVj71ZS1KJu$Mh5%yh0th%#T)QQszJvJInKPTyyi-e>$}f1#TxTV*A#6 z#a;`8-;UP%?_0fDDU=?Vqf`&*HX67))=^t}ua`YhapwM*b#}DaLv_%pcbkT(-)LE% z0SRQ+jwgB7sg4@_#_g_Zu5JI46*Up;c>+e=EXTcWM?=kncHKHQR>$|&b{EHbW;?ca zT;bsoasCB&r+o#e3c9Ytp*fOX%rM^U=C8NK83LUy)Oy?`_jY#{eH8w(Gym_ESAmy@ zo%5u6_Y`J0kkDa&N^BbciWxxaTzgK zy^HNy*4IlXeDlR=BMk7_o)mikdQ1&<@ZPLv87@rsumW=#Ot&rTTJ0PFT9m#S`@EX5 zBaWaGKk^`}KsbmKL#gl5GEcrZV0cG9LHeOx1W_iva8~ppt(jd39zU5cX83T7MO%$T z&Z!2t;Gobk!h00f)h$X3_PnjUzj=tPt*gRQq57ivp%@if3A(SXgnv;Y>@&KNFJ`{eK-`}yJ+Z&=@P9WND3*KJM ztPGm=kgVL0(7}-(1OxVkSW*3M8}sC*>k+l+uW_~a4`mOZjW#T!ceaDwwsGYM^4s#d zre%wmUg|c7pUK_n zQQN8y_Yc}N^%ykzniSOvN?U(tt!w87kw}+U$k{nNG7GGG$J&V+=&yG+@xjP7y`=c) z6G1=C8&VYO+Id$N>QrNI{pfN zv|}H9c{d7I5S2d8eLn<3Stf0Ftxl~33@tx^52NmrZgVj;3p>63wns?nW*$^6J){0h4==8R~FA&;d zXkd0CevIK5I-moP4?)F;cRg!;cYziCogEdWpDB~({ihO1$*_MhiJ^O9j~khwDgCvxFuK(eqQU%8pLx+CR{h# zbN#j89ZD~NMjEUaAneT~=XQ_T;m0Z~BS`X4tmS!`e|P#5U zIk}YayFC&Jek}{97&Ec~Erc?t`qj<$@ORLKj)^m2mhI5}9jzd{teec$^Yi9bcLpkZ ze%IL^dzp%9&Z%KeV-$nGXU41*5H#B(8VaM?RJ`a@n#LYm?u%AgI{kSv!1Mu-)$`=-5z+-U0KpwY|9;u zTZxh{=QcJe+jadW5dQVj|EJJOnRko-Ce>WXmEpwBp78zhvtNt)?ic z`glouR<&z;e4(AIJ!<9dtr`IjPZH-2sploX(44orMNU<^+3Kek=Ln0z~Atn~cn zU;b;OW-i(O0uk`#Yk3UUQYr9_&w4U34+j3XYk=A14etSq8k2tm5G*>|{H#3x~qw^JMD(k83Vfs|CnqQesTQ?mmri z&4~iywf8^^bOJy}Q@mg4y&tJV_R_nKCm2&yP6jke1QP%G_il>uweJzX>Q{p<#@%|N zleX|F%kV{H8iv_YHY)mKIgK&^Q!XK<&iTK$O}EEh-5suU9Fxg?-xjb8SyeLyhPV=wNrcV2G;Zc0;7E+b9c2zhyHs=6Mz$b0N*K#_Pnx2?_m1Vrprm8 zo}WRehb!^hH6$x{7bL;EwXd#b%v+BI+~CJ_K~9&?*y6p@=7_!X@1<#|h)p-~W!x+k z>VKJ}?d1K93KrwW62s1l7^1%_L%y6Pu>bLoa!Si=0qra;1xiQX+{Tph`Ap;ui&Q;- z_-VAB-|@NCVIg7RX;?AGH_zj#cx`Y*j1#c>L(|h(8kP3x()f7;Lwc%EtP1wg542Qb z4pHQS*r^Isfzx(=pA(83ERKoGnyfQ>_yM{DhD^{%E{8cM@Cz{4fchiNkcac>$-f#) zT2$>An0E`g<6wm8RDcfl`jZR?C$&0Vj`GlqUO&tqavlOX4hY2tImODs|4!Sl>Ha-4 z;t7j|<%V(MLdG~35b5!?t9TC4A1VdT3*QrJ(_iH31#gwD_zYdkT?>HO&cFIJ_R4x< zxFV0klgpv$G5?^Q$=Xiq%f73EAQ)RP9J5|O`~z07l}oM**>ei!&Mh{xfW8%JPxoj5 z2G)w+;hV7Ce*_=>wY)9(`|xh_+8Ee47eqH zci5$tw0r@kgP+ME?hEOVsIGCzfQ^;*bBX1zx1pGn1&~uo-q-0j4<65|;pj<{HUC;I zmH#iQ;;hE6A)4={o80Pni>lurdML(C{oUaOm5)IUt4SEOg|p!%^KcB#Gn#&phv}_s ze%QOb0~XG9lkb3Ql08$KLoUyN9!DRa2*{Lv+7o}-4e(H{Bp9uFIMNI%0uMCcYlXu~ zCX!(`lC!|fkA^QzHr_Qlo)U z$77hP1qzwSeaeLy<*(5@90}3!;#+R`r3HZS8f@wxz12jSJmvuDhn;s!tr|t8pK{k>wCr1GR>d=3rQofV!_MPht6~Rt_UQSNg8Oao?4iu%G;baEd{Rr+ zgWwAtHMd)P;S2NAPkk--WAkTpabbXDOgAAB+}I1hf#zd?TSoXx_(%N0((0O)XEV@t zrpC`KrvvZ!js;+8QOneF;jI9mRfmjM5igZI7N*_oedg>4c zGFMTADn#0`2M!gqp=-r?7B9%oB@K3tNica@2@b@)1Pb)fQl=0oY5bD>adKRiUx`pl zuu6JkCyR5v?t<=gbL-pQ|M)UY^iGXV$P&4$6wwKYn|hK*TX(VU!}&F4W_@+9+%5go z#UARa_MfHELn4e!``C4P+w2a74uco2RiG>4YOm)#$NvcVt@50)j)MdC-Hw7LhJ0IZ z^V!0pN=pjvDx&007U;T8Z^xGd$Xc(Fzfc2N9&S9JV zQ3>jpgA=_e_w4RurTzHf%BZ(8&STUE@s|3UVBK*XjDK?Is7XidxYj5U_i7~_dyG3HB%uj~S+!k;#TE^s(&-M&xo!qt@SBh-E&7F{X3Y!6@6~Jhv zA<~WJDQofUQqBaW!9Pxm)GSkmA|$IQQUD`pQO4fw zRkwnS$LI}9R!pHwgm`=rtRW8OU0t5Lj1rVG*7~rEG1gaGN3KSky>+v%+Me~)9W)EQ zmi7KiyUa;En8TW~yE4zcwe!hR@b_RFzeEV{pJU>Bm*x`Bc9*Dr6Xs~+(8=_?8Fj84 zDa^vm95;tLTj&gOyX)w{O-S!zzEuG-srgFb(_!;f7IIR$eS1K~O{VJzm=zm< z;io)b5YO^VQ{<9?&{hsxQE($GjrwDHK_aBshAb(mUKUt?&bqospG?s^bCLp2CwL;0 zag^Qtr)ojsJId{UA38i~YWQc5v=M4{jh1*UUxa{J@f2dRz5lyem76@!D55xVBP#C;@{aC<#rvVCU^Ob4i(PU zpBNcPWSfh=L^1EmovyImU%9c|UttOqA&Q)d5WaoIg+AV?KmmbrXK?1bs@dzytz7@} zc^`A1-4CcFCF#9RlpFK?CZ_ZLP0@SwQ^d(rXrAiVdn&9iA;*hZVi`COA+&Rp&++IJ z5-_nkV5I<}DmUO^9=!F=|M%+SMlP;t$w@Ndm#OJR6QU5pQlaz)h#OEBFziMx zG{bG^>~0N5hyPAKRifD5X+c)@_J0_~;3s3WukWGN?F0D@00!yNM(LV<=d{h0-Y4IG zs~Ky#WJK{ZxE+M^NF^p0QJ;$c2@AT=+$-HUoXIy@6|nnGGm5MoIZ&LJ zulOs-CE&W+0$R3-Z9m;C5Epq)FQ13B*?Z_1!}C8&Ce{)Vcg9u$0{j72OpktimL^esJ?LqERU;*7>V1EU&Yv|0X z1Y6sbiM0qOcL%wU-5fZn(U>LJ*x6e?lMA|xC}_Vuzw8(0o1haq>P3g?Nqg@i+A3r& z7e!Ydyl8t{>AL^pS{&~^wBKsu{CL!`e{y}tQQM97OfXyyv)%5-l2^2=C1P(M+}*~I zmX_X~4ti-jDT$N&3-cK1M`Iq3L*u}a`xRk(F8cc@aYPZ!m!jUDEQ~REQdb4`-uR0@ zsFe_~acibg_qT|7LXB-vECYZblK*;X7BoHDnnp$|&RzKt&;fswAE>z6&0~_!1pX?= zygLTHYqH+<1B;M;kH@I-Rf?9x@I&^j=5^~FKIa)1k1-AoW{5Uf$6T!ez8X9B3)_79 zIV#IXDeLy?n=cxYA2UQB;K7^E{gIkJUSl_=IIsGFVROP?m_t+=%pg*bmel+itD$ku z=vf9$S?b%~1o@4A7(qmJ1}wTrCRR)ZvUaZYDDpM4^Wk&a(k;2Ye~Uxb?Jwq`QL%54 zGv~MLx#59-#tjsPt}R5rfWN$}GWa4>PB*~Vr)$aF^XPQL)`UlOLe#^PScpYN55WD7 zHow^@wW+nSM4bESfTdRI6B~^faUv49GJ%t+U^ZVUv`+i$67aQD3s;jW2QP7n%d2gy zvs~&-A0j^Mylvo<;fQ&okdic79qb4AUli7!U*%X5#TtdAyY2_5(b;RNGC`|fP#1}l|?CrG^to)kJWp4NL4lH6GX5YN|v%T^=Ks0>gXv3(AQI?2OROy16hkf7eBNEW5XpPGIEG za!Ctf*ZdJ<2+VKwGi=cy%9Z#8fB1iqK{YG_P352l0RiIDCQ+exEx&NhozMTFF z@azGiRe$OdQ~y7yLhWyNG)6clX-C}u-_W27*j2~VV7bX42`d@yz2<}* zl2E*6H|zW>k3k0p#B5M6|31}lM?Meslk5!cm+4~qpCd@3v!+!9o=Kg?%PKK){CLpdKz^GEXTuPWqlvg_2af5J+Q z6j5wLy!0rvDj2&Npduxc?+UmfHUn7cmRmT;Pq(Rtk{bWwc)=8~7Nd+`p4Wg^pbm5= zJ3F8B+*4s<9e<-=Od8~d%Ga88Te{p4wb(za!OCrPi0yFAqvNLpSU+is0^$<9+McX$ zcd&2~%qG1K+jnSeXjZvMd1E~}r|zWXZciLv?7&x|vTI2z1+Gr|=ND?NG89p&ExqX5+!EEsUT`U$< zZ?;7ImnqntG4r7yP;x|kl9jO!?vx12E~QHNOy< zeFHV0yWznvof!b=48)EysNQ_;q%`z;MPL|5;vpFBs<+<2Z}c!36C7&E;4%bgeY>kA zS$5Z7>5^+7`A7-XxXWIf+K>DxPRROIoUuw6 zTQ7)}+g_sb>uDd*pzwfK1!iDU%V@=ZB zUF0ICH=|@U1Q=1a*xdR5GxL!Iet4bBI6}+q8sDovA8!|%7vc53Zf(U_?~Uox&ze^q zFF1eDYyM*%g3(wx50|-bEVV8oqV8|mP26pjnX2_`+BytO)1TW5c%OZN7Inw#1IC&i z7(zc=egRJ5PBLB83 z*j8Oz*5jOIBVp$ShauIv%}^s(jWw5L+3ao$i!NPH6e)+?W z-*&|Irj5&qZRL{XBFuS<X>8ykzvaqMWgVfrz>?fTuZk@M6 zv?6>Byk419>6NY~3Z7}b(-*adID;Sf%Hx1#p*TG26tSFh8jI-zklX=c5Kup!=%4M4 zmoF6b&-O<2kuL@muA#$WKdp)}y-CfUxK*0d@$-6+8W+s zGI~=9?)CV2dIY;Mq@rE2)Ae_fg0d@6;iF8^ENudR;j_3l4NIrnmq6?dt=t~L^7Q{7 z*ImMHp-ryB_ZwtIri64|C(m0&?;gtp2|qE$e{H){!>OJ^_nh47(TDAA)9=N0!sR(8 zafn_%IM6!wvM}n@zv!*_#B>!iPvJ|{}74v(=OS)hwL1y3#l5~_Pxf74EC;*`H~ zzQ{dC(|G?K#qA6Z?LOj_9o`lY@``@xYEa<0lNkajnX}zYkr9#*`H2XIu_&hlw3V(ZV3Z$d~`$LKNAJnWnbt_AB_VjU}QinXp@&9~qT%#v+_M?h$ z&0>Sjm-9_zWjeS$;Z{mPflFamXTDn4m~9>IMsk+IFS{ZYyvA`a!-j!d*d@A>ODdOQ zKkaV!+Pq(yj{S>JEiDxvXyC?V)KKDhuk-LzXOPkBCIfdD6*V}YoF_Hai{pZDnfod~ z?c)#RTUvh!?OfF@wd_^p%q)VfBUEkmO@WI3pK9s73<>M-Y)O0ciSbE=J+ZKap&H5x z&v{cLe+kFPJOvD#9IcLoX1{sSuZ~ID!KOt_a{jOR8zFK+t0c{2y{gL{?oH5g1Ej=_ zn-Uq9mD+8Z;eF3rA*_43V31rNN+K*X#bOboY>Rtg^9D~xrMQqDtLlkyLxgC_mC_GyvQfx-?1Lb#D{BiPJ>`*P_T6Lqn-i?fBK2^sWR23 zuWxBii=l0D?0Q!-&SUlA60TUfYl^h&ILScqd`56am z1bjw5XXeULcs(Pp0nUwsVPc=u`-6Gkyg%1#+IkV_0$w(D_>f{~KD|?m2q`Xr_{@Fs z4u7;Tp^#(2@J}{}>WB~^WigTBLgtB1njI zj1r_JM+t(`Vc=+_TNoWmD;S9VJ$~-{y1)1L`u+HG7u(Ku?S0O9KVQ%1Vn z|IM{sX`8+2kVw!S)hwKGZ))%j&**G40+wkXBB%73qvrV!^tW%hk(t&$W;}Mm39@#) zr(MGUqCGE!F%L}Y=hB3|INB^XmQ=GQSl|{)NZB~>4#EVX7Gw^s!6mZQ73(I~Ix+Br z%fb-??X4;1Ht9IM4Nnh8NSn0#@oQv*K<}RMSX>SB$jZd)wki$3GY7jo-2$>Y93xjt z`m3e%1d6VP;yV?4lO5+dFR{<0SN$ljs|53k^0Yhka|!t@LnX)uUvV50{rt_|A9cGw zTSGr|Rtg;>FvMmyYsuZF)@l& z+7@Vj&s&0m7N^u61bU=MOv0ddsQ|MCN``?0esn@+S+6CFfygqX&q|Y8C+wpOv=Kp= ze!^W3uA0)0_xC;*aKGQ9;RhftxD-nsD`*P*ZgC%lb(7i^*XnvWsR3 z<}MHtpv%9UMexvtSFBNm^$`{ZDT}nz{6r5lf95v>EK8aTEgyd*&-ibI9@3d-w;Gyr zd&y>wJdl`){3)fCanaii4@L*%8aYW4&W+iodiokEQEi!9AgI4b>y-RFYzpA2d=_ZG z1-Vg_dwjpj<)wgW{5@`KO19l#RdK(E-e6P`{LBw0sgBWkyu@Z)-g>^!@1w#FONZT2 z9)mMc5QF93keZH>=>SV*$J`2nCoR1Qq>jga25`c4<0YS^^dGn(no8m>XF5^e@uXMz zi%z)^anNF6u5!CjD$%VZLbQktUNrWsO@IeL$C*EvA@yMNd4go1+|wH?wab{eHol(I zDx1r8AHl(*eCY|~drFpTQXhY$Rysq|oPe#tUv|K)f#-v_5O4f6c1qU+ua;hvNh9R> z@7-)6r%*%nIie`d86QC6XJGsFm8mva>n;jZ&5s(E`4i9{5+u+euVKp}xVT(>Jr~r; zW)9@Z$aV-Q2xdp#Z97DeI==8dC;e?q-9!mVP@mIMj+u|h-j-8Cl20u?OHUQBN1GED zt(EvFsQD-wZq2KB_#M8uJq@uDsfP858oEu(S+n&V7DZxzzPPRbRZWQl?fc z0nY-d@1&#O*5UT zgwF0~A3-=wSj&d$({?hiy&iw>$u}eA#z3{mxaryZe8)*{zjmG! zA$&X*tIa66gHk5Z8+3z%oUiU3mW2C1vov|w( zCoit8n+CzHj><5JK}%rq>c#?l6Z}sH)zC*Rh6o+wQ}FN5P4kUR#*8Y<2eu4)h@g5< z;$_s7!3UJ1Po!}g{G<}-jIQ%e7y?hI_>blKGYd{T`N0dB2$XW-^t3PAJzWG^LCuL# zv{A79*>3~^TYw$JPwV)P-zgCnU|k^Hy5cV(hbW`2v#$SPSx&kq_i5itwzXg{AciHckTcp+_VbrVHhKu{^>#=WHa`F5>> zB*W<1-0b)QHre9V75m%qUO;!yS%BMuqGCZ=&uyUG`8EkeHXhcq+vVX z4(A(@WAA%_umgVU{9j+he?9pgaaenz`c!J z_2ox5$|@zO&S<%Z zw)CgV<*EJGSiy-f8{OHl{1y;Q)w3}S3QJI1}80dzysz+G8y-3)$8syW&mlM z!1I)7{NG_S1RuzMfyy6$tM}x4wx{ApKU`zWnrLC?X7(C@Zi-MmU3o7E$O-_wBMBPI zBc6GMiS*r*pZo_HW_yj!Sk_{U*Kb*e@5m~kY(D&4S{@~S9lTUc+o)Ag)4O0!+?$@c zfczIo<3>9NmPs~Wz42Wz=)U>1ezc4si922%>Uym;pFVsk-QzJCnsY$TbaUMscc4Ap z8@hYUN?lJSdKrPj_NLXQ9tq(*@uCb%j1phK_J+KXukGzrF9FOyG+hRC@##O_9;aU$ z`)l6{v{RG$4HcWS3`H>G?BO5NXg1zz3HI2Q9R0WCQPXNu7+ zR-`X`Gn0wsxAYSWfXJICxM!{4Y0nc2iVk_8ZNQD~Fe7V;EU!&6rpHM(yAmo@D;~+C zyi}YN_%Hmi&w8rqzm z#elv?#h8b5qY0D{o4HHN2PWrk5!R#3AvdWc<~9IQ!4~39<3>N>HOv0W`_CT?p@!{> z(NZp|yYS#(Lmq0or|qKSUg3{Ufps{a9>ciXb@rUySXQ&&Pgk`D{x7PBw6Zf_sk7nc zarxkA#9NDJzIu(7P<<3_WAYNf$t8`>(cmYLE9!i&03 z>D2^R8Apdgw)En}Q4_Vr3VRkjQ^>+BGECWJ9E-9;C+M?kr_DSwPEW>AP5ELYS*k>a zqq+_FnGU!1?;?S4ThL#1=+|yXedZDAnC90vNZo}Tude4pH$6-JE>~=x%-(z{E>2uv zE0_n$Vm>}pt-hbAviwQTg}1MbxQHgz^&eYv3lV4Hm}B3Jm#OmNTnza&d>O&FVt_sm zC^gq={E|aCYn~cR9L3M(PS5m%lV?JgXL_S@_^q%N84#h;yb0%Jy6(Y?-wIYRs@D~j zxMLu%8O$vn`%w&XT->c1@bvn#;KMVW4Dzy$=*N z`IB~zsqSCAS7mcr?POzn$+TJ%vr?+(86FOB^c$_}q~mi`(ogcW(M8J1iOKuHBXjB2 zhhXvMaVarID4QM6G_w((skV?VPWx-V@XO*c6#i=S+r##%32^Q-S`74*JWDWHjPri> zd@!M%jRw3BY>#N7UA-aBcF!0goep!;yv9SG`|{CW7zhK48v~VNht5N^Hi)cmLlD4! z<~{ii)Y|+&=XkahCo8u-kaA>kv%@iBjK;sQDKhbI0x7HiL;A2@GIR}()yA<<1v94& zmALRd?K>-+M6lPW3HgE?fnWL1_pcnMjcxaSgH*ElzFtkOalY4GwPJI_qI#;p*S4Cn z9%~red-cJic-34`MoBQk{TlqIeMY$(W&3pa)(NJ+_-TMTEdz~M&Ui%4eM2 z()p+UB@Y-`BCKFojo~5CJ5%-(1x^0;hocEsPQ4<*kzd#dn}$J{)cy%TH9PK6#ZPd^ zpf{)o!ZJ}MWY`BS220JJ5vME%xuxhEoYcgVi2+F&oblie{L0F3AuYcg#b0s6qvutO z)P=5}fNkP7l|4h>Si5LmsZ@nej?Vl#3=$T@Y1E@wMWQ`nR}P3X+!?5upb8+!aG-dd zoy~abmqCx8#hhL=46pXoH}&7F4OY1?4#b3xr_)6>RTgksbbqL;j4E6a4Jt0QCl-9R zt}OVPR2zL@;=8=ztCc_75&P68@Mcw+3Pmc-&6|mjRN%QmN?FGMYL`rkVNRl|q$6rt z*4x3nOt`X$Akd(kx&TBFK=$nQWscqR?M-er5b)5^u{Go2nJpsphMyTku(w&o56hFr zy{H>V9}JQ^WU9Nr$tC!|=7-OpSb@`c)~ey0P8C-SNE9Nj&YhwSjZ=|TFm4p57j7Os zxfS5XW=r0y!xMC?M$v?Rv_hcql&Lt#+tXFinHz}rSoWbYgJV8q_h+sSHKQ&^PP@(( z62(XKBvm0-GO!@z|2M4qzVI(98S)C=jok3J=Y>TBWQzPF3L zE}1x8sZJfz%kKcrL zdCpXdrDS8T7kQ}~iN}f2{$UYko^U^ms|`Vs*)2XFT2NrK^8$(SeoxyTAKF zd)ZeO<_i%=bRVpD+{Ne8sZHBpPN#5}K#AhW4KB;{Fi@j|UQk;i*F9j6)}S7?LpTdItE=SOk5tJn=!<0t7u zp^1&NVQ0MO&jnV?Ng`Wk*2>gtIoZC^D!RQBd@(bwt-(yYhOEO=@~0a0D4GuiyMBBg zI;ue%y-bOoj6wR32@Q@=2*Ix&B0vrn)s)CGs_`33o&R%)bLQ zo9)(K70ZskzftaLAg?qQNs8w&@VYg4BcF-;GjMBi@=)i`POh8Bho7H+AtN_kTUmn) zd+6u^kVkiUXWg0pr#QpqHNgEl;K-}q2{*KYzX)rfzSKOm5u^7^D|)Q0fD`N;nvNTq z_!5j)-V?|E#I`@EUzo61etqm~MgTA$Xb*#D>QS5k4MgN>{ONxAY9@ey?EDnmt9lzz z*ldZbZ?x{aU)@;JXv4QYKxdZR8gTkm>xAVMsJ9d>qI)gcWy}^=^DHp1on)Y144P#n z4$cic=w{ssUnx>hE9O?gVNL!-*cTZ=Yz`i5d08a-8TTh zIme#-kxVbm%V@4^o|-O~wYR*0ElM6>CoFl;8{lTN9 zl)+T_fdVKIl(D~`Vbh_b8PTo$yMzT6_EmSsAmyK8qp!7@Ro{G6%xQt6S%1q_Q;}S; zWbI)}w?v4~z0qak{gFuos;H>T74zr8UsZQyl#@`hl_OMzO{{a+UV_U$K3O z=ie4qx8DbR)OMpfIpBh!Hk~M}S+zI$R8*EF(_v^eC^(TbJ^|*DB~r;Wn*vBu zqYBcbvVQ;gEV%lITdLk14sw5U634!|D&kvyW`vY6x5K=F%W%W zQe(SoGW^7AGIFDKl0KAv=ai=OJ6yH4lo#8$$zpdW%>4ZuFw9gDLq>ETxnCnT0KX&h zE(#W2p$Taduj-q*jM=$dUM#c3OcgIMixvlfC%`6ksjyBMmE!1MLzFRAOZljZxJcgv zYHUxQsgnL8&`xn;|IowDRA(e8Sl@V&=sQ@8JPXJ7&9=oZZ9tA-L%_=1cm5RCPD`e7 zoc#6Gm#NwJJ$IjIq((ol4`%1S9lI@UqdL0{>)W~x)zBr4+bQ=LY~m)uRctQ5_4~oi z>Ufh6=G%xFo?J zoY)K3;uJgJf3GIK0Lph<raG94W@Yaqkq{oR3KObD(mE{+3=#D&{Y3mz( zQg!~# zyM@fB^EK%rh*GdRbHvD&{a^g30*JpWHL;z;@k=i%q2Y^@b?nOxEaE_fef*e~wGoAo zYkVQM!hF;gY|U9oauT(66-ObGV8n&sL31kvG081;dD_1_P!}=BrSi0BfjN=SYQh^~ zJN76odtsu==Tb{?{_P09Bw~m7_jlLs{#m6iQQ7F&kRa4}(f-`%l@t7452Y?z-F(Qu zez%jO{4!9xVNS>N9P9r;JKU2gUs>Z+%bd05huZcen49rx$2OA6^4T_N$)T*F-?Rl4ZIE> zDLr241Zr8-e>-$sh*T?KX>{w~PEsnh{oE+Bna{#-na`A6IlDS)YlxWor|08$G+<0OeWiG`-shD8wWbDs4#iS;(!zI!)Wf#hY<|bJqeqZZ72&@~k&P$}3IS z!O2rs9`Gyy6Z_#2iV(vKFo6bB$_CF3>A0_aI*9t)D zTl#`6?Aj`t=^7its;k~f*S;F6S4=47cK&Q@YXPkiRq>Pq@mo{w_RAn`2n zkvm(n)E~HL2}{ZFgG(hwLMKBy2E5gdwA|`&9Ua|8$uT751@N?RYW?m-NRhlr^qPk0 zLl(O*_GS(Iw87^_)12$3UT4c*^nqG--1nx@)loECRI-vvyg{1AJyW%BUT=wfa6%o& zNnY$X|FHQj74Recy}1MW=YG2y_4fau0mSyCnkPQlG{S%V^`r(Gztum`d)NB!W|*!2 zp;hl+!7m+ty$Z)CZ&ET+4}ejk@75BlF4&p_&@p?WP`bSE*Q-G}`wGfXV3SAMaKeq; z{<1)UH)teJb)-MAaEQPOX8)L)prC+rx5hj|o5+tICz=T+f7RH6L*3051wLu3TjVx* z))!^dSa(6j!II62ZCb)}YpdTd@dRQ!j zMr?1TG9-Xeiq^J=MaTU1FXEn4bU;2>uNHw<{7C+7OI|wD0>gLje=Yxt?B?9Yp$v~` zZ$FiHe}7kGkU8FtUH8TAr(Z`eb6OV4kgSNVTTY52xB(mf7O412dVzR2o49*hK`{PV z3J%2wfjwym+x+oj7}dvXXO6SxH)N$mbC-OydKz_#*xa4ixW2U}6Z4wpXW$?6P~Vm3 zl6!RxC9rJ@6~o`>((Sqt^Hw}rML7a}j>>rLaXH>C!*gFKg$d>Z>ubr^jO;F{R zDL>HdeK5U7f0dJ_gerjrIkh}+3$j0GS!Cn&ZLB=oEAJGixp(1302(&c$z3vb`%I1c8fcNB zu(@2Nl!w_*l>jThQTGu+yw|?aZt%Go$i;)^#-IG&FJ_NFHd?_}ic{FH>(D|5;OAG| zC^F1W5TLca9v8bw>lFt_f5Vs7x13OnuhvAhx1A38FCb636W_eu{X~q7SJW;}_E!kS zowtv$@am-hx=VSoe5NcEjZZPb^6OBZaq6=qX^~s=I*ePMI9Jig#>QBI(reQS!R;Hc zZ-C1!wpL}a$Q+?7VST=XKIWc<216EG8j8zKjy8Nh%7{`oSJHlfeQTYo6Dy{EzVXPZ zX|9(+XCA6hIYgg5fvl86H(Jb-awtdwaAm5xb{I1pWQA~*UZyjoG-Y!T+#Bm%Tb&57 zLSNPO-=10ZCL%&a8R_F?n0kDVryP9r>QBbNFWCJ95g}os+^&WysG2i+j`$sN7J__P zHP}YS#3sq~p>q_HZR@X@7VuVvs2b(MXis=a$Uc)z`y(mD1s0Mc7RM{nb~z5Se_D0N8<^Z3yhU+{@~&A?jMpe*o0WD#18>4SI-7 zy}BlH#7&FDCCdXUsz`3J2`M2WQi~N2V()nT)J|34r!B#obJiT(Plq=jOVP!9q+ODS z+1Qy;6WJt2M$|IQFH-?Dd~HEn#O;!fNC7>eQhzU+jxhX|cu_Qk8f39(l{ zRU!2f)$sYjlS}V?QU;@9o4Y+r-kO1*p~@lgGT5@xodG({L^jqGYQGvX9s1A3*NcwR z7g&FXZ!P6zvaw?!l+*4z$IU;IYsxnqow`oylxgv>rXDEc zE(mTjc+wa}&dlQ2^UbvmI@*#>`+X_9QsoTSxz!?MpEUdNoTfVq= zEl6LQo<`yGlwK6CSvgW>Cb3laYGT;MR+!973|znNCe5N+vsjh4XwZa6gk-|W9J8Ul zX#xgJ9!o@EO4`d>ha9k~Id_(!3D|Eiw%^gcuyM{YPTMe9{!{sw58zo?8V@O+FIqWPC+TR&i&EhNkjbc6(lgIWvpOzj z*HoXVkZgK6)E%0pskne=DI7O6{Cylh#oTN1v_N6#e+;Rm%(l?3Ckr1Q8W(v7$MuGf zq)7Nn7kZdPzcZ7^?bgc2p8?QRq)V|5m>a2Ju>F3&p~gDjV#wIA-j{&tW5ab=35IbP5iuE!#Yt z@9m?KD7>#;U5t5H1R`SFaL8%|4CH4vl6)&#_GCXh+~r82b`AGx=7|4 z`_JHbtvyDvalG+eV?^%FTZ>94KQ>5P4mdw63J?pO%s<6y1NGEpCj#KRg+MVlopfHD zU+LN8jm2ezhPf#jeN3N|3{|qqdja$acO%4OI$hj3Jy=z)s;#1GAzR$h$tVSs3`b|9 zhwUY8vVxk6wO)g?cklP6>6Zxi&f5GYc;@~n_2nnEb3^}{FahU?Mp2?r+~d~r+o|Ob zY*_7WVaZ@ASi4nj!gNB78{H(bXNgosIm3C=oz4)Pi{?@};=~{S%f5cUPcAjeR%swl zi>UcAbrEol0A;09QQz!OK2ewLa{60ihkH9awo~n(PVoQO<^#vnur2D>YpEHZiED73 z+HRI%!^|up4GT+BklSY)#akQN<}G4NHP@BygnWr5eE0V;TY#kXT;>#CYSHp~$z5OD zYyw*-%gfiUNSb>Heo8SQK5Z7kL#gC?Ly10CPxMGi%$7FwWG%#1kNA6-${%O^AjwBM zjDNAK$UQHt>)toy-U2Ptrn1~Yz*`Jm(C5QieO@Z44l6kypQq1#!A&<-2%0&ldZ(i$ z3I!w!{-bN_RGqYF_Ik1^Sh8n<(8!41ETzgmJ|2d-fQeeIv0canCq&Y8y7Im& zOi06Iy5^$)+BQCtP>ViO7NX4apiqAN zSpw$lgg6(l^_8OwIOC@LJet0ZG_jqvwMiNkkE+5Z-b*7~ROP(#PoA(|6|(YTb(M zpcK0H6#m(5Os0+01J}X6W(v$uGLu8NCX=ac>&VT&9Xth~WCgTdxhWRoq1V; zSmvk^U(^C-pN^4F5YxNw7VwkMnr~pmrvL`nPFk75sR{3ReV0!;i^!PtaOLFOZB%er zl^)^=ZYkYo6keUW!P1gpYtVv=}z=pG>nl&T^bLQzT2s(JyMhfxr5G3 z3ZIUjCAVSU!Ww5+0yk@LWx_a@<>+5RGqB3{q*Fam8cXz%O0SbJ9qb#lHB8?sqBrGH z9^z12RZ|SZ3QYLe;u<+@x;)YCj`BWc;iH}Ez(>cM74YU%kQ|Npzs&UDD#C4RVGn#Y zlF_tg<3e}uk00-UM;J{|iM!sKZnn8IMrbj@$kiA%P6isTch{@3_VNx)u-?^r3+%-G z%xy&=5*anVDKWJPzTkeRNBDP3N$S^&oGMG7sk55T*$P?7PEd|seg1rTO=9Z?#mC5E6vn#g9f{VcI1&YU(^reVbVsFI zIH^f)j!9EMa4#uiQ=shu+)%?30cEZLB$1u8}sE2p4~)KtyZpA1fWZU!O*nw;?^0*f1LI! z{IOdbAGT6v`zjx4tN+^So@(c8nIW*YXk|7$;TX(&OVBcgF@fdS?wNsm(1lotX+ZE> z0Hac`Nk^SYn}4$JkHXhV{xFNPRw@RqIPdxd|5cC)w-;+J=T*e;!B(?SRZeJtQ|6xT zC*P>;I--9#!bCT&tDWsresC80@@kHvNv#0W+fpvqsNzQ*6DH3#qjsChcBrbQ$& zMh8S4FMIHl><+=Y|5VOr6ece1?;TzIKKqh3ro`@`{}N2`y(brBu62HWRN-c#*OP+P9ivSB%K zb;{+zyl7(LdcxFJ+EQ8TQ+`%6|M!~>a4B%-OjJ^@bC$E~*hnzp^#w5eu_$rgIfgx; zQ1$BXu8aHQs9B1{qR%w(0AuTC1VcBvT)6RwFtyn3=`U?b9F)(_xlQdoO6a-2Iw?^J zt(?{ACqs%XZ;qW;5^JYPgx4;@)jVW!UU#yzMNd9U-Q<~I7ZkzyP${K+Jyhe0SQB}h z4q=*P%tR@JrJN?5=|);T)3le9CGNR;rL=d0Ozhd2lto@@Imy~V1ubg|W7;?5eHi02 zOkc1!R`#>DJIIxj=LH^zGD!A@(5T4J;(qZrZP><1;H?V}IT&Ob;_)K;MbKWOhcjPd zL^7-+c(P^k1BmYnK1cj&4OaD_Yn=MoY?WN;Bw3Y0Wale(zTP5^6}cGgL8OkKwA&4e z(O;Qiu3*A%eL|IH`z=(D#s+gx8OZ#WhSF`wRT0aXN`UD(YpBgb7_~KMjEm(>ZlQ-X z8HCDf#bku8O>5s$nTmkmjrp`Gdq~b#nD4;nivc;p8e4S!9*=WIYv)cXe9`cVo3Vj} z;ji~yY%vPf{R3dxmc`=Uvqm4fr!%bKcPPn+1|!>m80kN1cu2 dataMap = new MultiMap(); + dataMap.add(SERVICE_TYPE, serviceExecuting.get()); + proxy.get(serviceExecutionStateAPI, Optional.of(dataMap), this); } @Override diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 1da0d07d05beb..a748006b2afbc 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -87,7 +87,6 @@ public class VehicleHandler extends VehicleChannelHandler { private boolean isElectric = false; private boolean isHybrid = false; - private Position currentPosition = new Position(); private ImageProperties imageProperties = new ImageProperties(); StringResponseCallback vehicleStatusCallback = new VehicleStatusCallback(); @@ -281,25 +280,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { } } - /** - * URLs taken from https://github.com/bimmerconnected/bimmer_connected/blob/master/bimmer_connected/const.py - * - * """URLs for different services and error code mapping.""" - * - * AUTH_URL = 'https://customer.bmwgroup.com/{gcdm_oauth_endpoint}/authenticate' - * AUTH_URL_LEGACY = 'https://{server}/gcdm/oauth/token' - * BASE_URL = 'https://{server}/webapi/v1' - * - * VEHICLES_URL = BASE_URL + '/user/vehicles' - * VEHICLE_VIN_URL = VEHICLES_URL + '/{vin}' - * VEHICLE_STATUS_URL = VEHICLE_VIN_URL + '/status' - * REMOTE_SERVICE_STATUS_URL = VEHICLE_VIN_URL + '/serviceExecutionStatus?serviceType={service_type}' - * REMOTE_SERVICE_URL = VEHICLE_VIN_URL + "/executeService" - * VEHICLE_IMAGE_URL = VEHICLE_VIN_URL + "/image?width={width}&height={height}&view={view}" - * VEHICLE_POI_URL = VEHICLE_VIN_URL + '/sendpoi' - * - * } - */ @Override public void initialize() { updateStatus(ThingStatus.UNKNOWN); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_de.properties b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_de.properties index 5626cb0ad3c26..f41df79e09c98 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_de.properties +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_de.properties @@ -130,7 +130,7 @@ channel-type.bmwconnecteddrive.doors-channel.label = Zustand der T channel-type.bmwconnecteddrive.windows-channel.label = Zustand der Fenster channel-type.bmwconnecteddrive.lock-channel.label = Fahrzeug Abgeschlossen channel-type.bmwconnecteddrive.service-date-channel.label = Nächstes Service Datum -channel-type.bmwconnecteddrive.service-milegae-channel.label = Nächster Service bei Kilometer +channel-type.bmwconnecteddrive.service-mileage-channel.label = Nächster Service in Kilometern channel-type.bmwconnecteddrive.service-name-channel.label = Nächster Service channel-type.bmwconnecteddrive.check-control-channel.label = Aktuelle Warnung channel-type.bmwconnecteddrive.charging-status-channel.label = Ladezustand @@ -185,13 +185,13 @@ channel-type.bmwconnecteddrive.remote-light-channel.label = Lichthupe Ausf channel-type.bmwconnecteddrive.remote-finder-channel.label = Fahrzeug Lokalisieren channel-type.bmwconnecteddrive.remote-lock-channel.label = Fahrzeug Abschließen channel-type.bmwconnecteddrive.remote-unlock-channel.label = Fahrzug Aufschließen -channel-type.bmwconnecteddrive.remote-horn-channel.label = Hupen Aktivieren +channel-type.bmwconnecteddrive.remote-horn-channel.label = Hupe Aktivieren channel-type.bmwconnecteddrive.remote-climate-channel.label = Klimatisierung Ausführen channel-type.bmwconnecteddrive.remote-state-channel.label = Ausführungszustand channel-type.bmwconnecteddrive.png-channel.label = Fahrzeug Bild channel-type.bmwconnecteddrive.image-view-channel.label = Fahrzeug Ansicht -channel-type.bmwconnecteddrive.image-size-channel.label = Fahrzeug Bildgöße +channel-type.bmwconnecteddrive.image-size-channel.label = Fahrzeug Bildgröße channel-type.bmwconnecteddrive.vehicle-fingerprint-channel.label = Fahrzeug Fingerabdruck channel-type.bmwconnecteddrive.discovery-fingerprint-channel.label = Portal Fingerabdruck diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml index 513311646a165..ded92c5578250 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/bridge-connected-drive.xml @@ -24,7 +24,7 @@ - Select your Region in order to connect to the appropriate BMW Server + Select Region in order to connect to the appropriate BMW Server diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-group.xml index cbf4fed4966c5..c50b50633cda5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-range-channel-group.xml @@ -3,7 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - + Provides Mileage, remaining range and charge level values diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml index 32c7838a9b8df..050a67914596e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/image-channel-types.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> Image - + String diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml index 5e4c7e2219dca..5f99028879ded 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml @@ -14,7 +14,7 @@ - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml index 694995c4e4538..68d702fbc8447 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml @@ -14,7 +14,7 @@ - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java index 15c79c83f55f6..1c216afa01ec9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java @@ -14,15 +14,11 @@ import static org.junit.Assert.*; -import java.nio.charset.Charset; import java.util.Locale; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jetty.util.MultiMap; -import org.eclipse.jetty.util.UrlEncoded; import org.junit.Test; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants; -import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Position; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; @@ -77,21 +73,4 @@ public void testDistance() { double dist = Converter.measureDistance(lat, lon, lat + distance, lon + distance); assertTrue("Distance below 1 km", dist < 1); } - - @Test - public void testLocation() { - MultiMap dataMap = new MultiMap(); - Position p = new Position(); - p.lat = (float) 50.32; - p.lon = (float) 8.32; - - // LocalDateTime ldt = LocalDateTime.now(); - // dataMap.add("deviceTime", ldt.format(Converter.DATE_INPUT_PATTERN)); - dataMap.add("dlat", Float.toString(p.lat)); - dataMap.add("dlon", Float.toString(p.lon)); - System.out.println("Map " + dataMap); - String urlEncodedParameter = UrlEncoded.encode(dataMap, Charset.defaultCharset(), false); - System.out.println("Encoded " + urlEncodedParameter); - - } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/webapi-status.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/webapi-status.json index c206df971941e..7846fdcb27c22 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/webapi-status.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/webapi-status.json @@ -1,6 +1,6 @@ { "vehicleStatus": { - "vin": "WBY1Z81040V905639", + "vin": "ANONYMOUS", "mileage": 17131, "updateReason": "VEHICLE_SECURED", "updateTime": "2020-08-18T17:54:12+0000", diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status-charging.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status-charging.json index 0c9aa95b6586a..a50cf866c36e0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status-charging.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status-charging.json @@ -1,6 +1,6 @@ { "vehicleStatus": { - "vin": "WBY1Z81040V905639", + "vin": "ANONYMOUS", "mileage": 17307, "updateReason": "CHARGING_STARTED", "updateTime": "2020-08-25T15:37:16+0000", diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status.json index e747105d8d4f3..2bad0ef617243 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status.json @@ -1,6 +1,6 @@ { "vehicleStatus": { - "vin": "WBY1Z81040V905639", + "vin": "ANONYMOUS", "mileage": 17273, "updateReason": "VEHICLE_SHUTDOWN_SECURED", "updateTime": "2020-08-24T15:55:32+0000", From caeada3c95f5b0bf85280293ced1f11426c99429 Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 15 Sep 2020 19:12:10 +0200 Subject: [PATCH 032/176] readme corrections Signed-off-by: Bernd (cherry picked from commit 82c7d3adcb3ee0d0f2bc9486fe851abc1ebfa2b2) Signed-off-by: Bernd --- bom/openhab-addons/pom.xml | 5 +++++ .../org.openhab.binding.bmwconnecteddrive/README.md | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/bom/openhab-addons/pom.xml b/bom/openhab-addons/pom.xml index 4eaa9f9befd40..82ddfc208b217 100644 --- a/bom/openhab-addons/pom.xml +++ b/bom/openhab-addons/pom.xml @@ -161,6 +161,11 @@ org.openhab.binding.bluetooth.ruuvitag ${project.version} + + org.openhab.addons.bundles + org.openhab.binding.bmwconnecteddrive + ${project.version} + org.openhab.addons.bundles org.openhab.binding.boschindego diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 368974a3fb0dd..5463a9538a821 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -56,7 +56,7 @@ For Hybrid Vehicles in addition to _Fuel and Electric Range_ the _Hybrid Range_ For each Vehicle Properties are available. Basically 3 Types of Information are registered as Properties -* Informations regarding r Dealer with Address and Phone Number +* Informations regarding your Dealer with Address and Phone Number * Which services are available / not available * Vehicle Properties like Color, Model Type, Drive Train and Construction Year @@ -76,7 +76,7 @@ So it's valid to connect Channel Group [Last Destinations](#destinations) in ord ## Discovery Auto Discovery is starting after creation of the Bridge towards BMW ConnectedDrive. -A list of r registered Vehicles is queried and all found Vehicles are added in Inbox. +A list of your registered Vehicles is queried and all found Vehicles are added in Inbox. Unique Identifier is the *Vehicle Identification Number* (VIN). If a Thing is already declared in a *.things configuration* Discovery won't highlight it again. Properties will be attached to predefined Vehicles if the VIN is matching. @@ -319,7 +319,7 @@ depends on many factors like driving style and electric consumers. A timestamp is showing the last Vehicle Status update. If this isn't shown correctly please check the date settings. In case of Raspberry Pi execute *raspi-config*, select *Localization Options*, the *Change Time Zone* -Select r *Geaographical Area* and afterwards the correct City. +Select your *Geographical Area* and afterwards the correct City. One restart of openHAB service with *systemctl restart openhab2* is necessary in order to see the corrected Time Settings. Correct TimeZone is crucial for handling all Time information in openHAB and it's discussed many times in the Forum. @@ -358,7 +358,7 @@ Data like are anonymized. After the corresponding Fingerprint is generated please [follow the instructions to raise an Issue](https://community.openhab.org/t/how-to-file-an-issue/68464) and attach the Fingerprint data! -r feedback is highly appreciated! +Your feedback is highly appreciated! Here an example of Debug Fingerprint Data from a BEV_REX Vehicle @@ -614,7 +614,7 @@ end -The [OpenStreetMap Widget](https://community.openhab.org/t/custom-widget-map/39225) can be used to display a Map on r Panel. +The [OpenStreetMap Widget](https://community.openhab.org/t/custom-widget-map/39225) can be used to display a Map on the UI Panel. It's configurable with *Markers* and *Accuracy Circles* which are quite handy to display several informations. See the HABPanel example with the OpenStreetMap Widget on the right side with From f82a77b24080c57a08fb27dc02c93a8e308149e8 Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 15 Sep 2020 19:19:47 +0200 Subject: [PATCH 033/176] readme corrections Signed-off-by: Bernd (cherry picked from commit 03878a3b3965159a491857922b43c7cc1989421f) Signed-off-by: Bernd --- bundles/org.openhab.binding.bmwconnecteddrive/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 5463a9538a821..c73cf6e655558 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -697,7 +697,7 @@ end ### Status Image - + This Rule is aimed to improve the visibility of the Vehicle Status. Therefore the Image is used to reflect _an overall status_ which can be identified at the first glance. @@ -709,6 +709,7 @@ As an example the Rule is reflecting the following status as Image * Front - Vehicle is at the Home Location * Rear - Vehicle is away from Home Location +#### Status Image Rule ``` // Change Image according to Vehicle Status rule "Image Status" From 6b6e44190af69e234dd1d919e0cb646fbd64b06b Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 15 Sep 2020 19:26:02 +0200 Subject: [PATCH 034/176] readme corrections Signed-off-by: Bernd (cherry picked from commit cb9cd2da5080a7e52d29e5ef117e72dd3a8eb1ef) Signed-off-by: Bernd --- bundles/org.openhab.binding.bmwconnecteddrive/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index c73cf6e655558..1f66978a5abe6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -747,6 +747,6 @@ end ## Credits -This work is based on the work of [Bimmer Connected](https://github.com/bimmerconnected/bimmer_connected). +This work is based on the project of [Bimmer Connected](https://github.com/bimmerconnected/bimmer_connected). Also a [manual installation based on python](https://community.openhab.org/t/script-to-access-the-bmw-connecteddrive-portal-via-oh/37345) was already available for openHAB. This Binding is basically a port to openHAB based on these concept works! From e25f7247ba2a282d4cb3992e7d79ccd8408e302c Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 15 Sep 2020 19:55:51 +0200 Subject: [PATCH 035/176] readme corrections Signed-off-by: Bernd (cherry picked from commit 9ef83e02ffe30be289d0ec5e2b19a832ef721feb) Signed-off-by: Bernd --- bundles/org.openhab.binding.bmwconnecteddrive/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 1f66978a5abe6..bd4f1c840148d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -710,6 +710,7 @@ As an example the Rule is reflecting the following status as Image * Rear - Vehicle is away from Home Location #### Status Image Rule + ``` // Change Image according to Vehicle Status rule "Image Status" From 112f7bcb08a330c48eb1ea203ca2403fec8e54fd Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 15 Sep 2020 20:27:28 +0200 Subject: [PATCH 036/176] remove readme.md previews Signed-off-by: Bernd (cherry picked from commit b1c71549496c1d9c3e2f9c09fe78fc117a7c563d) Signed-off-by: Bernd --- .../README-toc.xml | 41 --- .../README.html | 338 ------------------ 2 files changed, 379 deletions(-) delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/README-toc.xml delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/README.html diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README-toc.xml b/bundles/org.openhab.binding.bmwconnecteddrive/README-toc.xml deleted file mode 100644 index 8b485d5e28411..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README-toc.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.html b/bundles/org.openhab.binding.bmwconnecteddrive/README.html deleted file mode 100644 index 925387d04c212..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.html +++ /dev/null @@ -1,338 +0,0 @@ - - - - - - -

BMW ConnectedDrive Binding

-

The Binding connects your BMW Vehicles which are registered in the - Garageof your BMW ConnectedDrive Portal. - Due to the high variety of Cars and ConnectedDrive Services you need to check which Channels are applicable to your Car. - The Discovery Service recognizes your Car with the correct type -

-
    -
  • Conventional Fuel Vehicle
  • -
  • Plugin-Hybrid Electrical Vehicle
  • -
  • Battery Electric Vehicle with Range Extender
  • -
  • Batterie Electric Vehicle
  • -
-

In addition Properties are attached to the Vehcile Thing to obeserve the Suppoerted & Activated Services. - Different Channel Groups are available so you are able to cross-check which group is supported by your Car. -
-

-

Supported Things

-

Bridge

-

The Bridge establishes the Connection between BMW ConnectedDrive Portal and opanHAB.

-

| Name | Bridge Type ID | Description | - |----------------------------|----------------|------------------------------------------------------------| - | BMW ConnectedDrive Account | account | Access to BMW ConnectedDrive Portal for a specific user |

-

Things

-

Four different Vehicle Types are provided. They differ in the supported Channel Groups & Channels. - While Conventional Fuel Vehicles have no "Charging Profile" Electric Vehicles don't provide a _fuel range_. - For Hybrid Vehicles - fuel rangeand - electric rangeis provided and in addition a - combined range -

-

| Name | Thing Type ID | Supported Channel Groups | - |-------------------------------------|---------------|------------------------------------------------------------| - | BMW Electric Vehicle | BEV | status, range, last-trip, all-trips, charge-profile, image, troubeshoot | - | BMW Electric Vehicle with REX | BEV_REX | status, range, last-trip, all-trips, charge-profile, image, troubeshoot | - | BMW Plug-In-Hybrid Electric Vehicle | PHEV | status, range, last-trip, all-trips, image, troubeshoot | - | BMW Conventional Vehicle | CONV | status, range, last-trip, all-trips, image, troubeshoot |

-

Properties

-

For each Vehicle Properties are set with various informations. - They are especially handy to figure out the provided Services of your Vehicle. - In the right picture you can see in - Activated Servicese.g. the - DoorLockand - DoorUnlockServices are mentioned. - So you're sure that in Channel Group - Remote Servicesyou are able to execute these commands. - Also - LastDestinationsis mentioned in - Supported Servicesso it's valid to connect Channel Group - Last Destinationsin order to display the last 3 Navigation Destinations. -

-

Basically 3 Types of Information are registered as Properties

-
    -
  • Informations regarding your Dealer with Address and Phone Number
  • -
  • Which services are available or not available
  • -
  • Vehicle Properties like Color, Model Type, Drive Train and Construction Year
  • -
-

Discovery

-

Auto Discovery is starting after you created the Bridge towards BMW ConnectedDrive. - A list of your registered Vehicles is queried and all found Vehicles are added in Inbox. - As Unique Identifier the - Vehicle Identification Number(VIN) is used. - If you already predefined a Thing in *.things configuration with the same VIN the Discovery won't discover it again. - The Discovery still takes care updating the Properties of your Vehicle. -

-

Configuration

-

Bridge

-

| Parameter | Type | Description | -
- |-----------------|---------|-------------------------------------------------------------------------| - | userName | text | BMW Connected Drive Username | - | password | text | BMW Connected Drive Password | - | region | text | Select your Region in order to connect to the appropriate BMW Server. | -

-

The region Configuration has 3 different possibilities

-
    -
  • - NORTH_AMERICA -
  • -
  • - CHINA -
  • -
  • - ROWfor Rest of World -
  • -
-

Things

-

All Things are needing the same Configuration Data

-

| Parameter | Type | Description | -
- |-----------------|---------|-------------------------------------------------------------------------| - | vin | text | Vehicle Identification Number (VIN) | - | refreshInterval | integer | Refresh Interval in Minutes | - | units | text | Unit Selection | - | imageSize | integer | Image Picture Size< | - | imageViewport | text | Image Viewport | -

-

The units can be configured in 3 ways

-
    -
  • - AUTODETECTselects Miles for US & UK, Kilometre otherwise -
  • -
  • - METRICselects directly Kilometers -
  • -
  • - IMPERIALselects directly Miles -
  • -
-

The imageVieport allows you to show your Car from different angels. - Possible values are FRONT, REAR, SIDE, DASHBOARD or DRIVERDOOR

-

Channels

-

There are many Channels available for each Vehicle. - For better overview they are clustered in different Channel Groups. - The Channel Groups are different for the Car Types but also depends on the build in Sensors of your Car. - This means also the Construction Year is relevant if some Channels are supported or not.

-

Channel Group - Vehicle Status -

-

Available for all Vehicles.

-

| Channel Label | Channel Group ID | Channel ID | Type | Description | - |-----------------------|------------------|---------------------|--------|---------------------------------------------------| - | Door Status | status | doors | String | Closed if all closed, else reports the Door which is still open | - | Window Status | status | windows | String | Closed if all closed, else reports the Window which is still open | - | Doors Locked | status | lock | String | Status if Doors are locked or unlocked | - | Upcoming Service | status | service | String | Upcoming Service either after certain Mileage, Date, or both | - | Check Control | status | check-control | String | Description of actual Check Control message, Ok if none is activae |

-

Channel Group - Range Data -

-

Available for all Vehicles. - Based on Vehicle Type (Thing Type ID) the Channel is presented or not. - For Conventional Fuel Cars the - Remaining Electric Rangeisn't presented while for Battery Electric Vehicles - Remaining Range Fuelisn't valid. - Hybrid Vehicles have both and in addition - Remaining Hybrid Range -

-

| Channel Label | Channel Group ID | Channel ID | Type | Valid for | Description | - |-----------------------|------------------|---------------------|---------------|-----------|----------------------------------------| - | Mileage | range | mileage | Number:Length | All | Total Distance Driven | - | Hybrid Range | range | range-hybrid | Number:Length | All | Total Distance Driven | - | Battery Range | range | range-electric | Number:Length | All | Total Distance Driven | - | Battery Charge Level | range | soc | Number:Length | All | Total Distance Driven | - | Fuel Range | range | range-fuel | Number:Length | All | Total Distance Driven | - | Remaining Fuel | range | remaining-fuel | Number:Length | All | Total Distance Driven |

-

Channel Group - Last Trip -

-

| Channel Label | Channel Group ID | Channel ID | Type | Description | - |-----------------------|------------------|---------------------|--------|---------------------------------------------------| - | Modbus-ID | status | modbus-id | String | Modbus ID / Magic Byte of E3DC |

-

Channel Group - Lifetime Statistics -

-

| Channel Label | Channel Group ID | Channel ID | Type | Description | - |-----------------------|------------------|---------------------|--------|---------------------------------------------------| - | Modbus-ID | range | modbus-id | String | Modbus ID / Magic Byte of E3DC |

-

Channel Group - Vehicle Location -

-

| Channel Label | Channel Group ID | Channel ID | Type | Description | - |-----------------------|------------------|---------------------|--------|---------------------------------------------------| - | Modbus-ID | status | modbus-id | String | Modbus ID / Magic Byte of E3DC |

-

Channel Group - Remote Services -

-

| Channel Label | Channel Group ID | Channel ID | Type | Description | - |-----------------------|------------------|---------------------|--------|---------------------------------------------------| - | Modbus-ID | range | modbus-id | String | Modbus ID / Magic Byte of E3DC |

-

Channel Group - Image -

-

| Channel Label | Channel Group ID | Channel ID | Type | Description | - |-----------------------|------------------|---------------------|--------|---------------------------------------------------| - | Modbus-ID | status | modbus-id | String | Modbus ID / Magic Byte of E3DC |

-

Channel Group - Troubleshooting -

-

| Channel Label | Channel Group ID | Channel ID | Type | Description | - |-----------------------|------------------|---------------------|--------|---------------------------------------------------| - | Modbus-ID | range | modbus-id | String | Modbus ID / Magic Byte of E3DC |

-

TroubleShooting

-

In order to to identify issues the TroubleShooting Channels are providing Analysis Informations

-

Discovery

-

If your Vehicle isn't discovered correctly perform the following steps

-
    -
  • Check if your Vehicle is attached correctly in ConnectedDrive. Only if it's attached to your ConnectedDrive Account it's possible to detect it.
  • -
  • In the below example sitemap the Switch - Log Discovery Fingerprintcan be executed. -
  • -
-

Car Data

-

Update Timestamp

-

There's a timestamp showing the last update of your Vehicle. If this isn't shown correctly please check the date settings. - In case of Raspberry Pi execute - raspi-cinfig_, select _Localization Options_, the _Change Time Zone - Select your - Geaographical Areaand afterwards the correct City. - One restart of openHAB service with - systemctl restart openhab2is necessary in order to see the corrected Time Settings. -

-

Full Example

-

The example is based on a BMW i3 with Range Extender (REX). - Exchange the 3 configuration parameters in the Things section

-
    -
  • YOUR_USERNAME - with your ConnectedDrive Login Username
  • -
  • YOUR_PASSWORD - with your ConnectedDrive Password Credentials
  • -
  • VEHICLE_VIN - the Vehicle Identification Number
  • -
-

and you're ready to go!

-

Things

-
Bridge bmwconnecteddrive:account:user   "BMW ConnectedDrive Account" [userName="YOUR_USERNAME",password="YOUR_PASSWORD",region="ROW"] {
-         Thing BEV_REX i3       "BMW i3 94h REX"                [ vin="VEHICLE_VIN",units="AUTODETECT",imageSize=2048,imageViewport="FRONT",refreshInterval=15]
-}
-

Items

-
Number:Length           i3Mileage                 "Odometer"                 <chart>    (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:range#mileage" }                                                                           
-Number:Length           i3Range                   "Hybrid Range"             <motion>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-range-hybrid"}
-Number:Length           i3RangeElectric           "Electric Range"           <motion>   (i3,long)   {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-range-electric"}   
-Number:Length           i3RangeFuel               "Fuel Range"               <motion>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-range-fuel"}
-Number:Dimensionless    i3BatterySoc              "Battery Charged"          <battery>  (i3,long)   {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-soc"}
-Number:Dimensionless    i3Fuel                    "Fuel Charged"             <oil>      (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-fuel"}
-String                  i3LastUpdate              "Updated"                  <calendar> (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:range#last-update"}
-
-String                  i3DoorStatus              "Door Status"       <lock>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:status#doors" }
-String                  i3WindowStatus            "Window Status"       <lock>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:status#windows" }
-String                  i3LockStatus              "Locked Status"       <lock>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:status#lock" }
-String                  i3ServiceStatus           "Service"       <calendar>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:status#service" }
-String                  i3CheckControl            "Check Control"       <error>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:status#check-control" }
-String                  i3ChargingStatus          "Charging"       <batterylevel>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:status#charging-status" }
-
-Number:Length           i3TripDistance            "Distance"                 <chart>    (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance" }                                                                           
-Number:Length           i3TripDistanceSinceCharge "Driven Since last Charge" <chart>    (i3,long)    {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance-since-charging" }                                                                           
-Number:Energy           i3AvgTripConsumption      "Average Consumption"      <energy>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-consumption" }                                                                           
-Number:Energy           i3AvgTripRecuperation     "Average Recuperation"     <energy>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-recuperation" }                                                                           
-
-Number:Length           i3CumulatedElectric       "Eletric Driven Distance"  <chart>    (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#cumulated-driven-distance" }                                                                           
-Number:Length           i3LongestEVTrip           "Longest Eletric Trip"     <chart>    (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#single-longest-distance" }                                                                           
-Number:Energy           i3AvgConsumption          "Average Consumption"      <energy>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#average-consumption" }                                                                           
-Number:Energy           i3AvgRecuperation         "Average Recuperation"     <energy>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#average-recuperation" }  
-
-Number                  i3Longitude               "Location Longitude"       <zoom>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:location#longitude" }                                                                           
-Number                  i3Latitude                "Location Latitude"        <zoom>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:location#latitude" }                                                                           
-String                  i3LatLong                 "Location as String"       <zoom>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:location#latlong" }
-Number:Angle            i3Heading                 "Vehicle Heading"          <zoom>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:location#heading" }  
-Number                  i3RangeRadius             "Range Radius"             <zoom>     (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:location#range-radius" }
-
-Switch                  i3RemoteFlash             "Remote Flashlight"        <switch>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#light" } 
-Switch                  i3RemoteFinder            "Remote Flashlight"        <switch>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#finder" } 
-Switch                  i3RemoteLock              "Remote Flashlight"        <switch>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#lock" } 
-Switch                  i3RemoteUnlock            "Remote Flashlight"        <switch>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#unlock" } 
-Switch                  i3RemoteHorn              "Remote Flashlight"        <switch>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#horn" } 
-Switch                  i3RemoteClimate           "Remote Flashlight"        <switch>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#climate" } 
-String                  i3RemoteState             "Remote Flashlight"        <status>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#state" } 
-
-Image                   i3Image                   "Car Image"                <switch> (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:image#rendered" }  
-
-Switch                  i3Troubleshoot            "Force Fingerprint Log"    <switch>   (i3)   {channel="bmwconnecteddrive:BEV_REX:user:i3:troubleshoot#cardata-fingerprint" }  
-Switch                  i3DiscoveryFinger         "Discovery Fingerprint"    <switch>   (i3)   {channel="bmwconnecteddrive:account:user:discovery-fingerprint"}
-

Sitemap

-
sitemap BMW label="BMW" {
-  Frame label="BMW i3" {
-    Image  item=i3Image                     label="Car Image"
-  } 
-  Frame label="Range" {
-    Text    item=i3Mileage                  label="Odometer [%d %unit%]"
-    Text    item=i3Range                    label="Range [%d %unit%]"
-    Text    item=i3RangeElectric            label="Eletric Range [%d %unit%]"
-    Text    item=i3RangeFuel                label="Fuel Range [%d %unit%]"
-    Text    item=i3BatterySoc               label="Battery Charge [%.1f %%]"
-    Text    item=i3Fuel                     label="Fuel Charge [%.1f %%]"
-    Text    item=i3LastUpdate               label="Last Update [%s]"
-  }
-  Frame label="Status" {
-    Text    item=i3DoorStatus               label="Door Status [%s]"
-    Text    item=i3WindowStatus             label="Window Status [%s]"
-    Text    item=i3LockStatus               label="Lock Status [%s]"
-    Text    item=i3ServiceStatus            label="Service [%s]"
-    Text    item=i3CheckControl             label="Check Control [%s]"
-    Text    item=i3ChargingStatus           label="Charging [%s]"
-  }
-  Frame label="Remote Services" {
-    Switch  item=i3RemoteFlash              label="Flash"
-    Switch  item=i3RemoteFinder             label="Finder"
-    Switch  item=i3RemoteLock               label="Lock"
-    Switch  item=i3RemoteUnlock             label="Unlock"
-    Switch  item=i3RemoteHorn               label="Horn"
-    Switch  item=i3RemoteClimate            label="Air Conditioning"
-    Text    item=i3RemoteState              label="Execution Status"
-}
-  Frame label="Last Trip" {
-    Text    item=i3TripDistance             label="Distance [%d %unit%]"
-    Text    item=i3TripDistanceSinceCharge  label="Distance since last Charge [%d %unit%]"
-    Text    item=i3AvgTripConsumption       label="Average Consumption [%.1f %unit%]"
-    Text    item=i3AvgTripRecuperation      label="Average Recuperation [%.1f %unit%]"
-  }
-  Frame label="Lifetime" {
-    Text    item=i3CumulatedElectric        label="Eletric Distance Driven [%d %unit%]"
-    Text    item=i3LongestEVTrip            label="Longest Trip [%d %unit%]"
-    Text    item=i3AvgConsumption           label="Average Consumption [%.1f %unit%]"
-    Text    item=i3AvgRecuperation          label="Average Recuperation [%.1f %unit%]"      
-  }
-  Frame label="Location" {
-    Text    item=i3Latitude                 label="Latitude  [%.4f]"
-    Text    item=i3Longitude                label="Longitude [%.4f]"
-    Text    item=i3LatLong                  label="Location  [%s]"
-    Text    item=i3Heading                  label="Heading [%.1f %unit%]" 
-    Text    item=i3RangeRadius              label="Radius [%d]"   
-  }
-  Frame label="Troubleshooting" {    
-    Switch  item=i3DiscoveryFinger          label="Log Discovery Fingerprint"
-    Switch  item=i3Troubleshoot             label="Log CarData Fingerprint"
-    
-  } 
-}
-

Going further

-

You're now able to receive your Vehicle Data in openHAB. Continue the work and combine this data with other Powerful openHAB Bindings and Widgets.

-

OpenstreetMap Widget

-

OpenWeatherMap Binding and Widget

-

Especially Electric Vehicles which maybe are charged with your Local Photovoltaic System the Weather forecast and corresponding Cloudiness is interesting. - Use the OpenWeatherMap Binding and existing - Widget Solutions to check this data in addition to your Vehicles State of Charge. -

-

Credits

-

This work is based on the work of - Bimmer Connected. - Also a - manual installation based on python was already available for openHAB. - This Binding is basically a port to openHAB based on these concept works! -
-

- - \ No newline at end of file From 8f560ec33847824966a0d02001a3942b7d60ac11 Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 15 Sep 2020 20:53:43 +0200 Subject: [PATCH 037/176] change unit test from hard coded date to service name Signed-off-by: Bernd (cherry picked from commit ffa97aca83a44227f51984abeef9d4cfa382113e) Signed-off-by: Bernd --- .../internal/handler/VehicleTests.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java index 6e6a8917cf52e..f9132163bf4b9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java @@ -23,7 +23,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jetty.client.HttpClient; -import org.eclipse.smarthome.core.library.types.DateTimeType; import org.eclipse.smarthome.core.library.types.StringType; import org.eclipse.smarthome.core.thing.ChannelUID; import org.eclipse.smarthome.core.thing.Thing; @@ -189,7 +188,10 @@ public void testF15() { String content = FileReader.readFileInString("src/test/resources/responses/F15/status.json"); // Check earliest Service by hard Map m = new HashMap(); - m.put(ConnectedDriveConstants.SERVICE_DATE, DateTimeType.valueOf("2018-06-01T14:00:00.000+0200")); + // Don>'t test on concrete timestamp - it's idfferent on each machine + // Check for cbsType which is "Oil" instead + // m.put(ConnectedDriveConstants.SERVICE_DATE, DateTimeType.valueOf("2018-06-01T14:00:00.000+0200")); + m.put(ConnectedDriveConstants.SERVICE_NAME, StringType.valueOf("Oil")); assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.of(m))); } @@ -200,7 +202,10 @@ public void testF15Miles() { String content = FileReader.readFileInString("src/test/resources/responses/F15/status.json"); // Check earliest Service by hard Map m = new HashMap(); - m.put(ConnectedDriveConstants.SERVICE_DATE, DateTimeType.valueOf("2018-06-01T14:00:00.000+0200")); + // Don>'t test on concrete timestamp - it's idfferent on each machine + // Check for cbsType which is "Oil" instead + // m.put(ConnectedDriveConstants.SERVICE_DATE, DateTimeType.valueOf("2018-06-01T14:00:00.000+0200")); + m.put(ConnectedDriveConstants.SERVICE_NAME, StringType.valueOf("Oil")); assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.of(m))); } From 0088cfbfad0fbcea4af61aaad74da4089c5cc27f Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 15 Sep 2020 20:59:38 +0200 Subject: [PATCH 038/176] remove locale time test Signed-off-by: Bernd (cherry picked from commit fcdd3c0057d7ca6eb15854de004f088a26371190) Signed-off-by: Bernd --- .../binding/bmwconnecteddrive/internal/util/LocaleTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java index 1c216afa01ec9..ccec9ab338944 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java @@ -44,7 +44,6 @@ public void languageTest() { assertFalse("Germany", ConnectedDriveConstants.IMPERIAL_COUNTRIES.contains(Locale.GERMAN.getCountry())); } - @Test public void testTimeUTCToLocaleTime() { String resource1 = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); VehicleStatusContainer status = GSON.fromJson(resource1, VehicleStatusContainer.class); From 87520d24e912bf8d5b1728c1cf3c870586902697 Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 15 Sep 2020 21:59:04 +0200 Subject: [PATCH 039/176] remote state execution status update increase Signed-off-by: Bernd (cherry picked from commit 43bd1613dad22adb1b36fe4d10b7c2b0823dccec) Signed-off-by: Bernd --- .../internal/handler/RemoteServiceHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java index 952470cf9965a..8d769412e8dcc 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -39,7 +39,7 @@ public class RemoteServiceHandler implements StringResponseCallback { // after 60 retries the state update will give up private static final String SERVICE_TYPE = "serviceType"; private static final int GIVEUP_COUNTER = 12; - private static final int STATE_UPDATE_SEC = 5; + private static final int STATE_UPDATE_SEC = 10; private int counter = 0; public enum ExecutionState { From 557a2ff649fccf803fcaad6e1598314c479d8b91 Mon Sep 17 00:00:00 2001 From: Bernd Date: Wed, 16 Sep 2020 21:02:39 +0200 Subject: [PATCH 040/176] update after remote service call Signed-off-by: Bernd (cherry picked from commit 72b324dfce9938e7ab3311df48e54d870d8c3ef1) Signed-off-by: Bernd --- bundles/org.openhab.binding.bmwconnecteddrive/README.md | 2 +- .../internal/handler/RemoteServiceHandler.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index bd4f1c840148d..dcef71c5c8f47 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -393,7 +393,7 @@ In addition search for all occurrences of *i3* and replace it with your Vehicle ### Things ``` -Bridge bmwconnecteddrive:account:user "BMW ConnectedDrive Account" [userName="R_USERNAME",password="R_PASSWORD",region="ROW"] { +Bridge bmwconnecteddrive:account:user "BMW ConnectedDrive Account" [userName="YOUR_USERNAME",password="YOUR_PASSWORD",region="ROW"] { Thing BEV_REX i3 "BMW i3 94h REX" [ vin="VEHICLE_VIN",units="AUTODETECT",imageSize=600,imageViewport="FRONT",refreshInterval=5] } ``` diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java index 8d769412e8dcc..21459fa91b9cd 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -38,7 +38,7 @@ public class RemoteServiceHandler implements StringResponseCallback { // after 60 retries the state update will give up private static final String SERVICE_TYPE = "serviceType"; - private static final int GIVEUP_COUNTER = 12; + private static final int GIVEUP_COUNTER = 6; private static final int STATE_UPDATE_SEC = 10; private int counter = 0; @@ -143,9 +143,9 @@ public void onResponse(Optional result) { if (!ExecutionState.EXECUTED.toString().equals(execStatus.status)) { handler.getScheduler().schedule(this::getState, STATE_UPDATE_SEC, TimeUnit.SECONDS); } else { - // refresh loop ends - refresh data + // refresh loop ends - update of status handled in the normal refreshInterval. Earlier update doesn't + // show better results! reset(); - handler.getData(); } } else { // schedule even if no result is present until retries exceeded From 50e96c51d5d52c07cbba42915790c62a44bbce46 Mon Sep 17 00:00:00 2001 From: Bernd Date: Fri, 18 Sep 2020 18:13:44 +0200 Subject: [PATCH 041/176] fix window intermediate state handling Signed-off-by: Bernd (cherry picked from commit 0424c871ebd16db40e01b423f8c90fb0fbbca5a1) Signed-off-by: Bernd --- .../internal/dto/status/VehicleStatus.java | 27 +- .../internal/discovery/DiscoveryTest.java | 3 +- .../internal/dto/StatusWrapper.java | 8 +- .../internal/handler/VehicleTests.java | 10 + .../resources/responses/F31/status-318i.json | 66 ++ .../test/resources/responses/vehicles.json | 853 +++++++++--------- 6 files changed, 549 insertions(+), 418 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F31/status-318i.json diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java index eab7c7f546588..19f7d65e86be3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java @@ -150,24 +150,31 @@ public String getUpdateTime() { * @return Closed if all "Closed", "Open" otherwise */ public static String checkClosed(Object dto) { - boolean validDoorFound = false; + boolean validObjectFound = false; for (Field field : dto.getClass().getDeclaredFields()) { try { - if (field.get(dto) != null) { - if (field.get(dto).equals(OPEN)) { - // report the first door which is still open - return Converter - .toTitleCase(new StringBuffer(field.getName()).append(" ").append(OPEN).toString()); - // Ignore INVALID fields == Door not present } else if (field.get(dto).equals(INVALID)) { - } else if (field.get(dto).equals(CLOSED)) { - validDoorFound = true; + Object d = field.get(dto); + if (d != null) { + String state = d.toString(); + // skip invalid entries - they don't apply to this Vehicle + if (!state.equals(INVALID)) { + if (!state.equals(CLOSED)) { + // report the first field - remove DOOR / WINDOW Strings because they are reported to the + // corresponding Channel + String id = field.getName().toLowerCase().replace("door", Constants.EMPTY).replace("window", + Constants.EMPTY); + return Converter.toTitleCase(new StringBuffer(id).append(" ").append(state).toString()); + } else { + // at least one valid object needs to be found in order to reply "CLOSED" + validObjectFound = true; + } } } } catch (IllegalArgumentException | IllegalAccessException e) { return Converter.toTitleCase(UNKNOWN); } } - if (validDoorFound) { + if (validObjectFound) { return Converter.toTitleCase(CLOSED); } else { return Converter.toTitleCase(UNKNOWN); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java index e7c0fbd011b9e..0753b1136bf6a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java @@ -42,6 +42,7 @@ public class DiscoveryTest { private final Logger logger = LoggerFactory.getLogger(DiscoveryTest.class); private static final Gson GSON = new Gson(); + private static final int DISCOVERY_VEHICLES = 9; @Test public void testDiscovery() { @@ -80,7 +81,7 @@ public void testBimmerDiscovery() { ArgumentCaptor services = ArgumentCaptor.forClass(DiscoveryService.class); discovery.onResponse(container); - verify(listener, times(8)).thingDiscovered(services.capture(), discoveries.capture()); + verify(listener, times(DISCOVERY_VEHICLES)).thingDiscovered(services.capture(), discoveries.capture()); List results = discoveries.getAllValues(); results.forEach(entry -> { logger.info("{}", entry.toString()); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index e158c4f6d7d5d..61871d5707d73 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -192,13 +192,17 @@ private void checkResult(ChannelUID channelUID, State state) { assertTrue(state instanceof StringType); st = (StringType) state; Windows windowState = GSON.fromJson(GSON.toJson(vStatus), Windows.class); - assertEquals("Windows Closed", VehicleStatus.checkClosed(windowState), st.toString()); + if (specialHandlingMap.containsKey(WINDOWS)) { + assertEquals("Windows", specialHandlingMap.get(WINDOWS).toString(), st.toString()); + } else { + assertEquals("Windows", VehicleStatus.checkClosed(windowState), st.toString()); + } break; case CHECK_CONTROL: assertTrue(state instanceof StringType); st = (StringType) state; if (specialHandlingMap.containsKey(CHECK_CONTROL)) { - assertEquals("Next Service", specialHandlingMap.get(CHECK_CONTROL).toString(), st.toString()); + assertEquals("Check Control", specialHandlingMap.get(CHECK_CONTROL).toString(), st.toString()); } else { assertEquals("Check Control", vStatus.getCheckControl(), st.toString()); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java index f9132163bf4b9..968e6f43e97e8 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java @@ -339,4 +339,14 @@ public void testI01RexMiles() { String content = FileReader.readFileInString("src/test/resources/responses/I01_REX/status.json"); assertTrue(testVehicle(content, HYBRID_CALL_TIMES, Optional.empty())); } + + @Test + public void test318iF31() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(VehicleType.CONVENTIONAL.toString(), false); + String content = FileReader.readFileInString("src/test/resources/responses/F31/status-318i.json"); + Map m = new HashMap(); + m.put(ConnectedDriveConstants.WINDOWS, StringType.valueOf("Driverfront Intermediate")); + assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.of(m))); + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F31/status-318i.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F31/status-318i.json new file mode 100644 index 0000000000000..f20475a95ee7b --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F31/status-318i.json @@ -0,0 +1,66 @@ +{ + "vehicleStatus": { + "mileage": 25659, + "remainingFuel": 55.0, + "remainingRangeElectric": 0.0, + "remainingRangeElectricMls": 0.0, + "remainingRangeFuel": 794.0, + "remainingRangeFuelMls": 493.0, + "maxRangeElectric": 0.0, + "maxRangeElectricMls": 0.0, + "maxFuel": 0.0, + "chargingLevelHv": 0.0, + "vin": "ANONYMOUS", + "updateReason": "VEHICLE_SHUTDOWN", + "updateTime": "2020-09-18T12:11:38+0000", + "doorDriverFront": "CLOSED", + "doorDriverRear": "CLOSED", + "doorPassengerFront": "CLOSED", + "doorPassengerRear": "CLOSED", + "windowDriverFront": "INTERMEDIATE", + "windowDriverRear": "CLOSED", + "windowPassengerFront": "CLOSED", + "windowPassengerRear": "CLOSED", + "trunk": "CLOSED", + "rearWindow": "CLOSED", + "hood": "CLOSED", + "doorLockState": "SECURED", + "parkingLight": "OFF", + "positionLight": "OFF", + "position": { + "lat": -1.0, + "lon": -1.0, + "heading": -1, + "status": "OK" + }, + "internalDataTimeUTC": "2020-09-18T12:11:38", + "singleImmediateCharging": false, + "vehicleCountry": "NL", + "DCS_CCH_Activation": "NA", + "DCS_CCH_Ongoing": false, + "checkControlMessages": [], + "cbsData": [ + { + "cbsType": "OIL", + "cbsState": "OK", + "cbsDueDate": "2022-07", + "cbsDescription": "Next service due when the stated distance has been covered or by the specified date.", + "cbsRemainingMileage": 29000 + }, + { + "cbsType": "VEHICLE_CHECK", + "cbsState": "OK", + "cbsDueDate": "2022-07", + "cbsDescription": "Next visual inspection due when the stated distance has been covered or by the stated date.", + "cbsRemainingMileage": 29000 + }, + { + "cbsType": "BRAKE_FLUID", + "cbsState": "OK", + "cbsDueDate": "2022-01", + "cbsDescription": "Next change due at the latest by the stated date.", + "cbsRemainingMileage": 0 + } + ] + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/vehicles.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/vehicles.json index fe73476204943..3599d593dcc39 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/vehicles.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/vehicles.json @@ -1,407 +1,450 @@ { - "vehicles" : [ { - "vehicleFinderRestriction" : "NONE", - "doorUnlock" : "ACTIVATED", - "color" : "SOPHISTOGRAU BRILLANTEFFEKT METALLI", - "onlineSearchMode" : "MAP", - "breakdownNumber" : "+4912345678", - "smartSolution" : "NOT_SUPPORTED", - "yearOfConstruction" : 2018, - "driveTrain" : "CONV", - "rangeMap" : "NOT_SUPPORTED", - "vehicleFinder" : "ACTIVATED", - "a4a" : "BLUETOOTH", - "hornBlow" : "ACTIVATED", - "chargeNow" : "NOT_SUPPORTED", - "countryCode" : "V6", - "bodytype" : "G31", - "lightFlash" : "ACTIVATED", - "vin" : "G31_NBTevo_VIN", - "model" : "530i xDrive", - "ipa" : "NOT_SUPPORTED", - "brand" : "BMW", - "climateControl" : "DEPARTURE_TIMER", - "sendPoi" : "ACTIVATED", - "lastDestinations" : "NOT_SUPPORTED", - "doorLock" : "ACTIVATED", - "chargingControl" : "NOT_SUPPORTED", - "onlineSearchProvider" : "GOOGLE", - "steering" : "LH", - "intermodalRouting" : "NOT_AVAILABLE", - "lscType" : "LSC_BASIS", - "hasAlarmSystem" : true, - "statisticsCommunityEnabled" : false, - "climateNow" : "ACTIVATED", - "fuelType" : "PETROL", - "hub" : "HUB_ECE", - "remote360" : "NOT_SUPPORTED", - "hmiVersion" : "ID5", - "climateFunction" : "PARK_HEATING", - "colorCode" : "A90", - "carCloud" : "ACTIVATED", - "statisticsAvailable" : false - }, - { - "vehicleFinderRestriction" : "NONE", - "doorUnlock" : "ACTIVATED", - "color" : "ALPINWEISS III", - "onlineSearchMode" : "MAP", - "breakdownNumber" : "+4989358111111", - "smartSolution" : "NOT_SUPPORTED", - "yearOfConstruction" : 2017, - "driveTrain" : "CONV", - "rangeMap" : "NOT_SUPPORTED", - "vehicleFinder" : "ACTIVATED", - "a4a" : "BLUETOOTH", - "hornBlow" : "ACTIVATED", - "chargeNow" : "NOT_SUPPORTED", - "countryCode" : "V1-NL", - "bodytype" : "F48", - "lightFlash" : "ACTIVATED", - "vin" : "F48_VIN", - "model" : "X1 sDrive18i", - "ipa" : "NOT_SUPPORTED", - "brand" : "BMW", - "climateControl" : "START_TIMER", - "sendPoi" : "ACTIVATED", - "lastDestinations" : "NOT_SUPPORTED", - "doorLock" : "ACTIVATED", - "chargingControl" : "NOT_SUPPORTED", - "onlineSearchProvider" : "GOOGLE", - "steering" : "LH", - "intermodalRouting" : "NOT_AVAILABLE", - "lscType" : "LSC_BASIS", - "hasAlarmSystem" : true, - "statisticsCommunityEnabled" : false, - "climateNow" : "ACTIVATED", - "fuelType" : "PETROL", - "hub" : "HUB_ECE", - "remote360" : "NOT_SUPPORTED", - "hmiVersion" : "ID5", - "dealer" : { - "country" : "NL", - "city" : "city", - "phone" : "phone", - "street" : "street", - "postalCode" : "1234 AB", - "name" : "BMW dealer" - }, - "climateFunction" : "VENTILATION", - "colorCode" : "300", - "carCloud" : "ACTIVATED", - "statisticsAvailable" : false - } - , - { - "vehicleFinderRestriction" : "NONE", - "doorUnlock" : "ACTIVATED", - "color" : "ARRAVANIGRAU/BMW i BLAU", - "onlineSearchMode" : "MAP", - "breakdownNumber" : "+4989358957103", - "smartSolution" : "NOT_SUPPORTED", - "yearOfConstruction" : 2014, - "driveTrain" : "BEV_REX", - "rangeMap" : "RANGE_CIRCLE", - "vehicleFinder" : "ACTIVATED", - "a4a" : "USB_ONLY", - "hornBlow" : "ACTIVATED", - "chargeNow" : "NOT_SUPPORTED", - "licensePlate" : "ABC000", - "countryCode" : "V1-R1-SE", - "bodytype" : "I01", - "lightFlash" : "ACTIVATED", - "vin" : "I01_VIN", - "model" : "i3 (+ REX)", - "ipa" : "NOT_SUPPORTED", - "brand" : "BMW_I", - "climateControl" : "NOT_SUPPORTED", - "sendPoi" : "ACTIVATED", - "lastDestinations" : "SUPPORTED", - "doorLock" : "ACTIVATED", - "chargingControl" : "WEEKLY_PLANNER", - "onlineSearchProvider" : "GOOGLE", - "steering" : "LH", - "intermodalRouting" : "NOT_AVAILABLE", - "supportedChargingModes" : [ "AC_LOW", "AC_HIGH", "DC" ], - "lscType" : "I_LSC_IMM", - "hasAlarmSystem" : false, - "statisticsCommunityEnabled" : false, - "climateNow" : "ACTIVATED", - "hub" : "HUB_ECE", - "remote360" : "NOT_SUPPORTED", - "hmiVersion" : "ID4", - "dealer" : { - "country" : "SE", - "city" : "Solna", - "phone" : "+46 8 7353900", - "street" : "G�rdsv�gen 9-11", - "postalCode" : "169 70", - "name" : "Bavaria Sverige Bil AB/ Solna" - }, - "climateFunction" : "AIRCONDITIONING", - "colorCode" : "B74", - "carCloud" : "NOT_SUPPORTED", - "statisticsAvailable" : true - }, - { - "vehicleFinderRestriction" : "NONE", - "doorUnlock" : "NOT_SUPPORTED", - "color" : "BLACK SAPPHIRE METALLIC", - "onlineSearchMode" : "MAP", - "breakdownNumber" : "+4989358957103", - "smartSolution" : "NOT_SUPPORTED", - "yearOfConstruction" : 2017, - "driveTrain" : "CONV", - "rangeMap" : "NOT_SUPPORTED", - "vehicleFinder" : "ACTIVATED", - "a4a" : "BLUETOOTH", - "hornBlow" : "ACTIVATED", - "chargeNow" : "NOT_SUPPORTED", - "countryCode" : "V2-CA", - "bodytype" : "F15", - "lightFlash" : "ACTIVATED", - "vin" : "F15_VIN", - "model" : "X5 xDrive35i", - "ipa" : "NOT_SUPPORTED", - "brand" : "BMW", - "climateControl" : "DEPARTURE_TIMER", - "sendPoi" : "ACTIVATED", - "lastDestinations" : "NOT_SUPPORTED", - "doorLock" : "ACTIVATED", - "chargingControl" : "NOT_SUPPORTED", - "steering" : "LH", - "intermodalRouting" : "NOT_AVAILABLE", - "lscType" : "LSC_BASIS", - "hasAlarmSystem" : true, - "statisticsCommunityEnabled" : false, - "climateNow" : "ACTIVATED", - "fuelType" : "PETROL", - "hub" : "HUB_US", - "remote360" : "NOT_SUPPORTED", - "hmiVersion" : "ID5", - "dealer" : { - "country" : "CA", - "city" : "Ottawa", - "phone" : "1-866-599-4999", - "street" : "85 Wellington St", - "postalCode" : "K1A 1A1", - "name" : "Parliament of Canada" - }, - "climateFunction" : "VENTILATION", - "colorCode" : "475", - "carCloud" : "NOT_SUPPORTED", - "statisticsAvailable" : false - }, - { - "vehicleFinderRestriction": "NONE", - "doorUnlock": "ACTIVATED", - "color": "SOLARORANGE MET. M. AKZENT FROZEN G", - "onlineSearchMode": "MAP", - "breakdownNumber": "+4989358957103", - "smartSolution": "NOT_SUPPORTED", - "yearOfConstruction": 2014, - "driveTrain": "BEV", - "rangeMap": "RANGE_CIRCLE", - "vehicleFinder": "ACTIVATED", - "a4a": "USB_ONLY", - "hornBlow": "ACTIVATED", - "chargeNow": "NOT_SUPPORTED", - "licensePlate": "HIDDEN", - "countryCode": "B3-ZA", - "bodytype": "I01", - "lightFlash": "ACTIVATED", - "vin": "I01_NOREX_VIN", - "model": "i3", - "ipa": "NOT_SUPPORTED", - "brand": "BMW_I", - "climateControl": "NOT_SUPPORTED", - "sendPoi": "ACTIVATED", - "lastDestinations": "SUPPORTED", - "doorLock": "ACTIVATED", - "chargingControl": "WEEKLY_PLANNER", - "onlineSearchProvider": "GOOGLE", - "steering": "RH", - "intermodalRouting": "NOT_AVAILABLE", - "supportedChargingModes": [ - "AC_LOW", - "AC_HIGH" - ], - "lscType": "I_LSC_IMM", - "hasAlarmSystem": true, - "statisticsCommunityEnabled": true, - "climateNow": "ACTIVATED", - "hub": "HUB_ECE", - "remote360": "NOT_SUPPORTED", - "hmiVersion": "ID4", - "dealer": { - "country": "ZA", - "city": "Midrand", - "phone": "+27 12 522 3000", - "street": "1 Bavaria Avenue", - "postalCode": "1685", - "name": "BMW (South Africa) (Pty) Ltd. ZA" - }, - "climateFunction": "AIRCONDITIONING", - "colorCode": "B78", - "carCloud": "NOT_SUPPORTED", - "statisticsAvailable": true - }, - { - "a4a": "USB_ONLY", - "bodytype": "F45", - "brand": "BMW", - "breakdownNumber": "+4989358957103", - "carCloud": "NOT_SUPPORTED", - "chargeNow": "NOT_SUPPORTED", - "chargingControl": "NOT_SUPPORTED", - "climateControl": "START_TIMER", - "climateFunction": "VENTILATION", - "climateNow": "ACTIVATED", - "color": "MEDITERRANBLAU METALLIC", - "colorCode": "C10", - "countryCode": "V1-ES", - "dealer": { - "city": "Madrid", - "country": "ES", - "name": "BMW Iberica S.A.", - "phone": "+34 913350505", - "postalCode": "28050", - "street": "Avenida de Burgos ,118" - }, - "doorLock": "ACTIVATED", - "doorUnlock": "ACTIVATED", - "driveTrain": "CONV", - "fuelType": "PETROL", - "hasAlarmSystem": false, - "hmiVersion": "ID4", - "hornBlow": "ACTIVATED", - "hub": "HUB_ECE", - "intermodalRouting": "NOT_AVAILABLE", - "ipa": "NOT_SUPPORTED", - "lastDestinations": "NOT_SUPPORTED", - "licensePlate": "some_license_plate", - "lightFlash": "ACTIVATED", - "lscType": "NOT_SUPPORTED", - "model": "225i", - "onlineSearchMode": "MAP", - "onlineSearchProvider": "GOOGLE", - "rangeMap": "NOT_SUPPORTED", - "remote360": "NOT_SUPPORTED", - "sendPoi": "ACTIVATED", - "smartSolution": "NOT_SUPPORTED", - "statisticsAvailable": false, - "statisticsCommunityEnabled": false, - "steering": "LH", - "vehicleFinder": "ACTIVATED", - "vehicleFinderRestriction": "NONE", - "vin": "F45_VIN", - "yearOfConstruction": 2016 - }, - { - "a4a": "USB_ONLY", - "bodytype": "F31", - "brand": "BMW", - "breakdownNumber": "+4989358957103", - "carCloud": "NOT_SUPPORTED", - "chargeNow": "NOT_SUPPORTED", - "chargingControl": "NOT_SUPPORTED", - "climateControl": "START_TIMER", - "climateControlRES": "NOT_SUPPORTED", - "climateFunction": "VENTILATION", - "climateNow": "ACTIVATED", - "climateNowRES": "NOT_SUPPORTED", - "color": "PLATINSILBER METALLIC", - "colorCode": "C08", - "countryCode": "V1-UK", - "dealer": { - "city": "Farnborough", - "country": "GB", - "name": "BMW (UK) Ltd. ICS - DIRECT SUPPLY", - "phone": "+44 1252 920000", - "postalCode": "GU14 0FB", - "street": "Summit ONE" - }, - "doorLock": "ACTIVATED", - "doorUnlock": "ACTIVATED", - "driveTrain": "CONV", - "fuelType": "DIESEL", - "hasAlarmSystem": true, - "hmiVersion": "ID4", - "hornBlow": "NOT_SUPPORTED", - "hub": "HUB_ECE", - "intermodalRouting": "NOT_AVAILABLE", - "ipa": "NOT_SUPPORTED", - "lastDestinations": "NOT_SUPPORTED", - "licensePlate": "some_license_plate", - "lightFlash": "ACTIVATED", - "lscType": "NOT_SUPPORTED", - "model": "320d", - "onlineSearchMode": "MAP", - "onlineSearchProvider": "GOOGLE", - "rangeMap": "NOT_SUPPORTED", - "remote360": "NOT_SUPPORTED", - "remoteSoftwareUpgrade": "NOT_SUPPORTED", - "sendPoi": "ACTIVATED", - "smartSolution": "NOT_SUPPORTED", - "statisticsAvailable": false, - "statisticsCommunityEnabled": false, - "steering": "RH", - "vehicleFinder": "ACTIVATED", - "vehicleFinderRestriction": "NONE", - "vin": "F31_VIN", - "yearOfConstruction": 2015 - }, - { - "a4a": "NOT_SUPPORTED", - "bodytype": "F35", - "brand": "BMW", - "breakdownNumber": "+4989358957103", - "carCloud": "NOT_SUPPORTED", - "chargeNow": "NOT_SUPPORTED", - "chargingControl": "NOT_SUPPORTED", - "climateControl": "NOT_SUPPORTED", - "climateControlRES": "NOT_SUPPORTED", - "climateFunction": "VENTILATION", - "climateNow": "NOT_SUPPORTED", - "climateNowRES": "NOT_SUPPORTED", - "color": "MINERALWEISS METALLIC", - "colorCode": "A96", - "countryCode": "V5-CN", - "dealer": { - "city": "Beijing", - "country": "CN", - "name": "Beijing Baozen Baiwang Automotive Sales Co., Ltd.", - "phone": "+86 10 62826789", - "postalCode": "100094", - "street": "F2 Baiwang Green Valley" - }, - "doorLock": "NOT_SUPPORTED", - "doorUnlock": "NOT_SUPPORTED", - "driveTrain": "CONV", - "fuelType": "PETROL", - "hasAlarmSystem": false, - "hmiVersion": "ID5", - "hornBlow": "NOT_SUPPORTED", - "hub": "HUB_CN", - "intermodalRouting": "NOT_AVAILABLE", - "ipa": "NOT_SUPPORTED", - "lastDestinations": "NOT_SUPPORTED", - "licensePlate": "some_license_plate", - "lightFlash": "NOT_SUPPORTED", - "lscType": "NOT_SUPPORTED", - "model": "328Li", - "onlineSearchMode": "MAP", - "rangeMap": "NOT_SUPPORTED", - "remote360": "NOT_SUPPORTED", - "remoteSoftwareUpgrade": "NOT_SUPPORTED", - "sendPoi": "NOT_SUPPORTED", - "smartSolution": "NOT_SUPPORTED", - "statisticsAvailable": false, - "statisticsCommunityEnabled": false, - "steering": "LH", - "vehicleFinder": "NOT_SUPPORTED", - "vin": "F31_VIN", - "yearOfConstruction": 2015 - } - ] + "vehicles": [ + { + "vehicleFinderRestriction": "NONE", + "doorUnlock": "ACTIVATED", + "color": "SOPHISTOGRAU BRILLANTEFFEKT METALLI", + "onlineSearchMode": "MAP", + "breakdownNumber": "+4912345678", + "smartSolution": "NOT_SUPPORTED", + "yearOfConstruction": 2018, + "driveTrain": "CONV", + "rangeMap": "NOT_SUPPORTED", + "vehicleFinder": "ACTIVATED", + "a4a": "BLUETOOTH", + "hornBlow": "ACTIVATED", + "chargeNow": "NOT_SUPPORTED", + "countryCode": "V6", + "bodytype": "G31", + "lightFlash": "ACTIVATED", + "vin": "G31_NBTevo_VIN", + "model": "530i xDrive", + "ipa": "NOT_SUPPORTED", + "brand": "BMW", + "climateControl": "DEPARTURE_TIMER", + "sendPoi": "ACTIVATED", + "lastDestinations": "NOT_SUPPORTED", + "doorLock": "ACTIVATED", + "chargingControl": "NOT_SUPPORTED", + "onlineSearchProvider": "GOOGLE", + "steering": "LH", + "intermodalRouting": "NOT_AVAILABLE", + "lscType": "LSC_BASIS", + "hasAlarmSystem": true, + "statisticsCommunityEnabled": false, + "climateNow": "ACTIVATED", + "fuelType": "PETROL", + "hub": "HUB_ECE", + "remote360": "NOT_SUPPORTED", + "hmiVersion": "ID5", + "climateFunction": "PARK_HEATING", + "colorCode": "A90", + "carCloud": "ACTIVATED", + "statisticsAvailable": false + }, + { + "vehicleFinderRestriction": "NONE", + "doorUnlock": "ACTIVATED", + "color": "ALPINWEISS III", + "onlineSearchMode": "MAP", + "breakdownNumber": "+4989358111111", + "smartSolution": "NOT_SUPPORTED", + "yearOfConstruction": 2017, + "driveTrain": "CONV", + "rangeMap": "NOT_SUPPORTED", + "vehicleFinder": "ACTIVATED", + "a4a": "BLUETOOTH", + "hornBlow": "ACTIVATED", + "chargeNow": "NOT_SUPPORTED", + "countryCode": "V1-NL", + "bodytype": "F48", + "lightFlash": "ACTIVATED", + "vin": "F48_VIN", + "model": "X1 sDrive18i", + "ipa": "NOT_SUPPORTED", + "brand": "BMW", + "climateControl": "START_TIMER", + "sendPoi": "ACTIVATED", + "lastDestinations": "NOT_SUPPORTED", + "doorLock": "ACTIVATED", + "chargingControl": "NOT_SUPPORTED", + "onlineSearchProvider": "GOOGLE", + "steering": "LH", + "intermodalRouting": "NOT_AVAILABLE", + "lscType": "LSC_BASIS", + "hasAlarmSystem": true, + "statisticsCommunityEnabled": false, + "climateNow": "ACTIVATED", + "fuelType": "PETROL", + "hub": "HUB_ECE", + "remote360": "NOT_SUPPORTED", + "hmiVersion": "ID5", + "dealer": { + "country": "NL", + "city": "city", + "phone": "phone", + "street": "street", + "postalCode": "1234 AB", + "name": "BMW dealer" + }, + "climateFunction": "VENTILATION", + "colorCode": "300", + "carCloud": "ACTIVATED", + "statisticsAvailable": false + }, + { + "vehicleFinderRestriction": "NONE", + "doorUnlock": "ACTIVATED", + "color": "ARRAVANIGRAU/BMW i BLAU", + "onlineSearchMode": "MAP", + "breakdownNumber": "+4989358957103", + "smartSolution": "NOT_SUPPORTED", + "yearOfConstruction": 2014, + "driveTrain": "BEV_REX", + "rangeMap": "RANGE_CIRCLE", + "vehicleFinder": "ACTIVATED", + "a4a": "USB_ONLY", + "hornBlow": "ACTIVATED", + "chargeNow": "NOT_SUPPORTED", + "licensePlate": "ABC000", + "countryCode": "V1-R1-SE", + "bodytype": "I01", + "lightFlash": "ACTIVATED", + "vin": "I01_VIN", + "model": "i3 (+ REX)", + "ipa": "NOT_SUPPORTED", + "brand": "BMW_I", + "climateControl": "NOT_SUPPORTED", + "sendPoi": "ACTIVATED", + "lastDestinations": "SUPPORTED", + "doorLock": "ACTIVATED", + "chargingControl": "WEEKLY_PLANNER", + "onlineSearchProvider": "GOOGLE", + "steering": "LH", + "intermodalRouting": "NOT_AVAILABLE", + "supportedChargingModes": [ + "AC_LOW", + "AC_HIGH", + "DC" + ], + "lscType": "I_LSC_IMM", + "hasAlarmSystem": false, + "statisticsCommunityEnabled": false, + "climateNow": "ACTIVATED", + "hub": "HUB_ECE", + "remote360": "NOT_SUPPORTED", + "hmiVersion": "ID4", + "dealer": { + "country": "SE", + "city": "Solna", + "phone": "+46 8 7353900", + "street": "G�rdsv�gen 9-11", + "postalCode": "169 70", + "name": "Bavaria Sverige Bil AB/ Solna" + }, + "climateFunction": "AIRCONDITIONING", + "colorCode": "B74", + "carCloud": "NOT_SUPPORTED", + "statisticsAvailable": true + }, + { + "vehicleFinderRestriction": "NONE", + "doorUnlock": "NOT_SUPPORTED", + "color": "BLACK SAPPHIRE METALLIC", + "onlineSearchMode": "MAP", + "breakdownNumber": "+4989358957103", + "smartSolution": "NOT_SUPPORTED", + "yearOfConstruction": 2017, + "driveTrain": "CONV", + "rangeMap": "NOT_SUPPORTED", + "vehicleFinder": "ACTIVATED", + "a4a": "BLUETOOTH", + "hornBlow": "ACTIVATED", + "chargeNow": "NOT_SUPPORTED", + "countryCode": "V2-CA", + "bodytype": "F15", + "lightFlash": "ACTIVATED", + "vin": "F15_VIN", + "model": "X5 xDrive35i", + "ipa": "NOT_SUPPORTED", + "brand": "BMW", + "climateControl": "DEPARTURE_TIMER", + "sendPoi": "ACTIVATED", + "lastDestinations": "NOT_SUPPORTED", + "doorLock": "ACTIVATED", + "chargingControl": "NOT_SUPPORTED", + "steering": "LH", + "intermodalRouting": "NOT_AVAILABLE", + "lscType": "LSC_BASIS", + "hasAlarmSystem": true, + "statisticsCommunityEnabled": false, + "climateNow": "ACTIVATED", + "fuelType": "PETROL", + "hub": "HUB_US", + "remote360": "NOT_SUPPORTED", + "hmiVersion": "ID5", + "dealer": { + "country": "CA", + "city": "Ottawa", + "phone": "1-866-599-4999", + "street": "85 Wellington St", + "postalCode": "K1A 1A1", + "name": "Parliament of Canada" + }, + "climateFunction": "VENTILATION", + "colorCode": "475", + "carCloud": "NOT_SUPPORTED", + "statisticsAvailable": false + }, + { + "vehicleFinderRestriction": "NONE", + "doorUnlock": "ACTIVATED", + "color": "SOLARORANGE MET. M. AKZENT FROZEN G", + "onlineSearchMode": "MAP", + "breakdownNumber": "+4989358957103", + "smartSolution": "NOT_SUPPORTED", + "yearOfConstruction": 2014, + "driveTrain": "BEV", + "rangeMap": "RANGE_CIRCLE", + "vehicleFinder": "ACTIVATED", + "a4a": "USB_ONLY", + "hornBlow": "ACTIVATED", + "chargeNow": "NOT_SUPPORTED", + "licensePlate": "HIDDEN", + "countryCode": "B3-ZA", + "bodytype": "I01", + "lightFlash": "ACTIVATED", + "vin": "I01_NOREX_VIN", + "model": "i3", + "ipa": "NOT_SUPPORTED", + "brand": "BMW_I", + "climateControl": "NOT_SUPPORTED", + "sendPoi": "ACTIVATED", + "lastDestinations": "SUPPORTED", + "doorLock": "ACTIVATED", + "chargingControl": "WEEKLY_PLANNER", + "onlineSearchProvider": "GOOGLE", + "steering": "RH", + "intermodalRouting": "NOT_AVAILABLE", + "supportedChargingModes": [ + "AC_LOW", + "AC_HIGH" + ], + "lscType": "I_LSC_IMM", + "hasAlarmSystem": true, + "statisticsCommunityEnabled": true, + "climateNow": "ACTIVATED", + "hub": "HUB_ECE", + "remote360": "NOT_SUPPORTED", + "hmiVersion": "ID4", + "dealer": { + "country": "ZA", + "city": "Midrand", + "phone": "+27 12 522 3000", + "street": "1 Bavaria Avenue", + "postalCode": "1685", + "name": "BMW (South Africa) (Pty) Ltd. ZA" + }, + "climateFunction": "AIRCONDITIONING", + "colorCode": "B78", + "carCloud": "NOT_SUPPORTED", + "statisticsAvailable": true + }, + { + "a4a": "USB_ONLY", + "bodytype": "F45", + "brand": "BMW", + "breakdownNumber": "+4989358957103", + "carCloud": "NOT_SUPPORTED", + "chargeNow": "NOT_SUPPORTED", + "chargingControl": "NOT_SUPPORTED", + "climateControl": "START_TIMER", + "climateFunction": "VENTILATION", + "climateNow": "ACTIVATED", + "color": "MEDITERRANBLAU METALLIC", + "colorCode": "C10", + "countryCode": "V1-ES", + "dealer": { + "city": "Madrid", + "country": "ES", + "name": "BMW Iberica S.A.", + "phone": "+34 913350505", + "postalCode": "28050", + "street": "Avenida de Burgos ,118" + }, + "doorLock": "ACTIVATED", + "doorUnlock": "ACTIVATED", + "driveTrain": "CONV", + "fuelType": "PETROL", + "hasAlarmSystem": false, + "hmiVersion": "ID4", + "hornBlow": "ACTIVATED", + "hub": "HUB_ECE", + "intermodalRouting": "NOT_AVAILABLE", + "ipa": "NOT_SUPPORTED", + "lastDestinations": "NOT_SUPPORTED", + "licensePlate": "some_license_plate", + "lightFlash": "ACTIVATED", + "lscType": "NOT_SUPPORTED", + "model": "225i", + "onlineSearchMode": "MAP", + "onlineSearchProvider": "GOOGLE", + "rangeMap": "NOT_SUPPORTED", + "remote360": "NOT_SUPPORTED", + "sendPoi": "ACTIVATED", + "smartSolution": "NOT_SUPPORTED", + "statisticsAvailable": false, + "statisticsCommunityEnabled": false, + "steering": "LH", + "vehicleFinder": "ACTIVATED", + "vehicleFinderRestriction": "NONE", + "vin": "F45_VIN", + "yearOfConstruction": 2016 + }, + { + "a4a": "USB_ONLY", + "bodytype": "F31", + "brand": "BMW", + "breakdownNumber": "+4989358957103", + "carCloud": "NOT_SUPPORTED", + "chargeNow": "NOT_SUPPORTED", + "chargingControl": "NOT_SUPPORTED", + "climateControl": "START_TIMER", + "climateControlRES": "NOT_SUPPORTED", + "climateFunction": "VENTILATION", + "climateNow": "ACTIVATED", + "climateNowRES": "NOT_SUPPORTED", + "color": "PLATINSILBER METALLIC", + "colorCode": "C08", + "countryCode": "V1-UK", + "dealer": { + "city": "Farnborough", + "country": "GB", + "name": "BMW (UK) Ltd. ICS - DIRECT SUPPLY", + "phone": "+44 1252 920000", + "postalCode": "GU14 0FB", + "street": "Summit ONE" + }, + "doorLock": "ACTIVATED", + "doorUnlock": "ACTIVATED", + "driveTrain": "CONV", + "fuelType": "DIESEL", + "hasAlarmSystem": true, + "hmiVersion": "ID4", + "hornBlow": "NOT_SUPPORTED", + "hub": "HUB_ECE", + "intermodalRouting": "NOT_AVAILABLE", + "ipa": "NOT_SUPPORTED", + "lastDestinations": "NOT_SUPPORTED", + "licensePlate": "some_license_plate", + "lightFlash": "ACTIVATED", + "lscType": "NOT_SUPPORTED", + "model": "320d", + "onlineSearchMode": "MAP", + "onlineSearchProvider": "GOOGLE", + "rangeMap": "NOT_SUPPORTED", + "remote360": "NOT_SUPPORTED", + "remoteSoftwareUpgrade": "NOT_SUPPORTED", + "sendPoi": "ACTIVATED", + "smartSolution": "NOT_SUPPORTED", + "statisticsAvailable": false, + "statisticsCommunityEnabled": false, + "steering": "RH", + "vehicleFinder": "ACTIVATED", + "vehicleFinderRestriction": "NONE", + "vin": "F31_VIN", + "yearOfConstruction": 2015 + }, + { + "a4a": "NOT_SUPPORTED", + "bodytype": "F35", + "brand": "BMW", + "breakdownNumber": "+4989358957103", + "carCloud": "NOT_SUPPORTED", + "chargeNow": "NOT_SUPPORTED", + "chargingControl": "NOT_SUPPORTED", + "climateControl": "NOT_SUPPORTED", + "climateControlRES": "NOT_SUPPORTED", + "climateFunction": "VENTILATION", + "climateNow": "NOT_SUPPORTED", + "climateNowRES": "NOT_SUPPORTED", + "color": "MINERALWEISS METALLIC", + "colorCode": "A96", + "countryCode": "V5-CN", + "dealer": { + "city": "Beijing", + "country": "CN", + "name": "Beijing Baozen Baiwang Automotive Sales Co., Ltd.", + "phone": "+86 10 62826789", + "postalCode": "100094", + "street": "F2 Baiwang Green Valley" + }, + "doorLock": "NOT_SUPPORTED", + "doorUnlock": "NOT_SUPPORTED", + "driveTrain": "CONV", + "fuelType": "PETROL", + "hasAlarmSystem": false, + "hmiVersion": "ID5", + "hornBlow": "NOT_SUPPORTED", + "hub": "HUB_CN", + "intermodalRouting": "NOT_AVAILABLE", + "ipa": "NOT_SUPPORTED", + "lastDestinations": "NOT_SUPPORTED", + "licensePlate": "some_license_plate", + "lightFlash": "NOT_SUPPORTED", + "lscType": "NOT_SUPPORTED", + "model": "328Li", + "onlineSearchMode": "MAP", + "rangeMap": "NOT_SUPPORTED", + "remote360": "NOT_SUPPORTED", + "remoteSoftwareUpgrade": "NOT_SUPPORTED", + "sendPoi": "NOT_SUPPORTED", + "smartSolution": "NOT_SUPPORTED", + "statisticsAvailable": false, + "statisticsCommunityEnabled": false, + "steering": "LH", + "vehicleFinder": "NOT_SUPPORTED", + "vin": "F31_VIN", + "yearOfConstruction": 2015 + }, + { + "vin": "ANONYMOUS", + "model": "318i", + "driveTrain": "CONV", + "brand": "BMW", + "yearOfConstruction": 2019, + "bodytype": "F31", + "color": "MINERALGRAU METALLIC", + "statisticsCommunityEnabled": false, + "statisticsAvailable": false, + "hasAlarmSystem": true, + "dealer": { + "name": "ANONYMOUS", + "street": "ANONYMOUS", + "postalCode": "ANONYMOUS", + "city": "ANONYMOUS", + "country": "ANONYMOUS", + "phone": "ANONYMOUS" + }, + "breakdownNumber": "ANONYMOUS", + "chargingControl": "NOT_SUPPORTED", + "vehicleFinder": "ACTIVATED", + "hornBlow": "ACTIVATED", + "lightFlash": "ACTIVATED", + "doorLock": "ACTIVATED", + "doorUnlock": "ACTIVATED", + "climateNow": "ACTIVATED", + "sendPoi": "ACTIVATED", + "remote360": "NOT_SUPPORTED", + "climateControl": "START_TIMER", + "chargeNow": "NOT_SUPPORTED", + "lastDestinations": "NOT_SUPPORTED", + "carCloud": "ACTIVATED", + "remoteSoftwareUpgrade": "NOT_SUPPORTED", + "climateNowRES": "NOT_SUPPORTED", + "climateControlRES": "NOT_SUPPORTED", + "smartSolution": "NOT_SUPPORTED", + "ipa": "NOT_SUPPORTED" + } + ] } From 02bfae2415ccdd4ab1feec20f716ff6cb0d35e27 Mon Sep 17 00:00:00 2001 From: Bernd Date: Mon, 21 Sep 2020 13:31:23 +0200 Subject: [PATCH 042/176] add service list interface Signed-off-by: Bernd (cherry picked from commit f6933f95eadafac4e578cb8aff2a3af0ed4d4a32) Signed-off-by: Bernd --- .../README.md | 33 +++- .../internal/ConnectedDriveConstants.java | 36 +++- .../internal/dto/status/VehicleStatus.java | 93 ++++++++-- .../handler/VehicleChannelHandler.java | 61 ++++++- .../internal/handler/VehicleHandler.java | 91 ++++++++-- .../internal/utils/Constants.java | 1 + .../i18n/bmwconnecteddrive_de.properties | 28 ++- .../thing/door-status-channel-types.xml | 54 ++++++ .../ESH-INF/thing/doors-status-group.xml | 24 +++ .../ESH-INF/thing/ev-last-trip-group.xml | 2 + .../ESH-INF/thing/hybrid-last-trip-group.xml | 19 ++ .../ESH-INF/thing/hybrid-lifetime-group.xml | 17 ++ ...-types.xml => last-trip-channel-types.xml} | 12 ++ ...l-types.xml => lifetime-channel-types.xml} | 4 + .../ESH-INF/thing/service-channel-types.xml | 30 ++++ .../resources/ESH-INF/thing/service-group.xml | 18 ++ .../resources/ESH-INF/thing/thing-bev.xml | 2 + .../resources/ESH-INF/thing/thing-bev_rex.xml | 6 +- .../resources/ESH-INF/thing/thing-conv.xml | 2 + .../resources/ESH-INF/thing/thing-phev.xml | 4 + .../thing/vehicle-status-channel-types.xml | 4 +- .../internal/dto/LifetimeWrapper.java | 156 +++++++++++++++++ .../internal/dto/StatusWrapper.java | 162 ++++++++++++++---- .../internal/dto/TripWrapper.java | 153 +++++++++++++++++ .../internal/handler/AllTripTests.java | 120 +++++++++++++ .../internal/handler/LastTripTests.java | 120 +++++++++++++ .../internal/handler/VehicleTests.java | 59 ++++--- .../resources/responses/530E/all-trips.json | 40 +++++ .../responses/530E/charge-profile.json | 42 +++++ .../resources/responses/530E/discovery.json | 46 +++++ .../resources/responses/530E/last-trip.json | 18 ++ .../test/resources/responses/530E/status.json | 72 ++++++++ .../resources/responses/F31/status-318i.json | 7 - .../responses/I01_REX/all-trips.json | 40 +++++ .../responses/I01_REX/charge-profile.json | 41 +++++ .../responses/I01_REX/discovery.json | 63 +++++++ .../responses/I01_REX/last-trip.json | 19 ++ .../src/test/resources/webapi/last-trip.json | 8 +- 38 files changed, 1591 insertions(+), 116 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/door-status-channel-types.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/doors-status-group.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-last-trip-group.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-lifetime-group.xml rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/{ev-last-trip-channel-types.xml => last-trip-channel-types.xml} (69%) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/{ev-lifetime-channel-types.xml => lifetime-channel-types.xml} (85%) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-channel-types.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-group.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AllTripTests.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/LastTripTests.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/all-trips.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/charge-profile.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/discovery.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/last-trip.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/status.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/all-trips.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/charge-profile.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/discovery.json create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/last-trip.json diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index dcef71c5c8f47..ba8a598f51cfb 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -148,8 +148,8 @@ Available for all Vehicles, Read-only. | Channel Label | Channel Group ID | Channel ID | Type | Description | |---------------------------|------------------|---------------------|---------------|----------------------------------------------------------------------| -| Door Status | status | doors | String | Closed if all closed, else reports the Door which is still open | -| Window Status | status | windows | String | Closed if all closed, else reports the Window which is still open | +| Overall Door Status | status | doors | String | Closed if all closed, else reports the Door which is still open | +| Overall Window Status | status | windows | String | Closed if all closed, else reports the Window which is still open | | Doors Locked | status | lock | String | Status if Doors are locked or unlocked | | Next Service Date | status | service-date | DateTime | Date of Upcoming Service | | Mileage till Next Service | status | service-mileage | Number:Length | Mileage till Upcoming Service | @@ -160,6 +160,34 @@ Available for all Vehicles, Read-only. See [further details for DateTime](#last-status-update-timestamp) in case of wrong timestamp values +#### Doors Details + +Detailed Status of all Doors and Windows +Available for all Vehicles, Read-only. + +| Channel Label | Channel Group ID | Channel ID | Type | +|----------------------------|------------------|-------------------------|---------------| +| Driver Door | doors | driver-front | String | +| Driver Door Rear | doors | driver-rear | String | +| Passenger Door | doors | passenger-front | String | +| Passenger Door Rear | doors | passenger-rear | String | +| Trunk | doors | trunk | String | +| Hood | doors | hood | String | +| Driver Door Window | doors | window-driver-front | String | +| Driver Door Rear Window | doors | window-driver-rear | String | +| Passenger Door Window | doors | window-passenger-front | String | +| Passenger Door Rear Window | doors | window-passenger-rear | String | +| Rear Window | doors | window-rear | String | +| Sunroof | doors | sunroof | String | + +Following Strings will be delivered + +* UNKNOWN - no status data available +* INVALID - this item isn't applicable for this Vehicle +* CLOSED - the Door / Window is closed +* OPEN - the Door / Window is open +* INTERMEDIATE - Window in intermediate position, not applicable for Doors + #### Range Data Based on Vehicle Type (Thing Type ID) some Channels are presented or not. @@ -221,6 +249,7 @@ These are Read-only values. | Channel Label | Channel Group ID | Channel ID | Type | |---------------------------------------|------------------|-------------------------|---------------| +| Last Trip Date | last-trip | distance | Number:Length | | Average Power Consumption per 100 km | last-trip | average-consumption | Number:Power | | Average Power Recuperation per 100 km | last-trip | average-recuperation | Number:Power | | Last Trip Distance | last-trip | distance | Number:Length | diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 4a0e2a40f28a3..964b24079cd1e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -103,6 +103,8 @@ public String toString() { // Thing Group definitions public static final String CHANNEL_GROUP_STATUS = "status"; + public static final String CHANNEL_GROUP_SERVICE = "service"; + public static final String CHANNEL_GROUP_DOORS = "doors"; public static final String CHANNEL_GROUP_RANGE = "range"; public static final String CHANNEL_GROUP_LOCATION = "location"; public static final String CHANNEL_GROUP_LAST_TRIP = "last-trip"; @@ -119,11 +121,30 @@ public String toString() { public static final String LOCK = "lock"; public static final String SERVICE_DATE = "service-date"; public static final String SERVICE_MILEAGE = "service-mileage"; - public static final String SERVICE_NAME = "service-name"; public static final String CHECK_CONTROL = "check-control"; public static final String CHARGE_STATUS = "charge"; public static final String LAST_UPDATE = "last-update"; + // Door Details + public static final String DOOR_DRIVER_FRONT = "driver-front"; + public static final String DOOR_DRIVER_REAR = "driver-rear"; + public static final String DOOR_PASSENGER_FRONT = "passenger-front"; + public static final String DOOR_PASSENGER_REAR = "passenger-rear"; + public static final String HOOD = "hood"; + public static final String TRUNK = "trunk"; + public static final String WINDOW_DOOR_DRIVER_FORNT = "window-driver-front"; + public static final String WINDOW_DOOR_DRIVER_REAR = "window-driver-rear"; + public static final String WINDOW_DOOR_PASSENGER_FRONT = "window-passenger-front"; + public static final String WINDOW_DOOR_PASSENGER_REAR = "window-passenger-rear"; + public static final String WINDOW_REAR = "window-rear"; + public static final String SUNROOF = "sunroof"; + + // Services + public static final String SERVICE_NAME = "service-name"; + public static final String SERVICE_TOTAL_COUNT = "service-total-count"; + public static final String SERVICE_INDEX = "service-index"; + public static final String SERVICE_NEXT = "service-next"; + // Charge Profile public static final String CHARGE_PROFILE_CLIMATE = "profile-climate"; public static final String CHARGE_PROFILE_MODE = "profile-mode"; @@ -150,16 +171,19 @@ public String toString() { public static final String RANGE_RADIUS_FUEL = "radius-fuel"; public static final String RANGE_RADIUS_HYBRID = "radius-hybrid"; - // Lifetime + // Last Trip + public static final String TRIP_DATE_TIME = "trip-date-time"; + public static final String TRIP_DURATION = "trip-duration"; + public static final String DISTANCE = "distance"; + public static final String DISTANCE_SINCE_CHARGING = "distance-since-charging"; public static final String AVG_CONSUMPTION = "average-consumption"; + public static final String AVG_COMBINED_CONSUMPTION = "average-combined-consumption"; public static final String AVG_RECUPERATION = "average-recuperation"; + + // Lifetime + Average Consumptions public static final String CUMULATED_DRIVEN_DISTANCE = "cumulated-driven-distance"; public static final String SINGLE_LONGEST_DISTANCE = "single-longest-distance"; - // Last Trip - public static final String DISTANCE = "distance"; - public static final String DISTANCE_SINCE_CHARGING = "distance-since-charging"; - // Lifetime public static final String LONGITUDE = "longitude"; public static final String LATITUDE = "latitude"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java index 19f7d65e86be3..9a8b2ef7cefaa 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java @@ -20,6 +20,8 @@ import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.gson.annotations.SerializedName; @@ -29,6 +31,8 @@ * @author Bernd Weymann - Initial contribution */ public class VehicleStatus { + private static final Logger logger = LoggerFactory.getLogger(VehicleStatus.class); + public int mileage;// ": 17273, public float remainingFuel;// ": 4, public float remainingRangeElectric;// ": 148, @@ -80,7 +84,7 @@ public class VehicleStatus { * @param imperial * @return */ - public CBSMessage getNextService(boolean imperial) { + public CBSMessage getNextService() { CBSMessage cbs = new CBSMessage(); if (cbsData == null) { return cbs; @@ -121,6 +125,58 @@ public CBSMessage getNextService(boolean imperial) { return cbs; } + public String getNextServiceDate() { + if (cbsData == null) { + return Constants.NULL_DATE; + } + if (cbsData.isEmpty()) { + return Constants.NULL_DATE; + } else { + LocalDateTime farFuture = LocalDateTime.now().plusYears(100); + LocalDateTime serviceDate = farFuture; + for (int i = 0; i < cbsData.size(); i++) { + CBSMessage entry = cbsData.get(i); + if (entry.cbsDueDate != null) { + LocalDateTime d = LocalDateTime.parse(entry.cbsDueDate + Constants.UTC_APPENDIX); + // LocalDate d = LocalDate.parse(entry.cbsDueDate + APPENDIX_DAY, + // Converter.SERVICE_DATE_INPUT_PATTERN); + if (d.isBefore(serviceDate)) { + serviceDate = d; + } + } + } + if (serviceDate.equals(farFuture)) { + return Constants.NULL_DATE; + } else { + return serviceDate.format(Converter.DATE_INPUT_PATTERN); + } + } + } + + public int getNextServiceMileage() { + if (cbsData == null) { + return -1; + } + if (cbsData.isEmpty()) { + return -1; + } else { + int serviceMileage = Integer.MAX_VALUE; + for (int i = 0; i < cbsData.size(); i++) { + CBSMessage entry = cbsData.get(i); + if (entry.cbsRemainingMileage != 0) { + if (entry.cbsRemainingMileage < serviceMileage) { + serviceMileage = entry.cbsRemainingMileage; + } + } + } + if (serviceMileage != Integer.MAX_VALUE) { + return serviceMileage; + } else { + return -1; + } + } + } + public String getCheckControl() { if (checkControlMessages == null) { return Converter.toTitleCase(UNKNOWN); @@ -150,34 +206,37 @@ public String getUpdateTime() { * @return Closed if all "Closed", "Open" otherwise */ public static String checkClosed(Object dto) { - boolean validObjectFound = false; + String overallState = Constants.UNKNOWN; for (Field field : dto.getClass().getDeclaredFields()) { try { Object d = field.get(dto); if (d != null) { String state = d.toString(); // skip invalid entries - they don't apply to this Vehicle - if (!state.equals(INVALID)) { - if (!state.equals(CLOSED)) { - // report the first field - remove DOOR / WINDOW Strings because they are reported to the - // corresponding Channel - String id = field.getName().toLowerCase().replace("door", Constants.EMPTY).replace("window", - Constants.EMPTY); - return Converter.toTitleCase(new StringBuffer(id).append(" ").append(state).toString()); - } else { + if (!state.equalsIgnoreCase(INVALID)) { + if (state.equalsIgnoreCase(OPEN)) { + overallState = OPEN; + // stop searching for more open items - overall Doors / Windows are OPEN + break; + } else if (state.equalsIgnoreCase(INTERMEDIATE)) { + if (!overallState.equalsIgnoreCase(OPEN)) { + overallState = INTERMEDIATE; + // continue searching - maybe another Door / Window is OPEN + } + } else if (state.equalsIgnoreCase(CLOSED)) { // at least one valid object needs to be found in order to reply "CLOSED" - validObjectFound = true; + if (overallState.equalsIgnoreCase(UNKNOWN)) { + overallState = CLOSED; + } + } else { + logger.debug("Unknown Status {} for Field {}", state, field); } } } } catch (IllegalArgumentException | IllegalAccessException e) { - return Converter.toTitleCase(UNKNOWN); + return UNKNOWN; } } - if (validObjectFound) { - return Converter.toTitleCase(CLOSED); - } else { - return Converter.toTitleCase(UNKNOWN); - } + return overallState; } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index bcee8c284b109..6112666312638 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -35,12 +35,32 @@ public class VehicleChannelHandler extends BaseThingHandler { protected ChannelUID doors; protected ChannelUID windows; protected ChannelUID lock; - protected ChannelUID serviceDate; - protected ChannelUID serviceMilage; - protected ChannelUID serviceDescription; + protected ChannelUID serviceNextDate; + protected ChannelUID serviceNextMileage; protected ChannelUID checkControl; protected ChannelUID lastUpdate; + protected ChannelUID serviceDate; + protected ChannelUID serviceMileage; + protected ChannelUID serviceName; + protected ChannelUID serviceCount; + protected ChannelUID serviceIndex; + protected ChannelUID serviceNext; + + protected ChannelUID doorDriverFront; + protected ChannelUID doorDriverRear; + protected ChannelUID doorPassengerFront; + protected ChannelUID doorPassengerRear; + protected ChannelUID doorHood; + protected ChannelUID doorTrunk; + + protected ChannelUID windowDriverFront; + protected ChannelUID windowDriverRear; + protected ChannelUID windowPassengerFront; + protected ChannelUID windowPassengerRear; + protected ChannelUID windowRear; + protected ChannelUID windowSunroof; + // Range channels protected ChannelUID mileage; protected ChannelUID remainingRangeHybrid; @@ -54,14 +74,18 @@ public class VehicleChannelHandler extends BaseThingHandler { // Lifetime Efficiency Channels protected ChannelUID lifeTimeAverageConsumption; + protected ChannelUID lifetimeAvgCombinedConsumption; protected ChannelUID lifeTimeAverageRecuperation; protected ChannelUID lifeTimeCumulatedDrivenDistance; protected ChannelUID lifeTimeSingleLongestDistance; // Last Trip Channels + protected ChannelUID tripDateTime; + protected ChannelUID tripDuration; protected ChannelUID tripDistance; protected ChannelUID tripDistanceSinceCharging; protected ChannelUID tripAvgConsumption; + protected ChannelUID tripAvgCombinedConsumption; protected ChannelUID tripAvgRecuperation; // Location Channels @@ -129,13 +153,33 @@ public VehicleChannelHandler(Thing thing) { doors = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, DOORS); windows = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, WINDOWS); lock = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, LOCK); - serviceDate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, SERVICE_DATE); - serviceMilage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, SERVICE_MILEAGE); - serviceDescription = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, SERVICE_NAME); + serviceNextDate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, SERVICE_DATE); + serviceNextMileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, SERVICE_MILEAGE); checkControl = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, CHECK_CONTROL); chargingStatus = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, CHARGE_STATUS); lastUpdate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, LAST_UPDATE); + serviceDate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, SERVICE_DATE); + serviceMileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, SERVICE_MILEAGE); + serviceName = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, SERVICE_NAME); + serviceCount = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, SERVICE_TOTAL_COUNT); + serviceIndex = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, SERVICE_INDEX); + serviceNext = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, SERVICE_NEXT); + + doorDriverFront = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, DOOR_DRIVER_FRONT); + doorDriverRear = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, DOOR_DRIVER_REAR); + doorPassengerFront = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, DOOR_PASSENGER_FRONT); + doorPassengerRear = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, DOOR_PASSENGER_REAR); + doorHood = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, HOOD); + doorTrunk = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, TRUNK); + + windowDriverFront = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, WINDOW_DOOR_DRIVER_FORNT); + windowDriverRear = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, WINDOW_DOOR_DRIVER_REAR); + windowPassengerFront = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, WINDOW_DOOR_PASSENGER_FRONT); + windowPassengerRear = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, WINDOW_DOOR_PASSENGER_REAR); + windowRear = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, WINDOW_REAR); + windowSunroof = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, SUNROOF); + // range Channels mileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, MILEAGE); remainingRangeHybrid = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, RANGE_HYBRID); @@ -148,13 +192,18 @@ public VehicleChannelHandler(Thing thing) { rangeRadiusHybrid = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, RANGE_RADIUS_HYBRID); // Last Trip Channels + tripDateTime = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, TRIP_DATE_TIME); + tripDuration = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, TRIP_DURATION); tripDistance = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, DISTANCE); tripDistanceSinceCharging = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, DISTANCE_SINCE_CHARGING); tripAvgConsumption = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, AVG_CONSUMPTION); + tripAvgCombinedConsumption = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, AVG_COMBINED_CONSUMPTION); tripAvgRecuperation = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, AVG_RECUPERATION); // Lifetime Channels lifeTimeAverageConsumption = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, AVG_CONSUMPTION); + lifetimeAvgCombinedConsumption = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, + AVG_COMBINED_CONSUMPTION); lifeTimeAverageRecuperation = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, AVG_RECUPERATION); lifeTimeCumulatedDrivenDistance = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, CUMULATED_DRIVEN_DISTANCE); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index a748006b2afbc..aa27488ac3bfc 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -14,6 +14,8 @@ import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -89,7 +91,7 @@ public class VehicleHandler extends VehicleChannelHandler { private ImageProperties imageProperties = new ImageProperties(); - StringResponseCallback vehicleStatusCallback = new VehicleStatusCallback(); + VehicleStatusCallback vehicleStatusCallback = new VehicleStatusCallback(); StringResponseCallback lastTripCallback = new LastTripCallback(); StringResponseCallback allTripsCallback = new AllTripsCallback(); StringResponseCallback chargeProfileCallback = new ChargeProfilesCallback(); @@ -199,6 +201,14 @@ public void handleCommand(ChannelUID channelUID, Command command) { } } } + if (channelUID.getIdWithoutGroup().equals(SERVICE_NEXT)) { + if (command instanceof OnOffType) { + if (command.equals(OnOffType.ON)) { + vehicleStatusCallback.next(); + updateState(channelUID, OnOffType.OFF); + } + } + } if (channelUID.getIdWithoutGroup().equals(VEHICLE_FINGERPRINT)) { // Log Troubleshoot data if (command instanceof OnOffType) { @@ -560,6 +570,8 @@ public void onResponse(Optional content) { .valueOf(Converter.round(c.chargecycleRange.userHigh), MetricPrefix.KILO(SIUnits.METRE))); updateState(lifeTimeAverageConsumption, QuantityType .valueOf(Converter.round(c.avgElectricConsumption.userAverage), SmartHomeUnits.KILOWATT_HOUR)); + updateState(lifetimeAvgCombinedConsumption, + QuantityType.valueOf(c.avgCombinedConsumption.userAverage, SmartHomeUnits.LITRE)); updateState(lifeTimeAverageRecuperation, QuantityType .valueOf(Converter.round(c.avgRecuperation.userAverage), SmartHomeUnits.KILOWATT_HOUR)); updateState(tripDistanceSinceCharging, QuantityType.valueOf( @@ -588,12 +600,14 @@ public void onResponse(Optional content) { if (trip == null) { return; } + updateState(tripDateTime, DateTimeType.valueOf(Converter.getLocalDateTime(trip.date))); + updateState(tripDuration, QuantityType.valueOf(trip.duration, SmartHomeUnits.MINUTE)); updateState(tripDistance, QuantityType.valueOf(Converter.round(trip.totalDistance), MetricPrefix.KILO(SIUnits.METRE))); - // updateState(tripDistanceSinceCharging, - // QuantityType.valueOf(entry.lastTrip, MetricPrefix.KILO(SIUnits.METRE))); updateState(tripAvgConsumption, QuantityType.valueOf(Converter.round(trip.avgElectricConsumption), SmartHomeUnits.KILOWATT_HOUR)); + updateState(tripAvgCombinedConsumption, + QuantityType.valueOf(trip.avgCombinedConsumption, SmartHomeUnits.LITRE)); updateState(tripAvgRecuperation, QuantityType.valueOf(Converter.round(trip.avgRecuperation), SmartHomeUnits.KILOWATT_HOUR)); } @@ -615,6 +629,8 @@ public void onError(NetworkError error) { @NonNullByDefault({}) public class VehicleStatusCallback implements StringResponseCallback { private ThingStatus thingStatus = ThingStatus.UNKNOWN; + private List services = new ArrayList(); + private int serviceIndexSelected = -1; /** * Vehicle Status is supported by all Vehicles so callback result is used to report Thing Status. @@ -630,6 +646,34 @@ private void setThingStatus(ThingStatus status, ThingStatusDetail detail, String } } + public void next() { + serviceIndexSelected++; + updateService(); + } + + private void updateService() { + if (services != null) { + updateState(serviceCount, new DecimalType(services.size())); + if (services.size() > 0) { + if (serviceIndexSelected < 0 || serviceIndexSelected >= services.size()) { + // select first item + serviceIndexSelected = 0; + } + CBSMessage entry = services.get(serviceIndexSelected); + updateState(serviceIndex, new DecimalType(serviceIndexSelected)); + updateState(serviceDate, DateTimeType.valueOf(Converter.getLocalDateTime(entry.getDueDate()))); + if (imperial) { + updateState(serviceMileage, + QuantityType.valueOf(Converter.round(entry.cbsRemainingMileage), ImperialUnits.MILE)); + } else { + updateState(serviceMileage, QuantityType.valueOf(Converter.round(entry.cbsRemainingMileage), + MetricPrefix.KILO(SIUnits.METRE))); + } + updateState(serviceName, StringType.valueOf(entry.getType())); + } + } + } + @Override public void onResponse(Optional content) { if (content.isPresent()) { @@ -646,20 +690,43 @@ public void onResponse(Optional content) { updateState(lock, StringType.valueOf(Converter.toTitleCase(vStatus.doorLockState))); Doors doorState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Doors.class); updateState(doors, StringType.valueOf(VehicleStatus.checkClosed(doorState))); + + updateState(doorDriverFront, StringType.valueOf(doorState.doorDriverFront)); + updateState(doorDriverRear, StringType.valueOf(doorState.doorDriverRear)); + updateState(doorPassengerFront, StringType.valueOf(doorState.doorPassengerFront)); + updateState(doorPassengerRear, StringType.valueOf(doorState.doorPassengerRear)); + updateState(doorTrunk, StringType.valueOf(doorState.trunk)); + updateState(doorHood, StringType.valueOf(doorState.hood)); + Windows windowState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Windows.class); updateState(windows, StringType.valueOf(VehicleStatus.checkClosed(windowState))); updateState(checkControl, StringType.valueOf(vStatus.getCheckControl())); - CBSMessage service = vStatus.getNextService(imperial); - updateState(serviceDate, DateTimeType.valueOf(Converter.getLocalDateTime(service.getDueDate()))); - updateState(serviceDescription, StringType.valueOf(Converter.toTitleCase(service.getType()))); - if (imperial) { - updateState(serviceMilage, - QuantityType.valueOf(Converter.round(service.cbsRemainingMileage), ImperialUnits.MILE)); - } else { - updateState(serviceMilage, QuantityType.valueOf(Converter.round(service.cbsRemainingMileage), - MetricPrefix.KILO(SIUnits.METRE))); + updateState(windowDriverFront, StringType.valueOf(windowState.windowDriverFront)); + updateState(windowDriverRear, StringType.valueOf(windowState.windowDriverRear)); + updateState(windowPassengerFront, StringType.valueOf(windowState.windowPassengerFront)); + updateState(windowPassengerRear, StringType.valueOf(windowState.windowPassengerRear)); + updateState(windowRear, StringType.valueOf(windowState.rearWindow)); + updateState(windowSunroof, StringType.valueOf(windowState.sunroof)); + + // Service Updates + String nextServiceDate = vStatus.getNextServiceDate(); + if (!nextServiceDate.equals(Constants.NULL_DATE)) { + updateState(serviceNextDate, DateTimeType.valueOf(Converter.getLocalDateTime(nextServiceDate))); } + double nextServiceMileage = vStatus.getNextServiceMileage(); + if (nextServiceMileage != Double.NaN) { + if (imperial) { + updateState(serviceNextMileage, + QuantityType.valueOf(Converter.round(nextServiceMileage), ImperialUnits.MILE)); + } else { + updateState(serviceNextMileage, QuantityType.valueOf(Converter.round(nextServiceMileage), + MetricPrefix.KILO(SIUnits.METRE))); + } + } + + services = vStatus.cbsData; + updateService(); // Range values // based on unit of length decide if range shall be reported in km or miles diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java index 8ed0887fb5668..0da6d9922734c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -29,6 +29,7 @@ public class Constants { public static final String OPEN = "OPEN"; public static final String INVALID = "INVALID"; public static final String CLOSED = "CLOSED"; + public static final String INTERMEDIATE = "INTERMEDIATE"; public static final String UNKNOWN = "UNKOWN"; public static final String NO_SERVICE_REQUEST = "No Service Requests"; public static final String UTC_APPENDIX = "-01T12:00:00"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_de.properties b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_de.properties index f41df79e09c98..f5623fd600e01 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_de.properties +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/i18n/bmwconnecteddrive_de.properties @@ -102,8 +102,12 @@ channel-group-type.bmwconnecteddrive.charge-values.label = Elektrisches Laden channel-group-type.bmwconnecteddrive.charge-values.description = Ladezustand und Ladeprofile des Fahrzeugs channel-group-type.bmwconnecteddrive.ev-lifetime-values.label = Gesamtlaufzeit Statistik channel-group-type.bmwconnecteddrive.ev-lifetime-values.description = Verbrauchswerte und zurückgelegte Strecken über die Fahrzeug-Gesamtlaufzeit +channel-group-type.bmwconnecteddrive.hybrid-lifetime-values.label = Gesamtlaufzeit Statistik +channel-group-type.bmwconnecteddrive.hybrid-lifetime-values.description = Verbrauchswerte und zurückgelegte Strecken über die Fahrzeug-Gesamtlaufzeit channel-group-type.bmwconnecteddrive.ev-last-trip-values.label = Statistik der letzten Fahrt channel-group-type.bmwconnecteddrive.ev-last-trip-values.description = Verbrauchswerte und zurück gelegte Strecke der letzten Fahrt +channel-group-type.bmwconnecteddrive.hybrid-last-trip-values.label = Statistik der letzten Fahrt +channel-group-type.bmwconnecteddrive.hybrid-last-trip-values.description = Verbrauchswerte und zurück gelegte Strecke der letzten Fahrt channel-group-type.bmwconnecteddrive.electric-range-values.label = Elektrische Reichweite channel-group-type.bmwconnecteddrive.electric-range-values.description = Tachostand, Reichweite und Ladestand des Fahrzeugs channel-group-type.bmwconnecteddrive.conv-range-values.label = Reichweite @@ -124,10 +128,12 @@ channel-group-type.bmwconnecteddrive.destination-values.label = Ziele channel-group-type.bmwconnecteddrive.destination-values.description = Zeigt die letzten 3 Ziele des Fahrzeugs channel-group-type.bmwconnecteddrive.troubleshoot-control.label = Fehlerbehebung channel-group-type.bmwconnecteddrive.troubleshoot-control.description = Generiert Daten zur Fehlerbehebung eines Problems +channel-group-type.bmwconnecteddrive.door-values.label = Details aller Türen +channel-group-type.bmwconnecteddrive.door-values.description = Zeigt die Dezails der Türen und Fenster des Fahrzeugs # Channel Types -channel-type.bmwconnecteddrive.doors-channel.label = Zustand der Türen -channel-type.bmwconnecteddrive.windows-channel.label = Zustand der Fenster +channel-type.bmwconnecteddrive.doors-channel.label = Gesamtzustand der Türen +channel-type.bmwconnecteddrive.windows-channel.label = Gesamtzustand der Fenster channel-type.bmwconnecteddrive.lock-channel.label = Fahrzeug Abgeschlossen channel-type.bmwconnecteddrive.service-date-channel.label = Nächstes Service Datum channel-type.bmwconnecteddrive.service-mileage-channel.label = Nächster Service in Kilometern @@ -136,6 +142,19 @@ channel-type.bmwconnecteddrive.check-control-channel.label = Aktuelle Warnung channel-type.bmwconnecteddrive.charging-status-channel.label = Ladezustand channel-type.bmwconnecteddrive.last-update-channel.label = Letzte Aktualisierung +channel-type.bmwconnecteddrive.driver-front-channel.label = Fahrertür +channel-type.bmwconnecteddrive.driver-rear-channel.label = Fahrertür Hinten +channel-type.bmwconnecteddrive.passenger-front-channel.label = Beifahrertür +channel-type.bmwconnecteddrive.passenger-rear-channel.label = Beifahrertür Hinten +channel-type.bmwconnecteddrive.hood-channel.label = Frontklappe +channel-type.bmwconnecteddrive.trunk-channel.label = Heckklappe +channel-type.bmwconnecteddrive.window-driver-front-channel.label = Fahrertür Fenster +channel-type.bmwconnecteddrive.window-driver-rear-channel.label = Fahrertür Hinten Fenster +channel-type.bmwconnecteddrive.window-passenger-front-channel.label = Beifahrertür Fenster +channel-type.bmwconnecteddrive.window-passenger-rear-channel.label = Beifahrertür Hinten Fenster +channel-type.bmwconnecteddrive.window-rear-channel.label = Heckfenster +channel-type.bmwconnecteddrive.sunroof-channel.label = Schiebedach + channel-type.bmwconnecteddrive.mileage-channel.label = Tachostand channel-type.bmwconnecteddrive.range-hybrid-channel.label = Hybride Reichweite channel-type.bmwconnecteddrive.range-electric-channel.label = Elektrische Reichweite @@ -174,9 +193,12 @@ channel-type.bmwconnecteddrive.longitude-channel.label = L channel-type.bmwconnecteddrive.latitude-channel.label = Breitengrad channel-type.bmwconnecteddrive.heading-channel.label = Ausrichtung -channel-type.bmwconnecteddrive.distance-channel.label = Distanz der letzten Fahr +channel-type.bmwconnecteddrive.trip-date-time-channel.label = Datum +channel-type.bmwconnecteddrive.trip-duration-channel.label = Dauer +channel-type.bmwconnecteddrive.distance-channel.label = Distanz channel-type.bmwconnecteddrive.distance-since-charging-channel.label = Distanz seit letzter Ladung channel-type.bmwconnecteddrive.average-consumption-channel.label = kw/h Verbrauch über 100 km +channel-type.bmwconnecteddrive.average-combined-consumption-channel.label = Liter Verbrauch kombiniert über 100 km channel-type.bmwconnecteddrive.average-recuperation-channel.label = kw/h Rekuperation über 100 km channel-type.bmwconnecteddrive.cumulated-driven-distance-channel.label = Elektrisch gefahrene Distanz channel-type.bmwconnecteddrive.single-longest-distance-channel.label = Längste Fahrt mit einer Ladung diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/door-status-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/door-status-channel-types.xml new file mode 100644 index 0000000000000..00495611c94fb --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/door-status-channel-types.xml @@ -0,0 +1,54 @@ + + + + String + + + + String + + + + String + + + + String + + + + String + + + + String + + + + String + + + + String + + + + String + + + + String + + + + String + + + + String + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/doors-status-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/doors-status-group.xml new file mode 100644 index 0000000000000..2658539819f57 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/doors-status-group.xml @@ -0,0 +1,24 @@ + + + + + Detailed Status of all Doors and Windows + + + + + + + + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-group.xml index bf3d76536abcf..390ae86d1f3f2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-group.xml @@ -7,6 +7,8 @@ EV Consumption Values and Distances for the Last Trip + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-last-trip-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-last-trip-group.xml new file mode 100644 index 0000000000000..1bec67cc336f4 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-last-trip-group.xml @@ -0,0 +1,19 @@ + + + + + Hybrid Consumption Values and Distances for the Last Trip + + + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-lifetime-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-lifetime-group.xml new file mode 100644 index 0000000000000..8e86a89ab0470 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/hybrid-lifetime-group.xml @@ -0,0 +1,17 @@ + + + + + Consumption Values and Distances over Lifetime + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/last-trip-channel-types.xml similarity index 69% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-channel-types.xml rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/last-trip-channel-types.xml index 90b4092f31b51..50b08f40e9930 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-last-trip-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/last-trip-channel-types.xml @@ -3,6 +3,14 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> + + DateTime + + + + Number:Time + + Number:Length @@ -15,6 +23,10 @@ Number:Energy + + Number:Volume + + Number:Energy diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/lifetime-channel-types.xml similarity index 85% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-channel-types.xml rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/lifetime-channel-types.xml index 84144a642b12d..f26d0a3a5e8a9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/ev-lifetime-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/lifetime-channel-types.xml @@ -15,6 +15,10 @@ Number:Length + + Number:Volume + + Number:Length diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-channel-types.xml new file mode 100644 index 0000000000000..47eae32696bfc --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-channel-types.xml @@ -0,0 +1,30 @@ + + + + Number + + + + Number + + + + DateTime + + + + Number:Length + + + + String + + + + Switch + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-group.xml new file mode 100644 index 0000000000000..7c2b1154e52ea --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-group.xml @@ -0,0 +1,18 @@ + + + + + All future Service schedules + + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml index 5f99028879ded..811986ccf9aef 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml @@ -14,7 +14,9 @@ + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml index 5994336075d93..8679d09508866 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml @@ -14,12 +14,14 @@ + + - - + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml index 68d702fbc8447..b0bd4123921fb 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml @@ -14,7 +14,9 @@ + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml index f731b24a966a3..9c190b23e09cd 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml @@ -14,10 +14,14 @@ + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml index 39898db2f4a81..923ab11171121 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/vehicle-status-channel-types.xml @@ -5,11 +5,11 @@ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> String - + String - + String diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java new file mode 100644 index 0000000000000..c5852878df6b3 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java @@ -0,0 +1,156 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; + +import static org.junit.Assert.*; +import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.measure.Unit; +import javax.measure.quantity.Length; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.library.types.DateTimeType; +import org.eclipse.smarthome.core.library.types.DecimalType; +import org.eclipse.smarthome.core.library.types.QuantityType; +import org.eclipse.smarthome.core.library.types.StringType; +import org.eclipse.smarthome.core.library.unit.MetricPrefix; +import org.eclipse.smarthome.core.library.unit.SIUnits; +import org.eclipse.smarthome.core.library.unit.SmartHomeUnits; +import org.eclipse.smarthome.core.thing.ChannelUID; +import org.eclipse.smarthome.core.types.State; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; +import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTrips; +import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTripsContainer; + +import com.google.gson.Gson; + +/** + * The {@link LifetimeWrapper} Test json responses from ConnectedDrive Portal + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class LifetimeWrapper { + private static final Gson GSON = new Gson(); + private static final Unit KILOMETRE = MetricPrefix.KILO(SIUnits.METRE); + + private AllTrips allTrips; + private boolean imperial; + private boolean isElectric; + private boolean hasFuel; + private boolean isHybrid; + + private Map specialHandlingMap = new HashMap(); + + public LifetimeWrapper(String type, boolean imperial, String statusJson) { + this.imperial = imperial; + hasFuel = type.equals(VehicleType.CONVENTIONAL.toString()) || type.equals(VehicleType.PLUGIN_HYBRID.toString()) + || type.equals(VehicleType.ELECTRIC_REX.toString()); + isElectric = type.equals(VehicleType.PLUGIN_HYBRID.toString()) + || type.equals(VehicleType.ELECTRIC_REX.toString()) || type.equals(VehicleType.ELECTRIC.toString()); + isHybrid = hasFuel && isElectric; + AllTripsContainer container = GSON.fromJson(statusJson, AllTripsContainer.class); + assertNotNull(container); + assertNotNull(container.allTrips); + allTrips = container.allTrips; + } + + /** + * Test results auctomatically against json values + * + * @param channels + * @param states + * @return + */ + public boolean checkResults(@Nullable List channels, @Nullable List states) { + assertNotNull(channels); + assertNotNull(states); + assertTrue("Same list sizes ", channels.size() == states.size()); + for (int i = 0; i < channels.size(); i++) { + checkResult(channels.get(i), states.get(i)); + } + return true; + } + + /** + * Add a specific check for a value e.g. hard coded "Upcoming Service" in order to check the right ordering + * + * @param specialHand + * @return + */ + public LifetimeWrapper append(Map compareMap) { + specialHandlingMap.putAll(compareMap); + return this; + } + + private void checkResult(ChannelUID channelUID, State state) { + String cUid = channelUID.getIdWithoutGroup(); + QuantityType qt; + StringType st; + StringType wanted; + DateTimeType dtt; + DecimalType dt; + switch (cUid) { + case DISTANCE_SINCE_CHARGING: + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + assertEquals("KM", KILOMETRE, qt.getUnit()); + assertEquals("Distance since charging", allTrips.chargecycleRange.userCurrentChargeCycle, + qt.floatValue(), 0.1); + break; + case SINGLE_LONGEST_DISTANCE: + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + assertEquals("KM", KILOMETRE, qt.getUnit()); + assertEquals("Longest Distance", allTrips.chargecycleRange.userHigh, qt.floatValue(), 0.1); + break; + case CUMULATED_DRIVEN_DISTANCE: + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + assertEquals("KM", KILOMETRE, qt.getUnit()); + assertEquals("Cumulated Distance", allTrips.totalElectricDistance.userTotal, qt.floatValue(), 0.1); + break; + case AVG_CONSUMPTION: + assertTrue("Is Electric", isElectric); + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + assertEquals("kw", SmartHomeUnits.KILOWATT_HOUR, qt.getUnit()); + assertEquals("Avg Consumption", allTrips.avgElectricConsumption.userAverage, qt.floatValue(), 0.1); + break; + case AVG_RECUPERATION: + assertTrue("Is Electric", isElectric); + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + assertEquals("kw", SmartHomeUnits.KILOWATT_HOUR, qt.getUnit()); + assertEquals("Avg Recuperation", allTrips.avgRecuperation.userAverage, qt.floatValue(), 0.1); + break; + case AVG_COMBINED_CONSUMPTION: + assertTrue("Is Hybrid", isHybrid); + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + assertEquals("Liter", SmartHomeUnits.LITRE, qt.getUnit()); + assertEquals("Avg Combined Consumption", allTrips.avgCombinedConsumption.userAverage, qt.floatValue(), + 0.01); + break; + default: + // fail in case of unknown update + assertFalse("Channel " + channelUID + " " + state + " not found", true); + break; + } + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index 61871d5707d73..da9acba569156 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -105,8 +105,10 @@ public StatusWrapper append(Map compareMap) { private void checkResult(ChannelUID channelUID, State state) { String cUid = channelUID.getIdWithoutGroup(); + String gUid = channelUID.getGroupId(); QuantityType qt; StringType st; + StringType wanted; DateTimeType dtt; DecimalType dt; switch (cUid) { @@ -207,38 +209,6 @@ private void checkResult(ChannelUID channelUID, State state) { assertEquals("Check Control", vStatus.getCheckControl(), st.toString()); } break; - case SERVICE_DATE: - assertTrue(state instanceof DateTimeType); - dtt = (DateTimeType) state; - if (specialHandlingMap.containsKey(SERVICE_DATE)) { - assertEquals("Next Service", specialHandlingMap.get(SERVICE_DATE).toString(), dtt.toString()); - } else { - String dueDateString = vStatus.getNextService(imperial).getDueDate(); - DateTimeType expectedDTT = DateTimeType.valueOf(Converter.getLocalDateTime(dueDateString)); - assertEquals("Next Service", expectedDTT.toString(), dtt.toString()); - } - break; - case SERVICE_MILEAGE: - assertTrue(state instanceof QuantityType); - qt = ((QuantityType) state); - if (imperial) { - assertEquals("Next Service Miles", ImperialUnits.MILE, qt.getUnit()); - assertEquals("Mileage", vStatus.getNextService(imperial).cbsRemainingMileage, qt.intValue()); - } else { - assertEquals("Next Service KM", KILOMETRE, qt.getUnit()); - assertEquals("Mileage", vStatus.getNextService(imperial).cbsRemainingMileage, qt.intValue()); - } - break; - case SERVICE_NAME: - assertTrue(state instanceof StringType); - st = (StringType) state; - if (specialHandlingMap.containsKey(SERVICE_NAME)) { - assertEquals("Next Service Name", specialHandlingMap.get(SERVICE_NAME).toString(), st.toString()); - } else { - assertEquals("Next Service Name", Converter.toTitleCase(vStatus.getNextService(imperial).getType()), - st.toString()); - } - break; case CHARGE_STATUS: assertTrue("Is Eelctric", isElectric); assertTrue(state instanceof StringType); @@ -314,6 +284,134 @@ private void checkResult(ChannelUID channelUID, State state) { qt.floatValue(), 0.1); } break; + case DOOR_DRIVER_FRONT: + assertTrue(state instanceof StringType); + st = (StringType) state; + wanted = StringType.valueOf(vStatus.doorDriverFront); + assertEquals("Door", wanted.toString(), st.toString()); + break; + case DOOR_DRIVER_REAR: + assertTrue(state instanceof StringType); + st = (StringType) state; + wanted = StringType.valueOf(vStatus.doorDriverRear); + assertEquals("Door", wanted.toString(), st.toString()); + break; + case DOOR_PASSENGER_FRONT: + assertTrue(state instanceof StringType); + st = (StringType) state; + wanted = StringType.valueOf(vStatus.doorPassengerFront); + assertEquals("Door", wanted.toString(), st.toString()); + break; + case DOOR_PASSENGER_REAR: + assertTrue(state instanceof StringType); + st = (StringType) state; + wanted = StringType.valueOf(vStatus.doorPassengerRear); + assertEquals("Door", wanted.toString(), st.toString()); + break; + case TRUNK: + assertTrue(state instanceof StringType); + st = (StringType) state; + wanted = StringType.valueOf(vStatus.trunk); + assertEquals("Door", wanted.toString(), st.toString()); + break; + case HOOD: + assertTrue(state instanceof StringType); + st = (StringType) state; + wanted = StringType.valueOf(vStatus.hood); + assertEquals("Door", wanted.toString(), st.toString()); + break; + case WINDOW_DOOR_DRIVER_FORNT: + assertTrue(state instanceof StringType); + st = (StringType) state; + wanted = StringType.valueOf(vStatus.windowDriverFront); + assertEquals("Window", wanted.toString(), st.toString()); + break; + case WINDOW_DOOR_DRIVER_REAR: + assertTrue(state instanceof StringType); + st = (StringType) state; + wanted = StringType.valueOf(vStatus.windowDriverRear); + assertEquals("Window", wanted.toString(), st.toString()); + break; + case WINDOW_DOOR_PASSENGER_FRONT: + assertTrue(state instanceof StringType); + st = (StringType) state; + wanted = StringType.valueOf(vStatus.windowPassengerFront); + assertEquals("Window", wanted.toString(), st.toString()); + break; + case WINDOW_DOOR_PASSENGER_REAR: + assertTrue(state instanceof StringType); + st = (StringType) state; + wanted = StringType.valueOf(vStatus.windowPassengerRear); + assertEquals("Window", wanted.toString(), st.toString()); + break; + case WINDOW_REAR: + assertTrue(state instanceof StringType); + st = (StringType) state; + wanted = StringType.valueOf(vStatus.rearWindow); + assertEquals("Window", wanted.toString(), st.toString()); + break; + case SUNROOF: + assertTrue(state instanceof StringType); + st = (StringType) state; + wanted = StringType.valueOf(vStatus.sunroof); + assertEquals("Window", wanted.toString(), st.toString()); + break; + case SERVICE_TOTAL_COUNT: + assertTrue(state instanceof DecimalType); + dt = (DecimalType) state; + assertEquals("Number of Services", vStatus.cbsData.size(), dt.intValue()); + break; + case SERVICE_INDEX: + assertTrue(state instanceof DecimalType); + dt = (DecimalType) state; + assertEquals("Number of Services", 0, dt.intValue()); + break; + case SERVICE_DATE: + assertTrue(state instanceof DateTimeType); + dtt = (DateTimeType) state; + if (gUid.contentEquals(CHANNEL_GROUP_STATUS)) { + if (specialHandlingMap.containsKey(SERVICE_DATE)) { + assertEquals("Next Service", specialHandlingMap.get(SERVICE_DATE).toString(), dtt.toString()); + } else { + String dueDateString = vStatus.getNextServiceDate(); + DateTimeType expectedDTT = DateTimeType.valueOf(Converter.getLocalDateTime(dueDateString)); + assertEquals("Next Service", expectedDTT.toString(), dtt.toString()); + } + } else if (gUid.equals(CHANNEL_GROUP_SERVICE)) { + String dueDateString = vStatus.cbsData.get(0).getDueDate(); + DateTimeType expectedDTT = DateTimeType.valueOf(Converter.getLocalDateTime(dueDateString)); + assertEquals("First Service Date", expectedDTT.toString(), dtt.toString()); + } + break; + case SERVICE_MILEAGE: + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + if (gUid.contentEquals(CHANNEL_GROUP_STATUS)) { + if (imperial) { + assertEquals("Next Service Miles", ImperialUnits.MILE, qt.getUnit()); + assertEquals("Mileage", vStatus.getNextServiceMileage(), qt.intValue()); + } else { + assertEquals("Next Service KM", KILOMETRE, qt.getUnit()); + assertEquals("Mileage", vStatus.getNextServiceMileage(), qt.intValue()); + } + } else if (gUid.equals(CHANNEL_GROUP_SERVICE)) { + if (imperial) { + assertEquals("First Service Miles", ImperialUnits.MILE, qt.getUnit()); + assertEquals("First Service Mileage", vStatus.cbsData.get(0).cbsRemainingMileage, + qt.intValue()); + } else { + assertEquals("First Service KM", KILOMETRE, qt.getUnit()); + assertEquals("First Service Mileage", vStatus.cbsData.get(0).cbsRemainingMileage, + qt.intValue()); + } + } + break; + case SERVICE_NAME: + assertTrue(state instanceof StringType); + st = (StringType) state; + wanted = StringType.valueOf(vStatus.cbsData.get(0).getType()); + assertEquals("Window", wanted.toString(), st.toString()); + break; default: // fail in case of unknown update assertFalse("Channel " + channelUID + " " + state + " not found", true); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java new file mode 100644 index 0000000000000..378a7b1d3d612 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java @@ -0,0 +1,153 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; + +import static org.junit.Assert.*; +import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.measure.Unit; +import javax.measure.quantity.Length; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.library.types.DateTimeType; +import org.eclipse.smarthome.core.library.types.DecimalType; +import org.eclipse.smarthome.core.library.types.QuantityType; +import org.eclipse.smarthome.core.library.types.StringType; +import org.eclipse.smarthome.core.library.unit.MetricPrefix; +import org.eclipse.smarthome.core.library.unit.SIUnits; +import org.eclipse.smarthome.core.library.unit.SmartHomeUnits; +import org.eclipse.smarthome.core.thing.ChannelUID; +import org.eclipse.smarthome.core.types.State; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; +import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTrip; +import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTripContainer; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; + +import com.google.gson.Gson; + +/** + * The {@link TripWrapper} Test json responses from ConnectedDrive Portal + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class TripWrapper { + private static final Gson GSON = new Gson(); + private static final Unit KILOMETRE = MetricPrefix.KILO(SIUnits.METRE); + + private LastTrip lastTrip; + private boolean imperial; + private boolean isElectric; + private boolean hasFuel; + private boolean isHybrid; + + private Map specialHandlingMap = new HashMap(); + + public TripWrapper(String type, boolean imperial, String statusJson) { + this.imperial = imperial; + hasFuel = type.equals(VehicleType.CONVENTIONAL.toString()) || type.equals(VehicleType.PLUGIN_HYBRID.toString()) + || type.equals(VehicleType.ELECTRIC_REX.toString()); + isElectric = type.equals(VehicleType.PLUGIN_HYBRID.toString()) + || type.equals(VehicleType.ELECTRIC_REX.toString()) || type.equals(VehicleType.ELECTRIC.toString()); + isHybrid = hasFuel && isElectric; + LastTripContainer container = GSON.fromJson(statusJson, LastTripContainer.class); + assertNotNull(container); + assertNotNull(container.lastTrip); + lastTrip = container.lastTrip; + } + + /** + * Test results auctomatically against json values + * + * @param channels + * @param states + * @return + */ + public boolean checkResults(@Nullable List channels, @Nullable List states) { + assertNotNull(channels); + assertNotNull(states); + assertTrue("Same list sizes ", channels.size() == states.size()); + for (int i = 0; i < channels.size(); i++) { + checkResult(channels.get(i), states.get(i)); + } + return true; + } + + /** + * Add a specific check for a value e.g. hard coded "Upcoming Service" in order to check the right ordering + * + * @param specialHand + * @return + */ + public TripWrapper append(Map compareMap) { + specialHandlingMap.putAll(compareMap); + return this; + } + + private void checkResult(ChannelUID channelUID, State state) { + String cUid = channelUID.getIdWithoutGroup(); + QuantityType qt; + StringType st; + StringType wanted; + DateTimeType dtt; + DecimalType dt; + switch (cUid) { + case TRIP_DATE_TIME: + assertTrue(state instanceof DateTimeType); + dtt = ((DateTimeType) state); + DateTimeType expected = DateTimeType.valueOf(Converter.getLocalDateTime(lastTrip.date)); + assertEquals("Trip Date", expected.toString(), dtt.toString()); + break; + case TRIP_DURATION: + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + assertEquals("Minute", SmartHomeUnits.MINUTE, qt.getUnit()); + assertEquals("Duration", lastTrip.duration, qt.floatValue(), 0.1); + break; + case DISTANCE: + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + assertEquals("KM", KILOMETRE, qt.getUnit()); + assertEquals("Distance", lastTrip.totalDistance, qt.floatValue(), 0.1); + break; + case AVG_CONSUMPTION: + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + assertEquals("kw", SmartHomeUnits.KILOWATT_HOUR, qt.getUnit()); + assertEquals("Avg Consumption", lastTrip.avgElectricConsumption, qt.floatValue(), 0.1); + break; + case AVG_COMBINED_CONSUMPTION: + assertTrue("Is Hybrid", isHybrid); + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + assertEquals("Liter", SmartHomeUnits.LITRE, qt.getUnit()); + assertEquals("Percent", Converter.round(lastTrip.avgCombinedConsumption), qt.floatValue(), 0.01); + break; + case AVG_RECUPERATION: + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + assertEquals("kw", SmartHomeUnits.KILOWATT_HOUR, qt.getUnit()); + assertEquals("Avg Recuperation", lastTrip.avgRecuperation, qt.floatValue(), 0.1); + break; + default: + // fail in case of unknown update + assertFalse("Channel " + channelUID + " " + state + " not found", true); + break; + } + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AllTripTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AllTripTests.java new file mode 100644 index 0000000000000..5a84b000e6868 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AllTripTests.java @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.smarthome.core.thing.ChannelUID; +import org.eclipse.smarthome.core.thing.Thing; +import org.eclipse.smarthome.core.thing.ThingUID; +import org.eclipse.smarthome.core.thing.binding.ThingHandlerCallback; +import org.eclipse.smarthome.core.types.State; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; +import org.openhab.binding.bmwconnecteddrive.internal.dto.LifetimeWrapper; +import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link AllTripTests} is responsible for handling commands, which are + * sent to one of the channels. + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class AllTripTests { + private final Logger logger = LoggerFactory.getLogger(VehicleHandler.class); + + private static final int HYBRID_CALL_TIMES = 6; + + @Nullable + ArgumentCaptor channelCaptor; + @Nullable + ArgumentCaptor stateCaptor; + @Nullable + ThingHandlerCallback tc; + @Nullable + VehicleHandler cch; + @Nullable + List allChannels; + @Nullable + List allStates; + String driveTrain = Constants.EMPTY; + boolean imperial; + + /** + * Prepare environment for Vehicle Status Updates + */ + public void setup(String type, boolean imperial) { + driveTrain = type; + this.imperial = imperial; + Thing thing = mock(Thing.class); + when(thing.getUID()).thenReturn(new ThingUID("testbinding", "test")); + HttpClient hc = mock(HttpClient.class); + cch = new VehicleHandler(thing, hc, type, imperial); + tc = mock(ThingHandlerCallback.class); + cch.setCallback(tc); + channelCaptor = ArgumentCaptor.forClass(ChannelUID.class); + stateCaptor = ArgumentCaptor.forClass(State.class); + } + + private boolean testTrip(String statusContent, int callbacksExpected, Optional> concreteChecks) { + assertNotNull(statusContent); + cch.allTripsCallback.onResponse(Optional.of(statusContent)); + verify(tc, times(callbacksExpected)).stateUpdated(channelCaptor.capture(), stateCaptor.capture()); + allChannels = channelCaptor.getAllValues(); + allStates = stateCaptor.getAllValues(); + + assertNotNull(driveTrain); + LifetimeWrapper checker = new LifetimeWrapper(driveTrain, imperial, statusContent); + trace(); + if (concreteChecks.isPresent()) { + return checker.append(concreteChecks.get()).checkResults(allChannels, allStates); + } else { + return checker.checkResults(allChannels, allStates); + } + } + + private void trace() { + for (int i = 0; i < allChannels.size(); i++) { + logger.info("Channel {} {}", allChannels.get(i), allStates.get(i)); + } + } + + @Test + public void testi3Rex() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(VehicleType.ELECTRIC_REX.toString(), false); + String content = FileReader.readFileInString("src/test/resources/responses/I01_REX/all-trips.json"); + assertTrue(testTrip(content, HYBRID_CALL_TIMES, Optional.empty())); + } + + @Test + public void test530E() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(VehicleType.PLUGIN_HYBRID.toString(), false); + String content = FileReader.readFileInString("src/test/resources/responses/530E/all-trips.json"); + assertTrue(testTrip(content, HYBRID_CALL_TIMES, Optional.empty())); + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/LastTripTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/LastTripTests.java new file mode 100644 index 0000000000000..613080be89424 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/LastTripTests.java @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.smarthome.core.thing.ChannelUID; +import org.eclipse.smarthome.core.thing.Thing; +import org.eclipse.smarthome.core.thing.ThingUID; +import org.eclipse.smarthome.core.thing.binding.ThingHandlerCallback; +import org.eclipse.smarthome.core.types.State; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; +import org.openhab.binding.bmwconnecteddrive.internal.dto.TripWrapper; +import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The {@link LastTripTests} is responsible for handling commands, which are + * sent to one of the channels. + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class LastTripTests { + private final Logger logger = LoggerFactory.getLogger(VehicleHandler.class); + + private static final int HYBRID_CALL_TIMES = 6; + + @Nullable + ArgumentCaptor channelCaptor; + @Nullable + ArgumentCaptor stateCaptor; + @Nullable + ThingHandlerCallback tc; + @Nullable + VehicleHandler cch; + @Nullable + List allChannels; + @Nullable + List allStates; + String driveTrain = Constants.EMPTY; + boolean imperial; + + /** + * Prepare environment for Vehicle Status Updates + */ + public void setup(String type, boolean imperial) { + driveTrain = type; + this.imperial = imperial; + Thing thing = mock(Thing.class); + when(thing.getUID()).thenReturn(new ThingUID("testbinding", "test")); + HttpClient hc = mock(HttpClient.class); + cch = new VehicleHandler(thing, hc, type, imperial); + tc = mock(ThingHandlerCallback.class); + cch.setCallback(tc); + channelCaptor = ArgumentCaptor.forClass(ChannelUID.class); + stateCaptor = ArgumentCaptor.forClass(State.class); + } + + private boolean testTrip(String statusContent, int callbacksExpected, Optional> concreteChecks) { + assertNotNull(statusContent); + cch.lastTripCallback.onResponse(Optional.of(statusContent)); + verify(tc, times(callbacksExpected)).stateUpdated(channelCaptor.capture(), stateCaptor.capture()); + allChannels = channelCaptor.getAllValues(); + allStates = stateCaptor.getAllValues(); + + assertNotNull(driveTrain); + TripWrapper checker = new TripWrapper(driveTrain, imperial, statusContent); + trace(); + if (concreteChecks.isPresent()) { + return checker.append(concreteChecks.get()).checkResults(allChannels, allStates); + } else { + return checker.checkResults(allChannels, allStates); + } + } + + private void trace() { + for (int i = 0; i < allChannels.size(); i++) { + logger.info("Channel {} {}", allChannels.get(i), allStates.get(i)); + } + } + + @Test + public void testi3Rex() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(VehicleType.ELECTRIC_REX.toString(), false); + String content = FileReader.readFileInString("src/test/resources/responses/I01_REX/last-trip.json"); + assertTrue(testTrip(content, HYBRID_CALL_TIMES, Optional.empty())); + } + + @Test + public void test530E() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(VehicleType.PLUGIN_HYBRID.toString(), false); + String content = FileReader.readFileInString("src/test/resources/responses/530E/last-trip.json"); + assertTrue(testTrip(content, HYBRID_CALL_TIMES, Optional.empty())); + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java index 968e6f43e97e8..65546180a3f4f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java @@ -49,9 +49,9 @@ public class VehicleTests { private final Logger logger = LoggerFactory.getLogger(VehicleHandler.class); - private static final int HYBRID_CALL_TIMES = 21; - private static final int CONV_CALL_TIMES = 15; - private static final int EV_CALL_TIMES = 16; + private static final int HYBRID_CALL_TIMES = 32; + private static final int CONV_CALL_TIMES = 26; + private static final int EV_CALL_TIMES = 27; @Nullable ArgumentCaptor channelCaptor; @@ -131,10 +131,11 @@ private void trace() { */ @Test public void testMyi3Rex() { + int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC_REX.toString(), false); String content = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, HYBRID_CALL_TIMES + numServices, Optional.empty())); } /** @@ -159,10 +160,11 @@ public void testMyi3Rex() { */ @Test public void testMyi3RexMiles() { + int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC_REX.toString(), true); String content = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, HYBRID_CALL_TIMES + numServices, Optional.empty())); } /** @@ -183,6 +185,7 @@ public void testMyi3RexMiles() { */ @Test public void testF15() { + int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F15/status.json"); @@ -192,11 +195,12 @@ public void testF15() { // Check for cbsType which is "Oil" instead // m.put(ConnectedDriveConstants.SERVICE_DATE, DateTimeType.valueOf("2018-06-01T14:00:00.000+0200")); m.put(ConnectedDriveConstants.SERVICE_NAME, StringType.valueOf("Oil")); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.of(m))); + assertTrue(testVehicle(content, CONV_CALL_TIMES + numServices, Optional.of(m))); } @Test public void testF15Miles() { + int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F15/status.json"); @@ -206,7 +210,7 @@ public void testF15Miles() { // Check for cbsType which is "Oil" instead // m.put(ConnectedDriveConstants.SERVICE_DATE, DateTimeType.valueOf("2018-06-01T14:00:00.000+0200")); m.put(ConnectedDriveConstants.SERVICE_NAME, StringType.valueOf("Oil")); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.of(m))); + assertTrue(testVehicle(content, CONV_CALL_TIMES + numServices, Optional.of(m))); } /** @@ -230,7 +234,7 @@ public void testF31() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F31/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, CONV_CALL_TIMES - 1, Optional.empty())); } @Test @@ -238,7 +242,7 @@ public void testF31Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F31/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, CONV_CALL_TIMES - 1, Optional.empty())); } @Test @@ -246,7 +250,7 @@ public void testF35() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F35/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, CONV_CALL_TIMES - 1, Optional.empty())); } @Test @@ -254,7 +258,7 @@ public void testF35Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F35/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, CONV_CALL_TIMES - 1, Optional.empty())); } @Test @@ -262,7 +266,7 @@ public void testF45() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F45/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, CONV_CALL_TIMES - 1, Optional.empty())); } @Test @@ -270,83 +274,92 @@ public void testF45Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F45/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, CONV_CALL_TIMES - 1, Optional.empty())); } @Test public void testF48() { + int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F48/status.json"); // Check earliest Service by hard Map m = new HashMap(); m.put(ConnectedDriveConstants.CHECK_CONTROL, StringType.valueOf("Tyre Pressure Notification")); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.of(m))); + assertTrue(testVehicle(content, CONV_CALL_TIMES + numServices, Optional.of(m))); } @Test public void testF48Miles() { + int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F48/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, CONV_CALL_TIMES + numServices, Optional.empty())); } @Test public void testG31NBTEvo() { + int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/G31_NBTevo/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, CONV_CALL_TIMES + numServices, Optional.empty())); } @Test public void testG31NBTEvoMiles() { + int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/G31_NBTevo/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, CONV_CALL_TIMES + numServices, Optional.empty())); } @Test public void testI01NoRex() { + int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/I01_NOREX/status.json"); - assertTrue(testVehicle(content, EV_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, EV_CALL_TIMES + numServices, Optional.empty())); } @Test public void testI01NoRexMiles() { + int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/I01_NOREX/status.json"); - assertTrue(testVehicle(content, EV_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, EV_CALL_TIMES + numServices, Optional.empty())); } @Test public void testI01Rex() { + int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC_REX.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/I01_REX/status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, HYBRID_CALL_TIMES + numServices, Optional.empty())); } @Test public void testI01RexMiles() { + int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC_REX.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/I01_REX/status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, HYBRID_CALL_TIMES + numServices, Optional.empty())); } @Test public void test318iF31() { + int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F31/status-318i.json"); Map m = new HashMap(); - m.put(ConnectedDriveConstants.WINDOWS, StringType.valueOf("Driverfront Intermediate")); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.of(m))); + m.put(ConnectedDriveConstants.WINDOWS, StringType.valueOf(Constants.INTERMEDIATE)); + assertTrue(testVehicle(content, CONV_CALL_TIMES + numServices, Optional.of(m))); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/all-trips.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/all-trips.json new file mode 100644 index 0000000000000..64976197c9972 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/all-trips.json @@ -0,0 +1,40 @@ +{ + "allTrips": { + "avgElectricConsumption": { + "communityLow": -4.74, + "communityAverage": 5.8, + "communityHigh": 21.04, + "userAverage": 6.73 + }, + "avgRecuperation": { + "communityLow": 1.27, + "communityAverage": 5.29, + "communityHigh": 19.77, + "userAverage": 5.1 + }, + "chargecycleRange": { + "communityAverage": 11.04, + "communityHigh": 169.59, + "userAverage": 23.74, + "userHigh": 3.62, + "userCurrentChargeCycle": 28.06 + }, + "totalElectricDistance": { + "communityLow": 20.33, + "communityAverage": 16575.07, + "communityHigh": 63175.2, + "userTotal": 20102.5 + }, + "avgCombinedConsumption": { + "communityLow": 2.45, + "communityAverage": 6.08, + "communityHigh": 10.86, + "userAverage": 4.93 + }, + "savedCO2": 557.382, + "savedCO2greenEnergy": 3278.717, + "totalSavedFuel": 1156.8, + "resetDate": "2020-09-19T12:54:20+0000", + "batterySizeMax": 9140 + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/charge-profile.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/charge-profile.json new file mode 100644 index 0000000000000..22f4fb1a24684 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/charge-profile.json @@ -0,0 +1,42 @@ +{ + "weeklyPlanner": { + "climatizationEnabled": true, + "chargingMode": "IMMEDIATE_CHARGING", + "chargingPreferences": "CHARGING_WINDOW", + "timer1": { + "departureTime": "07:10", + "timerEnabled": true, + "weekdays": [ + "MONDAY", + "TUESDAY", + "WEDNESDAY", + "THURSDAY", + "FRIDAY" + ] + }, + "timer2": { + "departureTime": "09:00", + "timerEnabled": true, + "weekdays": [ + "SATURDAY", + "SUNDAY" + ] + }, + "timer3": { + "departureTime": "00:00", + "timerEnabled": false, + "weekdays": [] + }, + "overrideTimer": { + "departureTime": "09:00", + "timerEnabled": false, + "weekdays": [ + "SUNDAY" + ] + }, + "preferredChargingWindow": { + "startTime": "00:00", + "endTime": "00:00" + } + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/discovery.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/discovery.json new file mode 100644 index 0000000000000..10289f07a944f --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/discovery.json @@ -0,0 +1,46 @@ +{ + "vehicles": [ + { + "vin": "ANONYMOUS", + "model": "530e iPerformance", + "driveTrain": "PHEV", + "brand": "BMW", + "yearOfConstruction": 2018, + "bodytype": "G30", + "color": "SCHWARZ II", + "statisticsCommunityEnabled": false, + "statisticsAvailable": true, + "hasAlarmSystem": true, + "dealer": { + "name": "ANONYMOUS", + "street": "ANONYMOUS", + "postalCode": "ANONYMOUS", + "city": "ANONYMOUS", + "country": "ANONYMOUS", + "phone": "ANONYMOUS" + }, + "breakdownNumber": "ANONYMOUS", + "supportedChargingModes": [ + "AC_LOW" + ], + "chargingControl": "WEEKLY_PLANNER", + "vehicleFinder": "ACTIVATED", + "hornBlow": "ACTIVATED", + "lightFlash": "ACTIVATED", + "doorLock": "ACTIVATED", + "doorUnlock": "ACTIVATED", + "climateNow": "ACTIVATED", + "sendPoi": "ACTIVATED", + "remote360": "NOT_SUPPORTED", + "climateControl": "NOT_SUPPORTED", + "chargeNow": "NOT_SUPPORTED", + "lastDestinations": "NOT_SUPPORTED", + "carCloud": "ACTIVATED", + "remoteSoftwareUpgrade": "NOT_SUPPORTED", + "climateNowRES": "NOT_SUPPORTED", + "climateControlRES": "NOT_SUPPORTED", + "smartSolution": "NOT_SUPPORTED", + "ipa": "NOT_SUPPORTED" + } + ] +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/last-trip.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/last-trip.json new file mode 100644 index 0000000000000..aa592b8503c45 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/last-trip.json @@ -0,0 +1,18 @@ +{ + "lastTrip": { + "efficiencyValue": 1, + "totalDistance": 2, + "electricDistance": 2, + "avgElectricConsumption": 9, + "avgRecuperation": 9, + "drivingModeValue": 0.5, + "totalConsumptionValue": 1.25, + "avgCombinedConsumption": 0, + "electricDistanceRatio": 100, + "savedFuel": 1.53, + "date": "2020-09-19T16:03:00+0000", + "duration": 3, + "chargingBehaviorValue": 1.25, + "electricDistanceShareValue": 1.25 + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/status.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/status.json new file mode 100644 index 0000000000000..2abfe731976b1 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/530E/status.json @@ -0,0 +1,72 @@ +{ + "vehicleStatus": { + "mileage": 47035, + "remainingFuel": 18.0, + "remainingRangeElectric": 3.0, + "remainingRangeElectricMls": 1.0, + "remainingRangeFuel": 249.0, + "remainingRangeFuelMls": 154.0, + "maxRangeElectric": 32.0, + "maxRangeElectricMls": 19.0, + "maxFuel": 0.0, + "chargingLevelHv": 17.0, + "vin": "ANONYMOUS", + "updateReason": "VEHICLE_SHUTDOWN_SECURED", + "updateTime": "2020-09-19T14:04:25+0000", + "doorDriverFront": "CLOSED", + "doorDriverRear": "CLOSED", + "doorPassengerFront": "CLOSED", + "doorPassengerRear": "CLOSED", + "windowDriverFront": "CLOSED", + "windowDriverRear": "CLOSED", + "windowPassengerFront": "CLOSED", + "windowPassengerRear": "CLOSED", + "trunk": "CLOSED", + "rearWindow": "INVALID", + "hood": "CLOSED", + "doorLockState": "SECURED", + "parkingLight": "OFF", + "positionLight": "OFF", + "connectionStatus": "DISCONNECTED", + "chargingStatus": "INVALID", + "lastChargingEndReason": "CHARGING_GOAL_REACHED", + "lastChargingEndResult": "SUCCESS", + "position": { + "lat": -1.0, + "lon": -1.0, + "heading": -1, + "status": "OK" + }, + "internalDataTimeUTC": "2020-09-19T14:04:25", + "singleImmediateCharging": false, + "chargingConnectionType": "CONDUCTIVE", + "chargingInductivePositioning": "NOT_POSITIONED", + "vehicleCountry": "SE", + "DCS_CCH_Activation": "NA", + "DCS_CCH_Ongoing": false, + "checkControlMessages": [], + "cbsData": [ + { + "cbsType": "OIL", + "cbsState": "OK", + "cbsDueDate": "2022-01", + "cbsDescription": "Next service due when the stated distance has been covered or by the specified date.", + "cbsRemainingMileage": 19000 + }, + { + "cbsType": "VEHICLE_CHECK", + "cbsState": "OK", + "cbsDueDate": "2022-01", + "cbsDescription": "Next visual inspection due when the stated distance has been covered or by the stated date.", + "cbsRemainingMileage": 19000 + }, + { + "cbsType": "BRAKE_FLUID", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next change due at the latest by the stated date.", + "cbsRemainingMileage": 0 + } + ] + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F31/status-318i.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F31/status-318i.json index f20475a95ee7b..e3dcaf7beb5c8 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F31/status-318i.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F31/status-318i.json @@ -53,13 +53,6 @@ "cbsDueDate": "2022-07", "cbsDescription": "Next visual inspection due when the stated distance has been covered or by the stated date.", "cbsRemainingMileage": 29000 - }, - { - "cbsType": "BRAKE_FLUID", - "cbsState": "OK", - "cbsDueDate": "2022-01", - "cbsDescription": "Next change due at the latest by the stated date.", - "cbsRemainingMileage": 0 } ] } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/all-trips.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/all-trips.json new file mode 100644 index 0000000000000..3fe434ee6c21a --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/all-trips.json @@ -0,0 +1,40 @@ +{ + "allTrips": { + "avgElectricConsumption": { + "communityLow": 11.05, + "communityAverage": 16.28, + "communityHigh": 21.99, + "userAverage": 16.46 + }, + "avgRecuperation": { + "communityLow": 0.47, + "communityAverage": 3.37, + "communityHigh": 11.51, + "userAverage": 4.53 + }, + "chargecycleRange": { + "communityAverage": 194.21, + "communityHigh": 270, + "userAverage": 57.3, + "userHigh": 185.48, + "userCurrentChargeCycle": 68 + }, + "totalElectricDistance": { + "communityLow": 19, + "communityAverage": 40850.56, + "communityHigh": 193006, + "userTotal": 16629.4 + }, + "avgCombinedConsumption": { + "communityLow": 0, + "communityAverage": 0.92, + "communityHigh": 4.44, + "userAverage": 0.64 + }, + "savedCO2": 461.083, + "savedCO2greenEnergy": 2712.255, + "totalSavedFuel": 0, + "resetDate": "2020-08-24T14:40:40+0000", + "batterySizeMax": 33200 + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/charge-profile.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/charge-profile.json new file mode 100644 index 0000000000000..840559b6cf134 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/charge-profile.json @@ -0,0 +1,41 @@ +{ + "weeklyPlanner": { + "climatizationEnabled": true, + "chargingMode": "IMMEDIATE_CHARGING", + "chargingPreferences": "CHARGING_WINDOW", + "timer1": { + "departureTime": "05:00", + "timerEnabled": false, + "weekdays": [ + "MONDAY", + "TUESDAY", + "WEDNESDAY", + "THURSDAY", + "FRIDAY" + ] + }, + "timer2": { + "departureTime": "12:00", + "timerEnabled": true, + "weekdays": [ + "SATURDAY" + ] + }, + "timer3": { + "departureTime": "00:00", + "timerEnabled": false, + "weekdays": [] + }, + "overrideTimer": { + "departureTime": "12:00", + "timerEnabled": false, + "weekdays": [ + "SATURDAY" + ] + }, + "preferredChargingWindow": { + "startTime": "11:00", + "endTime": "17:00" + } + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/discovery.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/discovery.json new file mode 100644 index 0000000000000..73b594678ba3b --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/discovery.json @@ -0,0 +1,63 @@ +{ + "vehicles": [ + { + "vin": "MY_REAL_VIN", + "model": "i3 94 (+ REX)", + "bodytype": "I01", + "driveTrain": "BEV_REX", + "color": "CAPPARISWEISS MIT AKZENT BMW I BLAU", + "colorCode": "B85", + "brand": "BMW_I", + "yearOfConstruction": 2017, + "statisticsCommunityEnabled": false, + "statisticsAvailable": true, + "hub": "HUB_ECE", + "hasAlarmSystem": true, + "dealer": { + "name": "My Real Dealer Name", + "street": "My Real Dealer Address", + "postalCode": "4711", + "city": "My Real Dealer City", + "country": "DE", + "phone": "My Real Dealer Phone" + }, + "breakdownNumber": "Real Phone Number", + "countryCode": "V6", + "egoVehiclePath": "", + "chargingUpdateMode": "NORMAL_PROGNOSE_BASED", + "steering": "LH", + "vehicleFinderRestriction": "NONE", + "hmiVersion": "ID4", + "a4a": "USB_ONLY", + "vehicleFinder": "ACTIVATED", + "remote360": "NOT_SUPPORTED", + "hornBlow": "ACTIVATED", + "lightFlash": "ACTIVATED", + "doorLock": "ACTIVATED", + "doorUnlock": "ACTIVATED", + "climateControl": "NOT_SUPPORTED", + "climateNow": "ACTIVATED", + "climateNowRES": "NOT_SUPPORTED", + "climateControlRES": "NOT_SUPPORTED", + "chargingControl": "WEEKLY_PLANNER", + "chargeNow": "NOT_SUPPORTED", + "sendPoi": "ACTIVATED", + "rangeMap": "RANGE_CIRCLE", + "lastDestinations": "SUPPORTED", + "intermodalRouting": "NOT_AVAILABLE", + "climateFunction": "AIRCONDITIONING", + "onlineSearchMode": "MAP", + "onlineSearchProvider": "GOOGLE", + "smartSolution": "NOT_SUPPORTED", + "carCloud": "NOT_SUPPORTED", + "supportedChargingModes": [ + "AC_LOW", + "DC" + ], + "lscType": "I_LSC_IMM", + "ipa": "NOT_SUPPORTED", + "puStep": "1119", + "remoteSoftwareUpgrade": "NOT_SUPPORTED" + } + ] +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/last-trip.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/last-trip.json new file mode 100644 index 0000000000000..c129bf37ce6c4 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/I01_REX/last-trip.json @@ -0,0 +1,19 @@ +{ + "lastTrip": { + "efficiencyValue": 0.98, + "totalDistance": 2, + "electricDistance": 2, + "avgElectricConsumption": 7, + "avgRecuperation": 6, + "drivingModeValue": 0.87, + "totalConsumptionValue": 1.25, + "avgCombinedConsumption": 0, + "electricDistanceRatio": 100, + "savedFuel": 0, + "date": "2020-08-24T17:55:00+0000", + "duration": 5, + "auxiliaryConsumptionValue": 0.78, + "anticipationValue": 0.99, + "accelerationValue": 0.99 + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/last-trip.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/last-trip.json index d5ddc98512762..c129bf37ce6c4 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/last-trip.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/last-trip.json @@ -6,14 +6,14 @@ "avgElectricConsumption": 7, "avgRecuperation": 6, "drivingModeValue": 0.87, - "accelerationValue": 0.99, - "anticipationValue": 0.99, "totalConsumptionValue": 1.25, - "auxiliaryConsumptionValue": 0.78, "avgCombinedConsumption": 0, "electricDistanceRatio": 100, "savedFuel": 0, "date": "2020-08-24T17:55:00+0000", - "duration": 5 + "duration": 5, + "auxiliaryConsumptionValue": 0.78, + "anticipationValue": 0.99, + "accelerationValue": 0.99 } } \ No newline at end of file From 6afcc53d4e10d31d01a69002823fa032ce353763 Mon Sep 17 00:00:00 2001 From: Bernd Date: Mon, 21 Sep 2020 18:58:57 +0200 Subject: [PATCH 043/176] final service data list interface adaptions Signed-off-by: Bernd (cherry picked from commit caffeb9539ebdb588555a165f21d2b7193ec3e70) Signed-off-by: Bernd --- .../doc/bmw-connected-old.png | Bin 0 -> 75918 bytes .../doc/bmw-connected.png | Bin 75918 -> 7392 bytes .../internal/ConnectedDriveConstants.java | 2 +- .../internal/dto/status/CBSMessage.java | 2 +- .../handler/RemoteServiceHandler.java | 3 +- .../internal/handler/VehicleHandler.java | 31 ++++++++++-------- .../internal/dto/StatusWrapper.java | 2 +- .../internal/dto/VehicleStatusTest.java | 17 +++++++++- .../test/resources/webapi/vehicle-status.json | 3 +- 9 files changed, 41 insertions(+), 19 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/doc/bmw-connected-old.png diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/doc/bmw-connected-old.png b/bundles/org.openhab.binding.bmwconnecteddrive/doc/bmw-connected-old.png new file mode 100644 index 0000000000000000000000000000000000000000..b5e399db7200a5d7bc97e981b53db09a74cdf258 GIT binary patch literal 75918 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�R#W%}g7G!^h^a^8icy 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%0ATi4cjQ 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 Eg4OzIQ~&?~ literal 0 HcmV?d00001 diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/doc/bmw-connected.png b/bundles/org.openhab.binding.bmwconnecteddrive/doc/bmw-connected.png index b5e399db7200a5d7bc97e981b53db09a74cdf258..579be907833faa43b7d7b3595a139c48cdf5a572 100644 GIT binary patch literal 7392 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 NCWhw>Uh9#f{tun#4Z#2a literal 75918 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�R#W%}g7G!^h^a^8icy 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%0ATi4cjQ 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 Eg4OzIQ~&?~ diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 964b24079cd1e..a473458e038ca 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -141,7 +141,7 @@ public String toString() { // Services public static final String SERVICE_NAME = "service-name"; - public static final String SERVICE_TOTAL_COUNT = "service-total-count"; + public static final String SERVICE_TOTAL_COUNT = "service-count"; public static final String SERVICE_INDEX = "service-index"; public static final String SERVICE_NEXT = "service-next"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java index bef526188a2cb..e8797b5ec6bfe 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java @@ -24,7 +24,7 @@ public class CBSMessage { public String cbsState;// ": "OK", public String cbsDueDate;// ": "2021-11", public String cbsDescription;// ": "Next change due at the latest by the stated date." - public int cbsRemainingMileage; // 46000 + public int cbsRemainingMileage = -1; // 46000 public String getDueDate() { if (cbsDueDate == null) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java index 21459fa91b9cd..d6d0bf2ac8dc9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -22,6 +22,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.remote.ExecutionStatusContainer; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; +import org.openhab.binding.bmwconnecteddrive.internal.utils.HTTPConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,7 +40,7 @@ public class RemoteServiceHandler implements StringResponseCallback { // after 60 retries the state update will give up private static final String SERVICE_TYPE = "serviceType"; private static final int GIVEUP_COUNTER = 6; - private static final int STATE_UPDATE_SEC = 10; + private static final int STATE_UPDATE_SEC = HTTPConstants.HTTP_TIMEOUT_SEC + 1; // regular timeout + 1sec private int counter = 0; public enum ExecutionState { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index aa27488ac3bfc..04a3d0c8bdf6b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -651,7 +651,10 @@ public void next() { updateService(); } - private void updateService() { + /** + * needs to be synchronized with onResponse update + */ + private synchronized void updateService() { if (services != null) { updateState(serviceCount, new DecimalType(services.size())); if (services.size() > 0) { @@ -660,7 +663,6 @@ private void updateService() { serviceIndexSelected = 0; } CBSMessage entry = services.get(serviceIndexSelected); - updateState(serviceIndex, new DecimalType(serviceIndexSelected)); updateState(serviceDate, DateTimeType.valueOf(Converter.getLocalDateTime(entry.getDueDate()))); if (imperial) { updateState(serviceMileage, @@ -669,7 +671,9 @@ private void updateService() { updateState(serviceMileage, QuantityType.valueOf(Converter.round(entry.cbsRemainingMileage), MetricPrefix.KILO(SIUnits.METRE))); } - updateState(serviceName, StringType.valueOf(entry.getType())); + updateState(serviceName, StringType.valueOf(Converter.toTitleCase(entry.getType()))); + // last update index - this is a sync point and you're sure that all data is valid noew + updateState(serviceIndex, new DecimalType(serviceIndexSelected)); } } } @@ -715,18 +719,19 @@ public void onResponse(Optional content) { updateState(serviceNextDate, DateTimeType.valueOf(Converter.getLocalDateTime(nextServiceDate))); } double nextServiceMileage = vStatus.getNextServiceMileage(); - if (nextServiceMileage != Double.NaN) { - if (imperial) { - updateState(serviceNextMileage, - QuantityType.valueOf(Converter.round(nextServiceMileage), ImperialUnits.MILE)); - } else { - updateState(serviceNextMileage, QuantityType.valueOf(Converter.round(nextServiceMileage), - MetricPrefix.KILO(SIUnits.METRE))); - } + if (imperial) { + updateState(serviceNextMileage, + QuantityType.valueOf(Converter.round(nextServiceMileage), ImperialUnits.MILE)); + } else { + updateState(serviceNextMileage, QuantityType.valueOf(Converter.round(nextServiceMileage), + MetricPrefix.KILO(SIUnits.METRE))); } - services = vStatus.cbsData; - updateService(); + // synchronize with commands + synchronized (this) { + services = vStatus.cbsData; + updateService(); + } // Range values // based on unit of length decide if range shall be reported in km or miles diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index da9acba569156..7339eda005f08 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -409,7 +409,7 @@ private void checkResult(ChannelUID channelUID, State state) { case SERVICE_NAME: assertTrue(state instanceof StringType); st = (StringType) state; - wanted = StringType.valueOf(vStatus.cbsData.get(0).getType()); + wanted = StringType.valueOf(Converter.toTitleCase(vStatus.cbsData.get(0).getType())); assertEquals("Window", wanted.toString(), st.toString()); break; default: diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleStatusTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleStatusTest.java index 1923dac4f56b2..b8afa8063a5a6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleStatusTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleStatusTest.java @@ -14,8 +14,11 @@ import static org.junit.Assert.assertEquals; +import java.util.List; + import org.eclipse.jdt.annotation.NonNullByDefault; import org.junit.Test; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.CBSMessage; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Position; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; @@ -33,7 +36,7 @@ public class VehicleStatusTest { private static final Gson GSON = new Gson(); @Test - public void testtestBevRexValues() { + public void testBevRexValues() { String resource1 = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); VehicleStatusContainer status = GSON.fromJson(resource1, VehicleStatusContainer.class); VehicleStatus vStatus = status.vehicleStatus; @@ -44,4 +47,16 @@ public void testtestBevRexValues() { assertEquals("DCS Activation", "NA", vStatus.dcsCchActivation); assertEquals("DCS Ongoing", false, vStatus.dcsCchOngoing); } + + @Test + public void testServices() { + String resource1 = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); + VehicleStatusContainer status = GSON.fromJson(resource1, VehicleStatusContainer.class); + VehicleStatus vStatus = status.vehicleStatus; + List services = vStatus.cbsData; + CBSMessage message = services.get(0); + assertEquals("Service Mileage ", 15345, message.cbsRemainingMileage); + message = services.get(1); + assertEquals("Service Mileage ", -1, message.cbsRemainingMileage); + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status.json index 2bad0ef617243..f3dac76ea5b21 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status.json @@ -49,7 +49,8 @@ "cbsType": "BRAKE_FLUID", "cbsState": "OK", "cbsDueDate": "2021-11", - "cbsDescription": "Next change due at the latest by the stated date." + "cbsDescription": "Next change due at the latest by the stated date.", + "cbsRemainingMileage": 15345 }, { "cbsType": "VEHICLE_CHECK", From 1282f077b77a46c20568cc6797b498fb3d1ffca2 Mon Sep 17 00:00:00 2001 From: Bernd Date: Mon, 21 Sep 2020 20:49:55 +0200 Subject: [PATCH 044/176] destinations list interface Signed-off-by: Bernd (cherry picked from commit ddf493c16c147b70f26f83879b436872ba5ce56b) Signed-off-by: Bernd --- .../internal/ConnectedDriveConstants.java | 36 ++++---- .../handler/VehicleChannelHandler.java | 42 ++++------ .../internal/handler/VehicleHandler.java | 84 ++++++++++++++----- .../thing/destination-channel-types.xml | 38 +++------ .../ESH-INF/thing/destination-group.xml | 15 ++-- .../resources/ESH-INF/thing/service-group.xml | 12 +-- .../internal/dto/StatusWrapper.java | 43 ++++++++-- .../internal/handler/VehicleTests.java | 4 +- 8 files changed, 156 insertions(+), 118 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index a473458e038ca..9de74cef5af8b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -104,6 +104,7 @@ public String toString() { // Thing Group definitions public static final String CHANNEL_GROUP_STATUS = "status"; public static final String CHANNEL_GROUP_SERVICE = "service"; + public static final String CHANNEL_GROUP_CHECK_CONTROL = "check"; public static final String CHANNEL_GROUP_DOORS = "doors"; public static final String CHANNEL_GROUP_RANGE = "range"; public static final String CHANNEL_GROUP_LOCATION = "location"; @@ -115,6 +116,19 @@ public String toString() { public static final String CHANNEL_GROUP_DESTINATION = "destination"; public static final String CHANNEL_GROUP_TROUBLESHOOT = "troubleshoot"; + // List Interface Constants + public static final String COUNT = "count"; + public static final String INDEX = "index"; + public static final String NEXT = "next"; + + // Generic Constants for several groups + public static final String NAME = "name"; + public static final String DATE = "date"; + public static final String MILEAGE = "mileage"; + public static final String LONGITUDE = "longitude"; + public static final String LATITUDE = "latitude"; + public static final String HEADING = "heading"; + // Status public static final String DOORS = "doors"; public static final String WINDOWS = "windows"; @@ -139,12 +153,6 @@ public String toString() { public static final String WINDOW_REAR = "window-rear"; public static final String SUNROOF = "sunroof"; - // Services - public static final String SERVICE_NAME = "service-name"; - public static final String SERVICE_TOTAL_COUNT = "service-count"; - public static final String SERVICE_INDEX = "service-index"; - public static final String SERVICE_NEXT = "service-next"; - // Charge Profile public static final String CHARGE_PROFILE_CLIMATE = "profile-climate"; public static final String CHARGE_PROFILE_MODE = "profile-mode"; @@ -161,7 +169,6 @@ public String toString() { public static final String CHARGE_TIMER3_DAYS = "timer3-enabled"; // Range - public static final String MILEAGE = "mileage"; public static final String RANGE_HYBRID = "hybrid"; public static final String RANGE_ELECTRIC = "electric"; public static final String SOC = "soc"; @@ -184,11 +191,6 @@ public String toString() { public static final String CUMULATED_DRIVEN_DISTANCE = "cumulated-driven-distance"; public static final String SINGLE_LONGEST_DISTANCE = "single-longest-distance"; - // Lifetime - public static final String LONGITUDE = "longitude"; - public static final String LATITUDE = "latitude"; - public static final String HEADING = "heading"; - // Image public static final String IMAGE_FORMAT = "png"; public static final String IMAGE_VIEWPORT = "view"; @@ -203,16 +205,6 @@ public String toString() { public static final String REMOTE_SERVICE_AIR_CONDITIONING = "climate"; public static final String REMOTE_STATE = "state"; - public static final String DESTINATION_NAME_1 = "name-1"; - public static final String DESTINATION_LAT_1 = "lat-1"; - public static final String DESTINATION_LON_1 = "lon-1"; - public static final String DESTINATION_NAME_2 = "name-2"; - public static final String DESTINATION_LAT_2 = "lat-2"; - public static final String DESTINATION_LON_2 = "lon-2"; - public static final String DESTINATION_NAME_3 = "name-3"; - public static final String DESTINATION_LAT_3 = "lat-3"; - public static final String DESTINATION_LON_3 = "lon-3"; - // Troubleshoot public static final String DISCOVERY_FINGERPRINT = "discovery-fingerprint"; public static final String VEHICLE_FINGERPRINT = "vehicle-fingerprint"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 6112666312638..e56e9cd4bcd1a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -103,15 +103,12 @@ public class VehicleChannelHandler extends BaseThingHandler { protected ChannelUID remoteStateChannel; // Remote Services - protected ChannelUID destinationName1; - protected ChannelUID destinationLat1; - protected ChannelUID destinationLon1; - protected ChannelUID destinationName2; - protected ChannelUID destinationLat2; - protected ChannelUID destinationLon2; - protected ChannelUID destinationName3; - protected ChannelUID destinationLat3; - protected ChannelUID destinationLon3; + protected ChannelUID destinationName; + protected ChannelUID destinationLat; + protected ChannelUID destinationLon; + protected ChannelUID destinationCount; + protected ChannelUID destinationIndex; + protected ChannelUID destinationNext; // Charging protected ChannelUID chargingStatus; @@ -159,12 +156,12 @@ public VehicleChannelHandler(Thing thing) { chargingStatus = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, CHARGE_STATUS); lastUpdate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, LAST_UPDATE); - serviceDate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, SERVICE_DATE); - serviceMileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, SERVICE_MILEAGE); - serviceName = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, SERVICE_NAME); - serviceCount = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, SERVICE_TOTAL_COUNT); - serviceIndex = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, SERVICE_INDEX); - serviceNext = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, SERVICE_NEXT); + serviceDate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, DATE); + serviceMileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, MILEAGE); + serviceName = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, NAME); + serviceCount = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, COUNT); + serviceIndex = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, INDEX); + serviceNext = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, COUNT); doorDriverFront = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, DOOR_DRIVER_FRONT); doorDriverRear = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, DOOR_DRIVER_REAR); @@ -237,15 +234,12 @@ public VehicleChannelHandler(Thing thing) { remoteClimateChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_AIR_CONDITIONING); remoteStateChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_STATE); - destinationName1 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_NAME_1); - destinationLat1 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_LAT_1); - destinationLon1 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_LON_1); - destinationName2 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_NAME_2); - destinationLat2 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_LAT_2); - destinationLon2 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_LON_2); - destinationName3 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_NAME_3); - destinationLat3 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_LAT_3); - destinationLon3 = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, DESTINATION_LON_3); + destinationName = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, NAME); + destinationLat = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, LATITUDE); + destinationLon = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, LONGITUDE); + destinationCount = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, COUNT); + destinationIndex = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, INDEX); + destinationNext = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, NEXT); imageChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_FORMAT); imageViewportChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_VIEWPORT); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 04a3d0c8bdf6b..f96bbeb32571a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -44,6 +44,7 @@ import org.eclipse.smarthome.io.net.http.HttpUtil; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; import org.openhab.binding.bmwconnecteddrive.internal.VehicleConfiguration; +import org.openhab.binding.bmwconnecteddrive.internal.dto.Destination; import org.openhab.binding.bmwconnecteddrive.internal.dto.DestinationContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.ChargeProfile; @@ -96,7 +97,7 @@ public class VehicleHandler extends VehicleChannelHandler { StringResponseCallback allTripsCallback = new AllTripsCallback(); StringResponseCallback chargeProfileCallback = new ChargeProfilesCallback(); StringResponseCallback rangeMapCallback = new RangeMapCallback(); - StringResponseCallback destinationCallback = new DestinationsCallback(); + DestinationsCallback destinationCallback = new DestinationsCallback(); ByteResponseCallback imageCallback = new ImageCallback(); public VehicleHandler(Thing thing, HttpClient hc, String type, boolean imperial) { @@ -201,12 +202,33 @@ public void handleCommand(ChannelUID channelUID, Command command) { } } } - if (channelUID.getIdWithoutGroup().equals(SERVICE_NEXT)) { - if (command instanceof OnOffType) { - if (command.equals(OnOffType.ON)) { - vehicleStatusCallback.next(); - updateState(channelUID, OnOffType.OFF); - } + if (channelUID.getIdWithoutGroup().equals(NEXT)) { + String gUid = channelUID.getGroupId(); + switch (gUid) { + case CHANNEL_GROUP_SERVICE: + if (command instanceof OnOffType) { + if (command.equals(OnOffType.ON)) { + vehicleStatusCallback.next(); + updateState(channelUID, OnOffType.OFF); + } + } + break; + case CHANNEL_GROUP_DESTINATION: + if (command instanceof OnOffType) { + if (command.equals(OnOffType.ON)) { + destinationCallback.next(); + updateState(channelUID, OnOffType.OFF); + } + } + break; + case CHANNEL_GROUP_CHECK_CONTROL: + if (command instanceof OnOffType) { + if (command.equals(OnOffType.ON)) { + vehicleStatusCallback.next(); + updateState(channelUID, OnOffType.OFF); + } + } + break; } } if (channelUID.getIdWithoutGroup().equals(VEHICLE_FINGERPRINT)) { @@ -490,6 +512,35 @@ public void onError(NetworkError error) { @NonNullByDefault({}) public class DestinationsCallback implements StringResponseCallback { + private List destinations = new ArrayList(); + private int destinationIndexSelected = -1; + + public void next() { + destinationIndexSelected++; + updateDestination(); + } + + /** + * needs to be synchronized with onResponse update + */ + private synchronized void updateDestination() { + if (destinations != null) { + updateState(destinationCount, new DecimalType(destinations.size())); + if (!destinations.isEmpty()) { + if (destinationIndexSelected < 0 || destinationIndexSelected >= destinations.size()) { + // select first item + destinationIndexSelected = 0; + } + Destination entry = destinations.get(destinationIndexSelected); + updateState(destinationName, StringType.valueOf(entry.getAddress())); + updateState(destinationLat, new DecimalType(entry.lat)); + updateState(destinationLon, new DecimalType(entry.lon)); + // last update index - this is a sync point and you're sure that all data is valid noew + updateState(destinationIndex, new DecimalType(destinationIndexSelected)); + } + } + } + @Override public void onResponse(Optional content) { destinationCache = content; @@ -497,20 +548,9 @@ public void onResponse(Optional content) { DestinationContainer dc = Converter.getGson().fromJson(content.get(), DestinationContainer.class); if (dc.destinations != null) { - if (!dc.destinations.isEmpty()) { - updateState(destinationName1, StringType.valueOf(dc.destinations.get(0).getAddress())); - updateState(destinationLat1, new DecimalType(dc.destinations.get(0).lat)); - updateState(destinationLon1, new DecimalType(dc.destinations.get(0).lon)); - } - if (dc.destinations.size() > 1) { - updateState(destinationName2, StringType.valueOf(dc.destinations.get(1).getAddress())); - updateState(destinationLat2, new DecimalType(dc.destinations.get(1).lat)); - updateState(destinationLon2, new DecimalType(dc.destinations.get(1).lon)); - } - if (dc.destinations.size() > 2) { - updateState(destinationName3, StringType.valueOf(dc.destinations.get(2).getAddress())); - updateState(destinationLat3, new DecimalType(dc.destinations.get(2).lat)); - updateState(destinationLon3, new DecimalType(dc.destinations.get(2).lon)); + synchronized (this) { + destinations = dc.destinations; + updateDestination(); } } } @@ -657,7 +697,7 @@ public void next() { private synchronized void updateService() { if (services != null) { updateState(serviceCount, new DecimalType(services.size())); - if (services.size() > 0) { + if (!services.isEmpty()) { if (serviceIndexSelected < 0 || serviceIndexSelected >= services.size()) { // select first item serviceIndexSelected = 0; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-channel-types.xml index b194fafbb361a..664a8b15358b9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-channel-types.xml @@ -3,40 +3,28 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - + String - + - + Number - + - + Number - + - + String - + - + Number - + - - Number - - - - String - - - - Number - - - - Number - + + Switch + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-group.xml index abd07e7ddff8d..b679bd8fa884f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-group.xml @@ -7,15 +7,12 @@ Show the Last 3 Destinations - - - - - - - - - + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-group.xml index 7c2b1154e52ea..cc85aad8bf55e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-group.xml @@ -7,12 +7,12 @@ All future Service schedules - - - - - - + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index 7339eda005f08..b75832683d4ee 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -115,12 +115,26 @@ private void checkResult(ChannelUID channelUID, State state) { case MILEAGE: assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); - if (imperial) { - assertEquals("Miles", ImperialUnits.MILE, qt.getUnit()); - } else { - assertEquals("KM", KILOMETRE, qt.getUnit()); + switch (gUid) { + case CHANNEL_GROUP_RANGE: + if (imperial) { + assertEquals("Miles", ImperialUnits.MILE, qt.getUnit()); + } else { + assertEquals("KM", KILOMETRE, qt.getUnit()); + } + assertEquals("Mileage", qt.intValue(), vStatus.mileage); + break; + case CHANNEL_GROUP_SERVICE: + if (imperial) { + assertEquals("Miles", ImperialUnits.MILE, qt.getUnit()); + } else { + assertEquals("KM", KILOMETRE, qt.getUnit()); + } + assertEquals("Mileage", qt.intValue(), vStatus.cbsData.get(0).cbsRemainingMileage); + break; + default: + assertFalse("Channel " + channelUID + " " + state + " not found", true); } - assertEquals("Mileage", qt.intValue(), vStatus.mileage); break; case RANGE_ELECTRIC: assertTrue("Is Eelctric", isElectric); @@ -356,12 +370,12 @@ private void checkResult(ChannelUID channelUID, State state) { wanted = StringType.valueOf(vStatus.sunroof); assertEquals("Window", wanted.toString(), st.toString()); break; - case SERVICE_TOTAL_COUNT: + case COUNT: assertTrue(state instanceof DecimalType); dt = (DecimalType) state; assertEquals("Number of Services", vStatus.cbsData.size(), dt.intValue()); break; - case SERVICE_INDEX: + case INDEX: assertTrue(state instanceof DecimalType); dt = (DecimalType) state; assertEquals("Number of Services", 0, dt.intValue()); @@ -406,12 +420,25 @@ private void checkResult(ChannelUID channelUID, State state) { } } break; - case SERVICE_NAME: + case NAME: assertTrue(state instanceof StringType); st = (StringType) state; wanted = StringType.valueOf(Converter.toTitleCase(vStatus.cbsData.get(0).getType())); assertEquals("Window", wanted.toString(), st.toString()); break; + case DATE: + assertTrue(state instanceof DateTimeType); + dtt = (DateTimeType) state; + switch (gUid) { + case CHANNEL_GROUP_SERVICE: + String dueDateString = vStatus.cbsData.get(0).getDueDate(); + DateTimeType expectedDTT = DateTimeType.valueOf(Converter.getLocalDateTime(dueDateString)); + assertEquals("Service", expectedDTT.toString(), dtt.toString()); + break; + default: + assertFalse("Channel " + channelUID + " " + state + " not found", true); + } + break; default: // fail in case of unknown update assertFalse("Channel " + channelUID + " " + state + " not found", true); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java index 65546180a3f4f..106eb6a7f95f2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java @@ -194,7 +194,7 @@ public void testF15() { // Don>'t test on concrete timestamp - it's idfferent on each machine // Check for cbsType which is "Oil" instead // m.put(ConnectedDriveConstants.SERVICE_DATE, DateTimeType.valueOf("2018-06-01T14:00:00.000+0200")); - m.put(ConnectedDriveConstants.SERVICE_NAME, StringType.valueOf("Oil")); + m.put(ConnectedDriveConstants.NAME, StringType.valueOf("Oil")); assertTrue(testVehicle(content, CONV_CALL_TIMES + numServices, Optional.of(m))); } @@ -209,7 +209,7 @@ public void testF15Miles() { // Don>'t test on concrete timestamp - it's idfferent on each machine // Check for cbsType which is "Oil" instead // m.put(ConnectedDriveConstants.SERVICE_DATE, DateTimeType.valueOf("2018-06-01T14:00:00.000+0200")); - m.put(ConnectedDriveConstants.SERVICE_NAME, StringType.valueOf("Oil")); + m.put(ConnectedDriveConstants.NAME, StringType.valueOf("Oil")); assertTrue(testVehicle(content, CONV_CALL_TIMES + numServices, Optional.of(m))); } From a0121891ee5b93da4301161d09f55f5af7ddad62 Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 22 Sep 2020 18:53:19 +0200 Subject: [PATCH 045/176] add check control list Signed-off-by: Bernd (cherry picked from commit 63e262d24e66011964f98315c8c389fe1d331a21) Signed-off-by: Bernd --- .../README.md | 15 +++++ .../internal/ConnectedDriveConstants.java | 2 +- .../handler/VehicleChannelHandler.java | 22 +++++-- .../internal/handler/VehicleHandler.java | 48 ++++++++++++-- .../thing/check-control-channel-types.xml | 22 +++++++ .../ESH-INF/thing/check-control-group.xml | 18 ++++++ .../thing/destination-channel-types.xml | 2 +- .../ESH-INF/thing/destination-group.xml | 6 +- .../ESH-INF/thing/service-channel-types.xml | 2 +- .../resources/ESH-INF/thing/service-group.xml | 2 +- .../resources/ESH-INF/thing/thing-bev.xml | 1 + .../resources/ESH-INF/thing/thing-bev_rex.xml | 1 + .../resources/ESH-INF/thing/thing-conv.xml | 1 + .../resources/ESH-INF/thing/thing-phev.xml | 1 + .../internal/dto/StatusWrapper.java | 62 ++++++++++++++----- .../internal/handler/VehicleTests.java | 62 ++++++++----------- 16 files changed, 198 insertions(+), 69 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/check-control-channel-types.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/check-control-group.xml diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index ba8a598f51cfb..ee482d518a39f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -330,6 +330,21 @@ Please check [TroubleShooting Section](#TroubleShooting) for further advice. ## Further Descriptions +### List Interface + +Currently there are 3 occurrences of dynamic data delivered as Lists + +* Upcoming Services +* Check Control Messages +* Last Destinations + +In order to provide all data the lists are organized the following way based on the Service Group example + +* **size** is the total length of the list. Read-only. +* **index** is the current selected index starting with 0 => list with size 10, valid index is between 0 - 9. If the index is set to _out of bounds_ it's set to first element. Read-write. +* **next** declares a switch for scrolling forward through the list in an endless way. Reaching end of list will start again from 0. Read-write. +* **name**, **mileage** and **date** declares the list item. It will change when setting new index or perform next. Read-only. + ### Range vs Range Radius diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 9de74cef5af8b..a12665aca2e58 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -117,7 +117,7 @@ public String toString() { public static final String CHANNEL_GROUP_TROUBLESHOOT = "troubleshoot"; // List Interface Constants - public static final String COUNT = "count"; + public static final String SIZE = "size"; public static final String INDEX = "index"; public static final String NEXT = "next"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index e56e9cd4bcd1a..7ecad6d1bd7ff 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -43,10 +43,16 @@ public class VehicleChannelHandler extends BaseThingHandler { protected ChannelUID serviceDate; protected ChannelUID serviceMileage; protected ChannelUID serviceName; - protected ChannelUID serviceCount; + protected ChannelUID serviceSize; protected ChannelUID serviceIndex; protected ChannelUID serviceNext; + protected ChannelUID checkControlMileage; + protected ChannelUID checkControlName; + protected ChannelUID checkControlSize; + protected ChannelUID checkControlIndex; + protected ChannelUID checkControlNext; + protected ChannelUID doorDriverFront; protected ChannelUID doorDriverRear; protected ChannelUID doorPassengerFront; @@ -106,7 +112,7 @@ public class VehicleChannelHandler extends BaseThingHandler { protected ChannelUID destinationName; protected ChannelUID destinationLat; protected ChannelUID destinationLon; - protected ChannelUID destinationCount; + protected ChannelUID destinationSize; protected ChannelUID destinationIndex; protected ChannelUID destinationNext; @@ -159,9 +165,15 @@ public VehicleChannelHandler(Thing thing) { serviceDate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, DATE); serviceMileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, MILEAGE); serviceName = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, NAME); - serviceCount = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, COUNT); + serviceSize = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, SIZE); serviceIndex = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, INDEX); - serviceNext = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, COUNT); + serviceNext = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, NEXT); + + checkControlMileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHECK_CONTROL, MILEAGE); + checkControlName = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHECK_CONTROL, NAME); + checkControlSize = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHECK_CONTROL, SIZE); + checkControlIndex = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHECK_CONTROL, INDEX); + checkControlNext = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHECK_CONTROL, NEXT); doorDriverFront = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, DOOR_DRIVER_FRONT); doorDriverRear = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, DOOR_DRIVER_REAR); @@ -237,7 +249,7 @@ public VehicleChannelHandler(Thing thing) { destinationName = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, NAME); destinationLat = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, LATITUDE); destinationLon = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, LONGITUDE); - destinationCount = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, COUNT); + destinationSize = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, SIZE); destinationIndex = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, INDEX); destinationNext = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, NEXT); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index f96bbeb32571a..f91446099ecd8 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -56,6 +56,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTrip; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTripContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.CBSMessage; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.CCMMessage; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Doors; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Position; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; @@ -208,7 +209,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { case CHANNEL_GROUP_SERVICE: if (command instanceof OnOffType) { if (command.equals(OnOffType.ON)) { - vehicleStatusCallback.next(); + vehicleStatusCallback.nextService(); updateState(channelUID, OnOffType.OFF); } } @@ -224,7 +225,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { case CHANNEL_GROUP_CHECK_CONTROL: if (command instanceof OnOffType) { if (command.equals(OnOffType.ON)) { - vehicleStatusCallback.next(); + vehicleStatusCallback.nextCheckControl(); updateState(channelUID, OnOffType.OFF); } } @@ -525,7 +526,7 @@ public void next() { */ private synchronized void updateDestination() { if (destinations != null) { - updateState(destinationCount, new DecimalType(destinations.size())); + updateState(destinationSize, new DecimalType(destinations.size())); if (!destinations.isEmpty()) { if (destinationIndexSelected < 0 || destinationIndexSelected >= destinations.size()) { // select first item @@ -671,6 +672,8 @@ public class VehicleStatusCallback implements StringResponseCallback { private ThingStatus thingStatus = ThingStatus.UNKNOWN; private List services = new ArrayList(); private int serviceIndexSelected = -1; + private List checkControls = new ArrayList(); + private int checkControlIndex = -1; /** * Vehicle Status is supported by all Vehicles so callback result is used to report Thing Status. @@ -686,17 +689,46 @@ private void setThingStatus(ThingStatus status, ThingStatusDetail detail, String } } - public void next() { + public void nextCheckControl() { + checkControlIndex++; + updateService(); + } + + public void nextService() { serviceIndexSelected++; updateService(); } + private synchronized void updateCheckControls() { + if (checkControls != null) { + updateState(checkControlSize, new DecimalType(checkControls.size())); + if (!checkControls.isEmpty()) { + if (checkControlIndex < 0 || checkControlIndex >= checkControls.size()) { + // select first item + checkControlIndex = 0; + } + CCMMessage entry = checkControls.get(checkControlIndex); + updateState(checkControlName, StringType.valueOf(entry.ccmDescriptionShort)); + if (imperial) { + updateState(checkControlMileage, + QuantityType.valueOf(Converter.round(entry.ccmMileage), ImperialUnits.MILE)); + } else { + updateState(checkControlMileage, QuantityType.valueOf(Converter.round(entry.ccmMileage), + MetricPrefix.KILO(SIUnits.METRE))); + } + // last update index - this is a sync point and you're sure that all data is valid noew + updateState(VehicleHandler.this.checkControlIndex, new DecimalType(checkControlIndex)); + } + + } + } + /** * needs to be synchronized with onResponse update */ private synchronized void updateService() { if (services != null) { - updateState(serviceCount, new DecimalType(services.size())); + updateState(serviceSize, new DecimalType(services.size())); if (!services.isEmpty()) { if (serviceIndexSelected < 0 || serviceIndexSelected >= services.size()) { // select first item @@ -744,7 +776,6 @@ public void onResponse(Optional content) { Windows windowState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Windows.class); updateState(windows, StringType.valueOf(VehicleStatus.checkClosed(windowState))); - updateState(checkControl, StringType.valueOf(vStatus.getCheckControl())); updateState(windowDriverFront, StringType.valueOf(windowState.windowDriverFront)); updateState(windowDriverRear, StringType.valueOf(windowState.windowDriverRear)); @@ -772,6 +803,11 @@ public void onResponse(Optional content) { services = vStatus.cbsData; updateService(); } + updateState(checkControl, StringType.valueOf(vStatus.getCheckControl())); + synchronized (this) { + checkControls = vStatus.checkControlMessages; + updateCheckControls(); + } // Range values // based on unit of length decide if range shall be reported in km or miles diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/check-control-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/check-control-channel-types.xml new file mode 100644 index 0000000000000..f7255bef47e26 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/check-control-channel-types.xml @@ -0,0 +1,22 @@ + + + + String + + + + String + + + + Number + + + + Switch + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/check-control-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/check-control-group.xml new file mode 100644 index 0000000000000..5831484f255a0 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/check-control-group.xml @@ -0,0 +1,18 @@ + + + + + Show the current active CheckControl Messages + + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-channel-types.xml index 664a8b15358b9..badec73ab69f0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-channel-types.xml @@ -15,7 +15,7 @@ Number - + String diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-group.xml index b679bd8fa884f..3d01bab32d197 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/destination-group.xml @@ -4,13 +4,13 @@ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - - Show the Last 3 Destinations + + Shows Your Destinations in a List - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-channel-types.xml index 47eae32696bfc..053c25635400e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-channel-types.xml @@ -3,7 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - + Number diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-group.xml index cc85aad8bf55e..c560655a98318 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/service-group.xml @@ -10,7 +10,7 @@ - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml index 811986ccf9aef..a6632ca6b6ca1 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev.xml @@ -16,6 +16,7 @@ + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml index 8679d09508866..c2ae7a6ab72f5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-bev_rex.xml @@ -16,6 +16,7 @@ + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml index b0bd4123921fb..d16ef96e7d706 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-conv.xml @@ -16,6 +16,7 @@ + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml index 9c190b23e09cd..21c4d32525f13 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/ESH-INF/thing/thing-phev.xml @@ -16,6 +16,7 @@ + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index b75832683d4ee..5dec17656784d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -115,25 +115,24 @@ private void checkResult(ChannelUID channelUID, State state) { case MILEAGE: assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); + if (imperial) { + assertEquals("Miles", ImperialUnits.MILE, qt.getUnit()); + } else { + assertEquals("KM", KILOMETRE, qt.getUnit()); + } switch (gUid) { case CHANNEL_GROUP_RANGE: - if (imperial) { - assertEquals("Miles", ImperialUnits.MILE, qt.getUnit()); - } else { - assertEquals("KM", KILOMETRE, qt.getUnit()); - } assertEquals("Mileage", qt.intValue(), vStatus.mileage); break; case CHANNEL_GROUP_SERVICE: - if (imperial) { - assertEquals("Miles", ImperialUnits.MILE, qt.getUnit()); - } else { - assertEquals("KM", KILOMETRE, qt.getUnit()); - } assertEquals("Mileage", qt.intValue(), vStatus.cbsData.get(0).cbsRemainingMileage); break; + case CHANNEL_GROUP_CHECK_CONTROL: + assertEquals("Mileage", qt.intValue(), vStatus.checkControlMessages.get(0).ccmMileage); + break; default: assertFalse("Channel " + channelUID + " " + state + " not found", true); + break; } break; case RANGE_ELECTRIC: @@ -370,15 +369,36 @@ private void checkResult(ChannelUID channelUID, State state) { wanted = StringType.valueOf(vStatus.sunroof); assertEquals("Window", wanted.toString(), st.toString()); break; - case COUNT: + case SIZE: assertTrue(state instanceof DecimalType); dt = (DecimalType) state; - assertEquals("Number of Services", vStatus.cbsData.size(), dt.intValue()); + switch (gUid) { + case CHANNEL_GROUP_CHECK_CONTROL: + assertEquals("Number CheckControl Messages", vStatus.checkControlMessages.size(), + dt.intValue()); + break; + case CHANNEL_GROUP_SERVICE: + assertEquals("Number of Services", vStatus.cbsData.size(), dt.intValue()); + break; + default: + assertFalse("Channel " + channelUID + " " + state + " not found", true); + break; + } break; case INDEX: assertTrue(state instanceof DecimalType); dt = (DecimalType) state; - assertEquals("Number of Services", 0, dt.intValue()); + switch (gUid) { + case CHANNEL_GROUP_SERVICE: + assertEquals("Index of Services", 0, dt.intValue()); + break; + case CHANNEL_GROUP_CHECK_CONTROL: + assertEquals("Index of CheckControls", 0, dt.intValue()); + break; + default: + assertFalse("Channel " + channelUID + " " + state + " not found", true); + break; + } break; case SERVICE_DATE: assertTrue(state instanceof DateTimeType); @@ -423,8 +443,19 @@ private void checkResult(ChannelUID channelUID, State state) { case NAME: assertTrue(state instanceof StringType); st = (StringType) state; - wanted = StringType.valueOf(Converter.toTitleCase(vStatus.cbsData.get(0).getType())); - assertEquals("Window", wanted.toString(), st.toString()); + switch (gUid) { + case CHANNEL_GROUP_SERVICE: + wanted = StringType.valueOf(Converter.toTitleCase(vStatus.cbsData.get(0).getType())); + assertEquals("Window", wanted.toString(), st.toString()); + break; + case CHANNEL_GROUP_CHECK_CONTROL: + wanted = StringType.valueOf(vStatus.checkControlMessages.get(0).ccmDescriptionShort); + assertEquals("Window", wanted.toString(), st.toString()); + break; + default: + assertFalse("Channel " + channelUID + " " + state + " not found", true); + break; + } break; case DATE: assertTrue(state instanceof DateTimeType); @@ -437,6 +468,7 @@ private void checkResult(ChannelUID channelUID, State state) { break; default: assertFalse("Channel " + channelUID + " " + state + " not found", true); + break; } break; default: diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java index 106eb6a7f95f2..900cbbca277f5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java @@ -49,9 +49,12 @@ public class VehicleTests { private final Logger logger = LoggerFactory.getLogger(VehicleHandler.class); - private static final int HYBRID_CALL_TIMES = 32; - private static final int CONV_CALL_TIMES = 26; - private static final int EV_CALL_TIMES = 27; + private static final int HYBRID_CALL_TIMES = 31; + private static final int CONV_CALL_TIMES = 25; + private static final int EV_CALL_TIMES = 26; + + private static final int LIST_UPDATES = 7; + private static final int CHECK_CONTROL_ACTIVE_CALLS = 3; @Nullable ArgumentCaptor channelCaptor; @@ -131,11 +134,10 @@ private void trace() { */ @Test public void testMyi3Rex() { - int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC_REX.toString(), false); String content = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES + numServices, Optional.empty())); + assertTrue(testVehicle(content, HYBRID_CALL_TIMES + LIST_UPDATES, Optional.empty())); } /** @@ -160,11 +162,10 @@ public void testMyi3Rex() { */ @Test public void testMyi3RexMiles() { - int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC_REX.toString(), true); String content = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES + numServices, Optional.empty())); + assertTrue(testVehicle(content, HYBRID_CALL_TIMES + LIST_UPDATES, Optional.empty())); } /** @@ -185,22 +186,20 @@ public void testMyi3RexMiles() { */ @Test public void testF15() { - int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F15/status.json"); // Check earliest Service by hard Map m = new HashMap(); - // Don>'t test on concrete timestamp - it's idfferent on each machine + // Don>'t test on concrete timestamp - it's is different on each machine // Check for cbsType which is "Oil" instead // m.put(ConnectedDriveConstants.SERVICE_DATE, DateTimeType.valueOf("2018-06-01T14:00:00.000+0200")); m.put(ConnectedDriveConstants.NAME, StringType.valueOf("Oil")); - assertTrue(testVehicle(content, CONV_CALL_TIMES + numServices, Optional.of(m))); + assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES, Optional.of(m))); } @Test public void testF15Miles() { - int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F15/status.json"); @@ -210,7 +209,7 @@ public void testF15Miles() { // Check for cbsType which is "Oil" instead // m.put(ConnectedDriveConstants.SERVICE_DATE, DateTimeType.valueOf("2018-06-01T14:00:00.000+0200")); m.put(ConnectedDriveConstants.NAME, StringType.valueOf("Oil")); - assertTrue(testVehicle(content, CONV_CALL_TIMES + numServices, Optional.of(m))); + assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES, Optional.of(m))); } /** @@ -234,7 +233,7 @@ public void testF31() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F31/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES - 1, Optional.empty())); + assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); } @Test @@ -242,7 +241,7 @@ public void testF31Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F31/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES - 1, Optional.empty())); + assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); } @Test @@ -250,7 +249,7 @@ public void testF35() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F35/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES - 1, Optional.empty())); + assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); } @Test @@ -258,7 +257,7 @@ public void testF35Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F35/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES - 1, Optional.empty())); + assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); } @Test @@ -266,7 +265,7 @@ public void testF45() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F45/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES - 1, Optional.empty())); + assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); } @Test @@ -274,92 +273,83 @@ public void testF45Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F45/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES - 1, Optional.empty())); + assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); } @Test public void testF48() { - int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F48/status.json"); // Check earliest Service by hard Map m = new HashMap(); m.put(ConnectedDriveConstants.CHECK_CONTROL, StringType.valueOf("Tyre Pressure Notification")); - assertTrue(testVehicle(content, CONV_CALL_TIMES + numServices, Optional.of(m))); + assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES + CHECK_CONTROL_ACTIVE_CALLS, Optional.of(m))); } @Test public void testF48Miles() { - int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F48/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES + numServices, Optional.empty())); + assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES + CHECK_CONTROL_ACTIVE_CALLS, Optional.empty())); } @Test public void testG31NBTEvo() { - int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/G31_NBTevo/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES + numServices, Optional.empty())); + assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES, Optional.empty())); } @Test public void testG31NBTEvoMiles() { - int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/G31_NBTevo/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES + numServices, Optional.empty())); + assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES, Optional.empty())); } @Test public void testI01NoRex() { - int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/I01_NOREX/status.json"); - assertTrue(testVehicle(content, EV_CALL_TIMES + numServices, Optional.empty())); + assertTrue(testVehicle(content, EV_CALL_TIMES + LIST_UPDATES, Optional.empty())); } @Test public void testI01NoRexMiles() { - int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/I01_NOREX/status.json"); - assertTrue(testVehicle(content, EV_CALL_TIMES + numServices, Optional.empty())); + assertTrue(testVehicle(content, EV_CALL_TIMES + LIST_UPDATES, Optional.empty())); } @Test public void testI01Rex() { - int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC_REX.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/I01_REX/status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES + numServices, Optional.empty())); + assertTrue(testVehicle(content, HYBRID_CALL_TIMES + LIST_UPDATES, Optional.empty())); } @Test public void testI01RexMiles() { - int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC_REX.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/I01_REX/status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES + numServices, Optional.empty())); + assertTrue(testVehicle(content, HYBRID_CALL_TIMES + LIST_UPDATES, Optional.empty())); } @Test public void test318iF31() { - int numServices = 5; logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F31/status-318i.json"); Map m = new HashMap(); m.put(ConnectedDriveConstants.WINDOWS, StringType.valueOf(Constants.INTERMEDIATE)); - assertTrue(testVehicle(content, CONV_CALL_TIMES + numServices, Optional.of(m))); + assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES, Optional.of(m))); } } From 612a8e0271b48d322fb54eba4c9353be7a0d3589 Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 22 Sep 2020 22:58:44 +0200 Subject: [PATCH 046/176] correct Doors and Windows default values Signed-off-by: Bernd (cherry picked from commit 60158881f7c6730a4960bde43f2dd1c782f5d808) Signed-off-by: Bernd --- .../internal/dto/status/Doors.java | 14 +++--- .../internal/dto/status/VehicleStatus.java | 36 ++++++++++------ .../internal/dto/status/Windows.java | 14 +++--- .../internal/handler/VehicleHandler.java | 2 +- .../internal/utils/Constants.java | 2 + .../internal/dto/StatusWrapper.java | 2 +- .../internal/handler/VehicleTests.java | 43 +++++++++++++++++-- 7 files changed, 83 insertions(+), 30 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Doors.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Doors.java index c4872adaf4417..8e1b39e5fd111 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Doors.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Doors.java @@ -12,16 +12,18 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.dto.status; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; + /** * The {@link Doors} Data Transfer Object * * @author Bernd Weymann - Initial contribution */ public class Doors { - public String doorDriverFront;// ": "CLOSED", - public String doorDriverRear;// ": "CLOSED", - public String doorPassengerFront;// ": "CLOSED", - public String doorPassengerRear;// ": "CLOSED", - public String trunk;// ": "CLOSED", - public String hood;// ": "CLOSED", + public String doorDriverFront = Constants.UNKNOWN;// ": "CLOSED", + public String doorDriverRear = Constants.UNKNOWN;// ": "CLOSED", + public String doorPassengerFront = Constants.UNKNOWN;// ": "CLOSED", + public String doorPassengerRear = Constants.UNKNOWN;// ": "CLOSED", + public String trunk = Constants.UNKNOWN;// ": "CLOSED", + public String hood = Constants.UNKNOWN;// ": "CLOSED", } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java index 9a8b2ef7cefaa..d6191502bfc21 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java @@ -46,18 +46,18 @@ public class VehicleStatus { public String vin;// : "ANONYMOUS", public String updateReason;// ": "VEHICLE_SHUTDOWN_SECURED", public String updateTime;// ": "2020-08-24 T15:55:32+0000", - public String doorDriverFront;// ": "CLOSED", - public String doorDriverRear;// ": "CLOSED", - public String doorPassengerFront;// ": "CLOSED", - public String doorPassengerRear;// ": "CLOSED", - public String windowDriverFront;// ": "CLOSED", - public String windowDriverRear;// ": "CLOSED", - public String windowPassengerFront;// ": "CLOSED", - public String windowPassengerRear;// ": "CLOSED", - public String sunroof;// ": "CLOSED", - public String trunk;// ": "CLOSED", - public String rearWindow;// ": "INVALID", - public String hood;// ": "CLOSED", + public String doorDriverFront = Constants.UNKNOWN;// ": "CLOSED", + public String doorDriverRear = Constants.UNKNOWN;// ": "CLOSED", + public String doorPassengerFront = Constants.UNKNOWN;// ": "CLOSED", + public String doorPassengerRear = Constants.UNKNOWN;// ": "CLOSED", + public String windowDriverFront = Constants.UNKNOWN;// ": "CLOSED", + public String windowDriverRear = Constants.UNKNOWN;// ": "CLOSED", + public String windowPassengerFront = Constants.UNKNOWN;// ": "CLOSED", + public String windowPassengerRear = Constants.UNKNOWN;// ": "CLOSED", + public String sunroof = Constants.UNKNOWN;// ": "CLOSED", + public String trunk = Constants.UNKNOWN;// ": "CLOSED", + public String rearWindow = Constants.UNKNOWN;// ": "INVALID", + public String hood = Constants.UNKNOWN;// ": "CLOSED", public String doorLockState;// ": "SECURED", public String parkingLight;// ": "OFF", public String positionLight;// ": "ON", @@ -177,6 +177,18 @@ public int getNextServiceMileage() { } } + public String checkControlActive() { + if (checkControlMessages == null) { + return UNKNOWN; + } + if (checkControlMessages.isEmpty()) { + return NOT_ACTIVE; + } else { + return ACTIVE; + } + + } + public String getCheckControl() { if (checkControlMessages == null) { return Converter.toTitleCase(UNKNOWN); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Windows.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Windows.java index 8cc3cfc958353..8898f88933f97 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Windows.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Windows.java @@ -12,16 +12,18 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.dto.status; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; + /** * The {@link Windows} Data Transfer Object * * @author Bernd Weymann - Initial contribution */ public class Windows { - public String windowDriverFront;// ": "CLOSED", - public String windowDriverRear;// ": "CLOSED", - public String windowPassengerFront;// ": "CLOSED", - public String windowPassengerRear;// ": "CLOSED", - public String sunroof;// ": "CLOSED", - public String rearWindow;// ": "INVALID", + public String windowDriverFront = Constants.UNKNOWN;// ": "CLOSED", + public String windowDriverRear = Constants.UNKNOWN;// ": "CLOSED", + public String windowPassengerFront = Constants.UNKNOWN;// ": "CLOSED", + public String windowPassengerRear = Constants.UNKNOWN;// ": "CLOSED", + public String sunroof = Constants.UNKNOWN;// ": "CLOSED", + public String rearWindow = Constants.UNKNOWN;// ": "INVALID", } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index f91446099ecd8..9b8b795fd6061 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -803,7 +803,7 @@ public void onResponse(Optional content) { services = vStatus.cbsData; updateService(); } - updateState(checkControl, StringType.valueOf(vStatus.getCheckControl())); + updateState(checkControl, StringType.valueOf(Converter.toTitleCase(vStatus.checkControlActive()))); synchronized (this) { checkControls = vStatus.checkControlMessages; updateCheckControls(); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java index 0da6d9922734c..6c44779ff94ba 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -26,6 +26,8 @@ public class Constants { // For Vehicle Status public static final String OK = "Ok"; + public static final String ACTIVE = "ACTIVE"; + public static final String NOT_ACTIVE = "NOT ACTIVE"; public static final String OPEN = "OPEN"; public static final String INVALID = "INVALID"; public static final String CLOSED = "CLOSED"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index 5dec17656784d..07be53a720767 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -219,7 +219,7 @@ private void checkResult(ChannelUID channelUID, State state) { if (specialHandlingMap.containsKey(CHECK_CONTROL)) { assertEquals("Check Control", specialHandlingMap.get(CHECK_CONTROL).toString(), st.toString()); } else { - assertEquals("Check Control", vStatus.getCheckControl(), st.toString()); + assertEquals("Check Control", Converter.toTitleCase(vStatus.checkControlActive()), st.toString()); } break; case CHARGE_STATUS: diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java index 900cbbca277f5..363ab499d55d9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java @@ -276,15 +276,50 @@ public void testF45Miles() { assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); } + /** + * testF48 + * Channel testbinding::test:status#lock Secured + * Channel testbinding::test:status#doors CLOSED + * Channel testbinding::test:doors#driver-front CLOSED + * Channel testbinding::test:doors#driver-rear CLOSED + * Channel testbinding::test:doors#passenger-front CLOSED + * Channel testbinding::test:doors#passenger-rear CLOSED + * Channel testbinding::test:doors#trunk CLOSED + * Channel testbinding::test:doors#hood CLOSED + * Channel testbinding::test:status#windows CLOSED + * Channel testbinding::test:doors#window-driver-front CLOSED + * Channel testbinding::test:doors#window-driver-rear CLOSED + * Channel testbinding::test:doors#window-passenger-front CLOSED + * Channel testbinding::test:doors#window-passenger-rear CLOSED + * Channel testbinding::test:doors#window-rear INVALID + * Channel testbinding::test:doors#sunroof UNKOWN + * Channel testbinding::test:status#service-date 2019-07-01T14:00:00.000+0200 + * Channel testbinding::test:status#service-mileage -1.0 km + * Channel testbinding::test:service#size 3 + * Channel testbinding::test:service#date 2019-07-01T14:00:00.000+0200 + * Channel testbinding::test:service#mileage 9000.0 km + * Channel testbinding::test:service#name Oil + * Channel testbinding::test:service#index 0 + * Channel testbinding::test:status#check-control Active + * Channel testbinding::test:check#size 1 + * Channel testbinding::test:check#name Tyre pressure notification + * Channel testbinding::test:check#mileage 41544.0 km + * Channel testbinding::test:check#index 0 + * Channel testbinding::test:range#mileage 21529.0 km + * Channel testbinding::test:range#fuel 590.0 km + * Channel testbinding::test:range#radius-fuel 472.0 km + * Channel testbinding::test:range#remaining-fuel 39.0 l + * Channel testbinding::test:status#last-update 2018-03-10T19:35:30.000+0100 + * Channel testbinding::test:location#latitude 50.50505065917969 + * Channel testbinding::test:location#longitude 10.1010103225708 + * Channel testbinding::test:location#heading 141.0 ° + **/ @Test public void testF48() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F48/status.json"); - // Check earliest Service by hard - Map m = new HashMap(); - m.put(ConnectedDriveConstants.CHECK_CONTROL, StringType.valueOf("Tyre Pressure Notification")); - assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES + CHECK_CONTROL_ACTIVE_CALLS, Optional.of(m))); + assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES + CHECK_CONTROL_ACTIVE_CALLS, Optional.empty())); } @Test From e388a0b2795f3883172783f7f183cb28d9825100 Mon Sep 17 00:00:00 2001 From: Bernd Date: Wed, 23 Sep 2020 01:03:23 +0200 Subject: [PATCH 047/176] remove service-name from status Signed-off-by: Bernd (cherry picked from commit 75e7116edbacfdf13d06523382293a4d2a7bc79f) Signed-off-by: Bernd --- .../README.md | 377 ++++++++++-------- .../internal/ConnectedDriveConstants.java | 3 +- .../internal/dto/status/VehicleStatus.java | 1 - .../handler/VehicleChannelHandler.java | 4 +- .../internal/handler/VehicleHandler.java | 5 +- .../i18n/bmwconnecteddrive_de.properties | 1 - .../thing/check-control-channel-types.xml | 22 +- .../ESH-INF/thing/check-control-group.xml | 11 +- .../ESH-INF/thing/ev-last-trip-group.xml | 4 +- .../ESH-INF/thing/ev-vehicle-status-group.xml | 1 - .../ESH-INF/thing/hybrid-last-trip-group.xml | 4 +- .../ESH-INF/thing/service-channel-types.xml | 6 +- .../thing/vehicle-status-channel-types.xml | 4 - .../ESH-INF/thing/vehicle-status-group.xml | 1 - .../internal/dto/TripWrapper.java | 4 +- 15 files changed, 255 insertions(+), 193 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index ee482d518a39f..0238d3a40c683 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -146,20 +146,46 @@ Please check [TroubleShooting Section](#TroubleShooting) for further advice. Reflects Status of the Vehicle. Available for all Vehicles, Read-only. -| Channel Label | Channel Group ID | Channel ID | Type | Description | -|---------------------------|------------------|---------------------|---------------|----------------------------------------------------------------------| -| Overall Door Status | status | doors | String | Closed if all closed, else reports the Door which is still open | -| Overall Window Status | status | windows | String | Closed if all closed, else reports the Window which is still open | -| Doors Locked | status | lock | String | Status if Doors are locked or unlocked | -| Next Service Date | status | service-date | DateTime | Date of Upcoming Service | -| Mileage till Next Service | status | service-mileage | Number:Length | Mileage till Upcoming Service | -| Next Service Description | status | service-name | String | Description of Upcoming Service | -| Check Control | status | check-control | String | Description of actual Check Control message, Ok if none is activated | -| Charging Status | status | charge | String | Only available for PHEV, BEV_REX and BEV | -| Last Status Timestamp | status | last-update | DateTime | Date and Time of last status update. | +| Channel Label | Channel Group ID | Channel ID | Type | Description | +|---------------------------|------------------|---------------------|---------------|-----------------------------------------------------------------------------------| +| Overall Door Status | status | doors | String | **Closed** if all closed otherwise **Open**. **Unknown** if no data is delivered | +| Overall Window Status | status | windows | String | **Closed** if all closed otherwise **Open** or **Intermediate**. **Unknown** if no data is delivered | +| Doors Locked | status | lock | String | Status if Doors are locked or unlocked | +| Next Service Date | status | service-date | DateTime | Date of Upcoming Service | +| Mileage till Next Service | status | service-mileage | Number:Length | Mileage till Upcoming Service | +| Check Control | status | check-control | String | Indicator if CheckControl is **Active** or **Not Active**. **Unknown** if no data is delivered | +| Charging Status | status | charge | String | Only available for PHEV, BEV_REX and BEV | +| Last Status Timestamp | status | last-update | DateTime | Date and Time of last status update. | See [further details for DateTime](#last-status-update-timestamp) in case of wrong timestamp values +#### Services + +Group for all upcoming Services with Description, Service Date and / or Service Mileage +It's designed as [List Interface](#list-interface) so all upcoming Services can be checked. + +| Channel Label | Channel Group ID | Channel ID | Type | +|--------------------------------|------------------|---------------------|----------------| +| Service Name | service | name | String | +| Service Date | service | date | Number | +| Mileage till Service | service | mileage | Number:Length | +| Number of Scheduled Services | service | size | String | +| Current Selected Service Index | service | index | Number | +| Select next Service | service | next | Switch | + +#### Check Control + +Group for all current active CheckControl Messages. +It's designed as [List Interface](#list-interface) to show all active Messages. + +| Channel Label | Channel Group ID | Channel ID | Type | +|---------------------------------|------------------|---------------------|----------------| +| CheckControl Description | check | name | String | +| CheckControl Mileage Occurrence | check | mileage | Number:Length | +| Active CheckControl Messages | check | size | String | +| Selected CheckControl Message | check | index | Number | +| Next CheckControl Message | check | next | Switch | + #### Doors Details Detailed Status of all Doors and Windows @@ -247,13 +273,15 @@ These are Read-only values. Check [Vehicle Properties](#Properties) if *Statistics* is present in *Services Supported* These are Read-only values. -| Channel Label | Channel Group ID | Channel ID | Type | -|---------------------------------------|------------------|-------------------------|---------------| -| Last Trip Date | last-trip | distance | Number:Length | -| Average Power Consumption per 100 km | last-trip | average-consumption | Number:Power | -| Average Power Recuperation per 100 km | last-trip | average-recuperation | Number:Power | -| Last Trip Distance | last-trip | distance | Number:Length | -| Distance since Last Charge | last-trip | distance-since-charging | Number:Length | +| Channel Label | Channel Group ID | Channel ID | Type | +|-----------------------------------------|------------------|------------------------------|---------------| +| Last Trip Date | last-trip | date | DateTime | +| Last Trip Duration | last-trip | duration | Number:Time | +| Average Power Consumption per 100 km | last-trip | average-consumption | Number:Power | +| Average Combined Consumption per 100 km | last-trip | average-combined-consumption | Number:Volume | +| Average Power Recuperation per 100 km | last-trip | average-recuperation | Number:Power | +| Last Trip Distance | last-trip | distance | Number:Length | +| Distance since Last Charge | last-trip | distance-since-charging | Number:Length | #### Lifetime Statistics @@ -261,12 +289,13 @@ These are Read-only values. Check [Vehicle Properties](#Properties) if *Statistics* is present in *Services Supported* These are Read-only values. -| Channel Label | Channel Group ID | Channel ID | Type | -|---------------------------------------|------------------|--------------------------|---------------| -| Average Power Consumption per 100 km | lifetime | average-consumption | Number:Power | -| Average Power Recuperation per 100 km | lifetime | average-recuperation | Number:Power | -| Cumulated Electric Driven Distance | lifetime | cumulated-driven-distance | Number:Length | -| Longest Distance with one Charge | lifetime | single-longest-distance | Number:Length | +| Channel Label | Channel Group ID | Channel ID | Type | +|-----------------------------------------|------------------|------------------------------|---------------| +| Average Power Consumption per 100 km | lifetime | average-consumption | Number:Power | +| Average Power Recuperation per 100 km | lifetime | average-recuperation | Number:Power | +| Cumulated Electric Driven Distance | lifetime | cumulated-driven-distance | Number:Length | +| Average Combined Consumption per 100 km | lifetime | average-combined-consumption | Number:Volume | +| Longest Distance with one Charge | lifetime | single-longest-distance | Number:Length | #### Remote Services @@ -290,19 +319,16 @@ State *Executed* is the final State when Execution is finished. #### Destinations Check [Vehicle Properties](#Properties) if *LastDestinations* is present in *Services Supported* -These are Read-only values. +It's designed as [List Interface](#list-interface) in order to have access to all stored Destinations. -| Channel Label | Channel Group ID | Channel ID | Type | -|--------------------------------------|------------------|---------------------|---------| -| Last Destination Name | destination | name-1 | String | -| Last Destination Latitude | destination | lat-1 | Number | -| Last Destination Longitude | destination | lon-1 | Number | -| Second Last Destination Name | destination | name-2 | String | -| Second Last Destination Latitude | destination | lat-2 | Number | -| Second Last Destination Longitude | destination | lon-2 | Number | -| Third Last Destination Name | destination | name-3 | String | -| Third Last Destination Latitude | destination | lat-3 | Number | -| Third Last Destination Longitude | destination | lon-3 | Number | +| Channel Label | Channel Group ID | Channel ID | Type | +|----------------------------------|------------------|---------------------|---------| +| Destination Name | destination | name | String | +| Destination Latitude | destination | latitude | Number | +| Destination Longitude | destination | longitude | Number | +| Number of Available Destinations | destination | size | String | +| Index of Selected Destination | destination | index | Number | +| Skip to Next Destination | destination | next | Switch | #### Image @@ -445,78 +471,104 @@ Bridge bmwconnecteddrive:account:user "BMW ConnectedDrive Account" [userName=" ### Items ``` -Number:Length i3Mileage "Odometer [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#mileage" } -Number:Length i3Range "Range [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#hybrid"} -Number:Length i3RangeElectric "Electric Range [%d %unit%]" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#electric"} -Number:Length i3RangeFuel "Fuel Range [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#fuel"} -Number:Dimensionless i3BatterySoc "Battery Charge [%.1f %%]" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#soc"} -Number:Volume i3Fuel "Fuel [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-fuel"} -Number:Length i3RadiusElectric "Electric Radius [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#radius-electric" } -Number:Length i3RadiusHybrid "Hybrid Radius [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#radius-hybrid" } - -String i3DoorStatus "Door Status [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#doors" } -String i3WindowStatus "Window Status [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#windows" } -String i3LockStatus "Lock Status [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#lock" } -DateTime i3ServiceDate "Service Date [%1$tb %1$tY]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#service-date" } -String i3ServiceMileage "Service Mileage [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#service-mileage" } -String i3ServiceName "Service Name [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#service-name" } -String i3CheckControl "Check Control [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#check-control" } -String i3ChargingStatus "Charging [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#charge" } -DateTime i3LastUpdate "Update [%1$tA, %1$td.%1$tm. %1$tH:%1$tM]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#last-update"} - -Number:Length i3TripDistance "Distance [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance" } -Number:Length i3TripDistanceSinceCharge "Distance since last Charge [%d %unit%]" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#distance-since-charging" } -Number:Energy i3AvgTripConsumption "Average Consumption [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-consumption" } -Number:Energy i3AvgTripRecuperation "Average Recuperation [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#average-recuperation" } - -Number:Length i3CumulatedElectric "Electric Distance Driven [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#cumulated-driven-distance" } -Number:Length i3LongestEVTrip "Longest Electric Trip [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#single-longest-distance" } -Number:Energy i3AvgConsumption "Average Consumption [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#average-consumption" } -Number:Energy i3AvgRecuperation "Average Recuperation [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:lifetime#average-recuperation" } - -Number i3Latitude "Latitude [%.4f]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:location#latitude" } -Number i3Longitude "Longitude [%.4f]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:location#longitude" } -Number:Angle i3Heading "Heading [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:location#heading" } - -Switch i3RemoteFlash "Flash" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#light" } -Switch i3RemoteFinder "Finder" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#finder" } -Switch i3RemoteLock "Lock" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#lock" } -Switch i3RemoteUnlock "Unlock" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#unlock" } -Switch i3RemoteHorn "Horn Blow" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#horn" } -Switch i3RemoteClimate "Climate" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#climate" } -String i3RemoteState "Remote Execution State [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:remote#state" } - -String i3Dest1Name "Destination 1 [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#name-1" } -Number i3Dest1Lat "Longitude [%.4f]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lat-1" } -Number i3Dest1Lon "Latitude [%.4f]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lon-1" } -String i3Dest2Name "Destination 2 [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#name-2" } -Number i3Dest2Lat "Longitude [%.4f]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lat-2" } -Number i3Dest2Lon "Latitude [%.4f]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lon-2" } -String i3Dest3Name "Destination 3 [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#name-3" } -Number i3Dest3Lat "Longitude [%.4f]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lat-3" } -Number i3Dest3Lon "Latitude [%.4f]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:destination#lon-3" } +Number:Length i3Mileage "Odometer [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#mileage" } +Number:Length i3Range "Range [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#hybrid"} +Number:Length i3RangeElectric "Electric Range [%d %unit%]" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#electric"} +Number:Length i3RangeFuel "Fuel Range [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#fuel"} +Number:Dimensionless i3BatterySoc "Battery Charge [%.1f %%]" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#soc"} +Number:Volume i3Fuel "Fuel [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-fuel"} +Number:Length i3RadiusElectric "Electric Radius [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#radius-electric" } +Number:Length i3RadiusHybrid "Hybrid Radius [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#radius-hybrid" } + +String i3DoorStatus "Door Status [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#doors" } +String i3WindowStatus "Window Status [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#windows" } +String i3LockStatus "Lock Status [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#lock" } +DateTime i3NextServiceDate "Next Service Date [%1$tb %1$tY]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#service-date" } +String i3NextServiceMileage "Next Service Mileage [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#service-mileage" } +String i3CheckControl "Check Control [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#check-control" } +String i3ChargingStatus "Charging [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#charge" } +DateTime i3LastUpdate "Update [%1$tA, %1$td.%1$tm. %1$tH:%1$tM]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#last-update"} + +DateTime i3TripDateTime "Trip Date [%1$tA, %1$td.%1$tm. %1$tH:%1$tM]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#date"} +Number:Time i3TripDuration "Trip Duration [%d %unit%]" AB^Si=zsSw^}U*0NSSv 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�R#W%}g7G!^h^a^8icy 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%0ATi4cjQ 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 Eg4OzIQ~&?~ diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/doc/properties-oh2.png b/bundles/org.openhab.binding.bmwconnecteddrive/doc/properties-oh2.png deleted file mode 100644 index 04dfb6e8d2cea4c12c1f8d8efa74f519a6e1d382..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49353 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 checkControlMessages;// ":[], - public List cbsData; + public List checkControlMessages = new ArrayList();// ":[], + public List cbsData = new ArrayList(); /** * Get Next Service for Date and / or Mileage diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java.bak b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java.bak deleted file mode 100644 index 4ee8b68c1a71f..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java.bak +++ /dev/null @@ -1,247 +0,0 @@ -/** - * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.status; - -import static org.openhab.binding.bmwconnecteddrive.internal.utils.Constants.*; - -import java.lang.reflect.Field; -import java.time.LocalDateTime; -import java.util.List; - -import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; -import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; - -import com.google.gson.annotations.SerializedName; - -/** - * The {@link VehicleStatus} Data Transfer Object - * - * @author Bernd Weymann - Initial contribution - */ -public class VehicleStatus { - public int mileage;// ": 17273, - public float remainingFuel;// ": 4, - public float remainingRangeElectric;// ": 148, - public float remainingRangeElectricMls;// ": 91, - public float remainingRangeFuel;// ": 70," - public float remainingRangeFuelMls;// ":43," - public float maxRangeElectric;// ":216," - public float maxRangeElectricMls;// ":134," - public float maxFuel;// ":8.5, - public float chargingLevelHv;// ":71, - public String vin;// : "ANONYMOUS", - public String updateReason;// ": "VEHICLE_SHUTDOWN_SECURED", - public String updateTime;// ": "2020-08-24 T15:55:32+0000", - public String doorDriverFront = Constants.UNKNOWN;// ": "CLOSED", - public String doorDriverRear = Constants.UNKNOWN;// ": "CLOSED", - public String doorPassengerFront = Constants.UNKNOWN;// ": "CLOSED", - public String doorPassengerRear = Constants.UNKNOWN;// ": "CLOSED", - public String windowDriverFront = Constants.UNKNOWN;// ": "CLOSED", - public String windowDriverRear = Constants.UNKNOWN;// ": "CLOSED", - public String windowPassengerFront = Constants.UNKNOWN;// ": "CLOSED", - public String windowPassengerRear = Constants.UNKNOWN;// ": "CLOSED", - public String sunroof = Constants.UNKNOWN;// ": "CLOSED", - public String trunk = Constants.UNKNOWN;// ": "CLOSED", - public String rearWindow = Constants.UNKNOWN;// ": "INVALID", - public String hood = Constants.UNKNOWN;// ": "CLOSED", - public String doorLockState;// ": "SECURED", - public String parkingLight;// ": "OFF", - public String positionLight;// ": "ON", - public String connectionStatus;// ": "DISCONNECTED", - public String chargingStatus;// ": "INVALID"," - public String lastChargingEndReason;// ": "CHARGING_GOAL_REACHED", - public String lastChargingEndResult;// ": "SUCCESS"," - public Position position; - public String internalDataTimeUTC;// ": "2020-08-24 T15:55:32", - public boolean singleImmediateCharging;// ":false, - public String chargingConnectionType;// ": "CONDUCTIVE", - public String chargingInductivePositioning;// ": "NOT_POSITIONED", - public String vehicleCountry;// ": "DE","+" - @SerializedName("DCS_CCH_Activation") - public String dcsCchActivation;// ": "NA", - @SerializedName("DCS_CCH_Ongoing") - public boolean dcsCchOngoing;// ":false - public List checkControlMessages;// ":[], - public List cbsData; - - /** - * Get Next Service for Date and / or Mileage - * - * @param imperial - * @return - */ - public CBSMessage getNextService() { - CBSMessage cbs = new CBSMessage(); - if (cbsData == null) { - return cbs; - } - if (cbsData.isEmpty()) { - return cbs; - } else { - int serviceMileage = Integer.MAX_VALUE; - LocalDateTime serviceDate = LocalDateTime.now().plusYears(100); - - for (int i = 0; i < cbsData.size(); i++) { - CBSMessage entry = cbsData.get(i); - if (entry.cbsRemainingMileage != 0 && entry.cbsDueDate != null) { - LocalDateTime d = LocalDateTime.parse(entry.cbsDueDate + Constants.UTC_APPENDIX); - // LocalDate d = LocalDate.parse(entry.cbsDueDate + APPENDIX_DAY, - // Converter.SERVICE_DATE_INPUT_PATTERN); - if ((entry.cbsRemainingMileage < serviceMileage) || (d.isBefore(serviceDate))) { - serviceDate = d; - serviceMileage = entry.cbsRemainingMileage; - cbs = entry; - } - } else if (entry.cbsRemainingMileage != 0) { - if (entry.cbsRemainingMileage < serviceMileage) { - serviceMileage = entry.cbsRemainingMileage; - cbs = entry; - } - } else if (entry.cbsDueDate != null) { - LocalDateTime d = LocalDateTime.parse(entry.cbsDueDate + Constants.UTC_APPENDIX); - // LocalDate d = LocalDate.parse(entry.cbsDueDate + APPENDIX_DAY, - // Converter.SERVICE_DATE_INPUT_PATTERN); - if (d.isBefore(serviceDate)) { - serviceDate = d; - cbs = entry; - } - } - } - } - return cbs; - } - - public String getNextServiceDate() { - if (cbsData == null) { - return Constants.NULL_DATE; - } - if (cbsData.isEmpty()) { - return Constants.NULL_DATE; - } else { - LocalDateTime farFuture = LocalDateTime.now().plusYears(100); - LocalDateTime serviceDate = farFuture; - for (int i = 0; i < cbsData.size(); i++) { - CBSMessage entry = cbsData.get(i); - if (entry.cbsDueDate != null) { - LocalDateTime d = LocalDateTime.parse(entry.cbsDueDate + Constants.UTC_APPENDIX); - // LocalDate d = LocalDate.parse(entry.cbsDueDate + APPENDIX_DAY, - // Converter.SERVICE_DATE_INPUT_PATTERN); - if (d.isBefore(serviceDate)) { - serviceDate = d; - } - } - } - if (serviceDate.equals(farFuture)) { - return Constants.NULL_DATE; - } else { - return serviceDate.format(Converter.DATE_INPUT_PATTERN); - } - } - } - - public int getNextServiceMileage() { - if (cbsData == null) { - return -1; - } - if (cbsData.isEmpty()) { - return -1; - } else { - int serviceMileage = Integer.MAX_VALUE; - for (int i = 0; i < cbsData.size(); i++) { - CBSMessage entry = cbsData.get(i); - if (entry.cbsRemainingMileage != 0) { - if (entry.cbsRemainingMileage < serviceMileage) { - serviceMileage = entry.cbsRemainingMileage; - } - } - } - if (serviceMileage != Integer.MAX_VALUE) { - return serviceMileage; - } else { - return -1; - } - } - } - - public String checkControlActive() { - if (checkControlMessages == null) { - return UNKNOWN; - } - if (checkControlMessages.isEmpty()) { - return NOT_ACTIVE; - } else { - return ACTIVE; - } - } - - public String getCheckControl() { - if (checkControlMessages == null) { - return Converter.toTitleCase(UNKNOWN); - } - if (checkControlMessages.isEmpty()) { - return OK; - } else { - return Converter.toTitleCase(checkControlMessages.get(0).ccmDescriptionShort); - } - } - - public String getUpdateTime() { - if (internalDataTimeUTC != null) { - return internalDataTimeUTC; - } else if (updateTime != null) { - return updateTime; - } else { - return Constants.NULL_DATE; - } - } - - /** - * Check for certain Windows or Doors DTO object the "Closed" Status - * INVALID values will be ignored - * - * @param dto - * @return Closed if all "Closed", "Open" otherwise - */ - public static String checkClosed(Object dto) { - String overallState = Constants.UNKNOWN; - for (Field field : dto.getClass().getDeclaredFields()) { - try { - Object d = field.get(dto); - if (d != null) { - String state = d.toString(); - // skip invalid entries - they don't apply to this Vehicle - if (!state.equalsIgnoreCase(INVALID)) { - if (state.equalsIgnoreCase(OPEN)) { - overallState = OPEN; - // stop searching for more open items - overall Doors / Windows are OPEN - break; - } else if (state.equalsIgnoreCase(INTERMEDIATE)) { - if (!overallState.equalsIgnoreCase(OPEN)) { - overallState = INTERMEDIATE; - // continue searching - maybe another Door / Window is OPEN - } - } else if (state.equalsIgnoreCase(CLOSED)) { - // at least one valid object needs to be found in order to reply "CLOSED" - if (overallState.equalsIgnoreCase(UNKNOWN)) { - overallState = CLOSED; - } - } - } - } - } catch (IllegalArgumentException | IllegalAccessException e) { - return UNKNOWN; - } - } - return overallState; - } -} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 4ec81dbca2638..f8d39a57a7ff0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -21,6 +21,12 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; import org.openhab.binding.bmwconnecteddrive.internal.dto.Destination; +import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.ChargeProfile; +import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.ChargingWindow; +import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.Timer; +import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.WeeklyPlanner; +import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTrips; +import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTrip; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.CBSMessage; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.CCMMessage; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Doors; @@ -31,6 +37,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DecimalType; +import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.StringType; import org.openhab.core.library.unit.ImperialUnits; @@ -407,9 +414,61 @@ private void updateDestination() { * Channel Groups */ - protected void updateDoors(Doors doorState) { - updateState(doors, StringType.valueOf(VehicleStatus.checkClosed(doorState))); + protected void updateAllTrips(AllTrips allTrips) { + updateState(lifeTimeCumulatedDrivenDistance, QuantityType + .valueOf(Converter.round(allTrips.totalElectricDistance.userTotal), MetricPrefix.KILO(SIUnits.METRE))); + updateState(lifeTimeSingleLongestDistance, QuantityType + .valueOf(Converter.round(allTrips.chargecycleRange.userHigh), MetricPrefix.KILO(SIUnits.METRE))); + updateState(lifeTimeAverageConsumption, QuantityType + .valueOf(Converter.round(allTrips.avgElectricConsumption.userAverage), SmartHomeUnits.KILOWATT_HOUR)); + updateState(lifetimeAvgCombinedConsumption, + QuantityType.valueOf(allTrips.avgCombinedConsumption.userAverage, SmartHomeUnits.LITRE)); + updateState(lifeTimeAverageRecuperation, QuantityType + .valueOf(Converter.round(allTrips.avgRecuperation.userAverage), SmartHomeUnits.KILOWATT_HOUR)); + updateState(tripDistanceSinceCharging, QuantityType.valueOf( + Converter.round(allTrips.chargecycleRange.userCurrentChargeCycle), MetricPrefix.KILO(SIUnits.METRE))); + } + + protected void updateLastTrip(LastTrip trip) { + // Whyever the Last Trip DateTime is delivered without offest - so LocalTime + updateState(tripDateTime, DateTimeType.valueOf(Converter.getLocalDateTimeWithoutOffest(trip.date))); + updateState(tripDuration, QuantityType.valueOf(trip.duration, SmartHomeUnits.MINUTE)); + updateState(tripDistance, + QuantityType.valueOf(Converter.round(trip.totalDistance), MetricPrefix.KILO(SIUnits.METRE))); + updateState(tripAvgConsumption, + QuantityType.valueOf(Converter.round(trip.avgElectricConsumption), SmartHomeUnits.KILOWATT_HOUR)); + updateState(tripAvgCombinedConsumption, + QuantityType.valueOf(trip.avgCombinedConsumption, SmartHomeUnits.LITRE)); + updateState(tripAvgRecuperation, + QuantityType.valueOf(Converter.round(trip.avgRecuperation), SmartHomeUnits.KILOWATT_HOUR)); + } + protected void updateChargeProfile(ChargeProfile cp) { + WeeklyPlanner planner = cp.weeklyPlanner; + updateState(chargeProfileClimate, OnOffType.from(planner.climatizationEnabled)); + updateState(chargeProfileChargeMode, StringType.valueOf(Converter.toTitleCase(planner.chargingMode))); + + ChargingWindow cw = planner.preferredChargingWindow; + updateState(chargeWindowStart, StringType.valueOf(cw.startTime)); + updateState(chargeWindowEnd, StringType.valueOf(cw.endTime)); + + Timer t1 = planner.timer1; + updateState(timer1Departure, StringType.valueOf(t1.departureTime)); + updateState(timer1Enabled, OnOffType.from(t1.timerEnabled)); + updateState(timer1Days, StringType.valueOf(t1.getDays())); + + Timer t2 = planner.timer2; + updateState(timer2Departure, StringType.valueOf(t2.departureTime)); + updateState(timer2Enabled, OnOffType.from(t2.timerEnabled)); + updateState(timer2Days, StringType.valueOf(t2.getDays())); + + Timer t3 = planner.timer3; + updateState(timer3Departure, StringType.valueOf(t3.departureTime)); + updateState(timer3Enabled, OnOffType.from(t3.timerEnabled)); + updateState(timer3Days, StringType.valueOf(t3.getDays())); + } + + protected void updateDoors(Doors doorState) { updateState(doorDriverFront, StringType.valueOf(doorState.doorDriverFront)); updateState(doorDriverRear, StringType.valueOf(doorState.doorDriverRear)); updateState(doorPassengerFront, StringType.valueOf(doorState.doorPassengerFront)); @@ -419,8 +478,6 @@ protected void updateDoors(Doors doorState) { } protected void updateWindows(Windows windowState) { - updateState(windows, StringType.valueOf(VehicleStatus.checkClosed(windowState))); - updateState(windowDriverFront, StringType.valueOf(windowState.windowDriverFront)); updateState(windowDriverRear, StringType.valueOf(windowState.windowDriverRear)); updateState(windowPassengerFront, StringType.valueOf(windowState.windowPassengerFront)); @@ -452,6 +509,17 @@ protected void updateVehicleStatus(VehicleStatus vStatus) { updateState(serviceNextMileage, QuantityType.valueOf(Converter.round(nextServiceMileage), MetricPrefix.KILO(SIUnits.METRE))); } + // CheckControl Active? + updateState(checkControl, StringType.valueOf(Converter.toTitleCase(vStatus.checkControlActive()))); + // last update Time + updateState(lastUpdate, DateTimeType.valueOf(Converter.getLocalDateTime(vStatus.getUpdateTime()))); + + Doors doorState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Doors.class); + Windows windowState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Windows.class); + updateState(doors, StringType.valueOf(VehicleStatus.checkClosed(doorState))); + updateState(windows, StringType.valueOf(VehicleStatus.checkClosed(windowState))); + updateDoors(doorState); + updateWindows(windowState); // Range values // based on unit of length decide if range shall be reported in km or miles @@ -508,8 +576,6 @@ protected void updateVehicleStatus(VehicleStatus vStatus) { if (hasFuel) { updateState(remainingFuel, QuantityType.valueOf(vStatus.remainingFuel, SmartHomeUnits.LITRE)); } - // last update Time - updateState(lastUpdate, DateTimeType.valueOf(Converter.getLocalDateTime(vStatus.getUpdateTime()))); // Charge Values if (isElectric) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index cdc2657015635..7ded13a1e8b03 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -25,33 +25,23 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.DestinationContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.ChargeProfile; -import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.ChargingWindow; -import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.Timer; -import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.WeeklyPlanner; import org.openhab.binding.bmwconnecteddrive.internal.dto.compat.VehicleAttributesContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTrips; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTripsContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTrip; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTripContainer; -import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Doors; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; -import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Windows; import org.openhab.binding.bmwconnecteddrive.internal.handler.RemoteServiceHandler.ExecutionState; import org.openhab.binding.bmwconnecteddrive.internal.handler.RemoteServiceHandler.RemoteService; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.openhab.binding.bmwconnecteddrive.internal.utils.ImageProperties; import org.openhab.core.io.net.http.HttpUtil; -import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DecimalType; 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.MetricPrefix; -import org.openhab.core.library.unit.SIUnits; -import org.openhab.core.library.unit.SmartHomeUnits; import org.openhab.core.thing.Bridge; import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.Thing; @@ -202,7 +192,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { case CHANNEL_GROUP_DESTINATION: if (command instanceof OnOffType) { if (command.equals(OnOffType.ON)) { - destinationCallback.next(); + nextDestination(); updateState(channelUID, OnOffType.OFF); } } @@ -452,28 +442,7 @@ public void onResponse(Optional content) { chargeProfileCache = content; if (content.isPresent()) { ChargeProfile cp = Converter.getGson().fromJson(content.get(), ChargeProfile.class); - WeeklyPlanner planner = cp.weeklyPlanner; - updateState(chargeProfileClimate, OnOffType.from(planner.climatizationEnabled)); - updateState(chargeProfileChargeMode, StringType.valueOf(Converter.toTitleCase(planner.chargingMode))); - - ChargingWindow cw = planner.preferredChargingWindow; - updateState(chargeWindowStart, StringType.valueOf(cw.startTime)); - updateState(chargeWindowEnd, StringType.valueOf(cw.endTime)); - - Timer t1 = planner.timer1; - updateState(timer1Departure, StringType.valueOf(t1.departureTime)); - updateState(timer1Enabled, OnOffType.from(t1.timerEnabled)); - updateState(timer1Days, StringType.valueOf(t1.getDays())); - - Timer t2 = planner.timer2; - updateState(timer2Departure, StringType.valueOf(t2.departureTime)); - updateState(timer2Enabled, OnOffType.from(t2.timerEnabled)); - updateState(timer2Days, StringType.valueOf(t2.getDays())); - - Timer t3 = planner.timer3; - updateState(timer3Departure, StringType.valueOf(t3.departureTime)); - updateState(timer3Enabled, OnOffType.from(t3.timerEnabled)); - updateState(timer3Days, StringType.valueOf(t3.getDays())); + updateChargeProfile(cp); } } @@ -562,23 +531,11 @@ public class AllTripsCallback implements StringResponseCallback { public void onResponse(Optional content) { if (content.isPresent()) { allTripsCache = content; - AllTripsContainer at = Converter.getGson().fromJson(content.get(), AllTripsContainer.class); - AllTrips c = at.allTrips; - if (c == null) { - return; + AllTripsContainer atc = Converter.getGson().fromJson(content.get(), AllTripsContainer.class); + AllTrips at = atc.allTrips; + if (at != null) { + updateAllTrips(at); } - updateState(lifeTimeCumulatedDrivenDistance, QuantityType - .valueOf(Converter.round(c.totalElectricDistance.userTotal), MetricPrefix.KILO(SIUnits.METRE))); - updateState(lifeTimeSingleLongestDistance, QuantityType - .valueOf(Converter.round(c.chargecycleRange.userHigh), MetricPrefix.KILO(SIUnits.METRE))); - updateState(lifeTimeAverageConsumption, QuantityType - .valueOf(Converter.round(c.avgElectricConsumption.userAverage), SmartHomeUnits.KILOWATT_HOUR)); - updateState(lifetimeAvgCombinedConsumption, - QuantityType.valueOf(c.avgCombinedConsumption.userAverage, SmartHomeUnits.LITRE)); - updateState(lifeTimeAverageRecuperation, QuantityType - .valueOf(Converter.round(c.avgRecuperation.userAverage), SmartHomeUnits.KILOWATT_HOUR)); - updateState(tripDistanceSinceCharging, QuantityType.valueOf( - Converter.round(c.chargecycleRange.userCurrentChargeCycle), MetricPrefix.KILO(SIUnits.METRE))); } } @@ -600,20 +557,9 @@ public void onResponse(Optional content) { lastTripCache = content; LastTripContainer lt = Converter.getGson().fromJson(content.get(), LastTripContainer.class); LastTrip trip = lt.lastTrip; - if (trip == null) { - return; + if (trip != null) { + updateLastTrip(trip); } - // Whyever the Last Trip DateTime is delivered without offest - so LocalTime - updateState(tripDateTime, DateTimeType.valueOf(Converter.getLocalDateTimeWithoutOffest(trip.date))); - updateState(tripDuration, QuantityType.valueOf(trip.duration, SmartHomeUnits.MINUTE)); - updateState(tripDistance, - QuantityType.valueOf(Converter.round(trip.totalDistance), MetricPrefix.KILO(SIUnits.METRE))); - updateState(tripAvgConsumption, QuantityType.valueOf(Converter.round(trip.avgElectricConsumption), - SmartHomeUnits.KILOWATT_HOUR)); - updateState(tripAvgCombinedConsumption, - QuantityType.valueOf(trip.avgCombinedConsumption, SmartHomeUnits.LITRE)); - updateState(tripAvgRecuperation, - QuantityType.valueOf(Converter.round(trip.avgRecuperation), SmartHomeUnits.KILOWATT_HOUR)); } } @@ -660,10 +606,6 @@ public void onResponse(Optional content) { return; } updateVehicleStatus(vStatus); - Doors doorState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Doors.class); - updateDoors(doorState); - Windows windowState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Windows.class); - updateWindows(windowState); setCheckControlList(vStatus.checkControlMessages); setServiceList(vStatus.cbsData); updatePosition(vStatus.position); @@ -678,6 +620,17 @@ public void onError(NetworkError error) { } } + /** + * Fallback API if origin isn't supported. + * This comes from the Community Discussion where a Vehicle from 2015 answered with "404" + * https://community.openhab.org/t/bmw-connecteddrive-binding/105124 + * + * Selection of API was discussed here + * https://community.openhab.org/t/bmw-connecteddrive-bmw-i3/103876 + * + * I figured out that only one API was working for this Vehicle. So this backward compatible Callback is introduced. + * The delivered data is converted into the origin dto object so no changes in previous functional code needed + */ @NonNullByDefault({}) public class OldVehicleStatusCallback implements StringResponseCallback { @Override diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java.bak b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java.bak deleted file mode 100644 index acbfcfd47c8e5..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java.bak +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.utils; - -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -import com.google.gson.Gson; - -/** - * The {@link Converter} Conversion Helpers - * - * @author Bernd Weymann - Initial contribution - */ -@NonNullByDefault -public class Converter { - public static final DateTimeFormatter SERVICE_DATE_INPUT_PATTERN = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - public static final DateTimeFormatter SERVICE_DATE_OUTPUT_PATTERN = DateTimeFormatter.ofPattern("MMM yyyy"); - - public static final String DATE_INPUT_PATTERN_STRING = "yyyy-MM-dd'T'HH:mm:ss"; - public static final String DATE_INPUT_ZONE_PATTERN_STRING = "yyyy-MM-dd'T'HH:mm:ssZ"; - public static final DateTimeFormatter DATE_INPUT_PATTERN = DateTimeFormatter.ofPattern(DATE_INPUT_PATTERN_STRING); - public static final DateTimeFormatter DATE_INPUT_ZONE_PATTERN = DateTimeFormatter - .ofPattern(DATE_INPUT_ZONE_PATTERN_STRING); - public static final DateTimeFormatter DATE_TIMEZONE_INPUT_PATTERN = DateTimeFormatter - .ofPattern("yyyy-MM-dd'T'HH:mm:ssZ"); - public static final DateTimeFormatter DATE_OUTPUT_PATTERN = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); - - private static final Gson GSON = new Gson(); - - public static double round(double value) { - double scale = Math.pow(10, 1); - return Math.round(value * scale) / scale; - } - - public static String getLocalDateTimeWithoutOffest(@Nullable String input) { - if (input == null) { - return Constants.NULL_DATE; - } - LocalDateTime ldt; - if (input.contains(Constants.PLUS)) { - ldt = LocalDateTime.parse(input, Converter.DATE_INPUT_ZONE_PATTERN); - } else { - ldt = LocalDateTime.parse(input, Converter.DATE_INPUT_PATTERN); - } - return ldt.format(Converter.DATE_INPUT_PATTERN); - } - - public static String getLocalDateTime(@Nullable String input) { - if (input == null) { - return Constants.NULL_DATE; - } - LocalDateTime ldt; - if (input.contains(Constants.PLUS)) { - ldt = LocalDateTime.parse(input, Converter.DATE_INPUT_ZONE_PATTERN); - } else { - ldt = LocalDateTime.parse(input, Converter.DATE_INPUT_PATTERN); - } - ZonedDateTime zdtUTC = ldt.atZone(ZoneId.of("UTC")); - ZonedDateTime zdtLZ = zdtUTC.withZoneSameInstant(ZoneId.systemDefault()); - return zdtLZ.format(Converter.DATE_INPUT_PATTERN); - } - - public static String toTitleCase(@Nullable String input) { - if (input == null) { - return Converter.toTitleCase(Constants.UNKNOWN); - } else { - String lower = input.replaceAll(Constants.UNDERLINE, Constants.SPACE).toLowerCase(); - String[] arr = lower.split(Constants.SPACE); - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < arr.length; i++) { - sb.append(Character.toUpperCase(arr[i].charAt(0))).append(arr[i].substring(1)).append(" "); - } - return sb.toString().trim(); - } - } - - public static String capitalizeFirst(String str) { - return str.substring(0, 1).toUpperCase() + str.substring(1); - } - - public static Gson getGson() { - return GSON; - } - - /** - * Measure distance between 2 coordinates - * - * @param sourceLatitude - * @param sourceLongitude - * @param destinationLatitude - * @param destinationLongitude - * @return distance - */ - public static double measureDistance(double sourceLatitude, double sourceLongitude, double destinationLatitude, - double destinationLongitude) { - double earthRadius = 6378.137; // Radius of earth in KM - double dLat = destinationLatitude * Math.PI / 180 - sourceLatitude * Math.PI / 180; - double dLon = destinationLongitude * Math.PI / 180 - sourceLongitude * Math.PI / 180; - double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(sourceLatitude * Math.PI / 180) - * Math.cos(destinationLatitude * Math.PI / 180) * Math.sin(dLon / 2) * Math.sin(dLon / 2); - double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - return earthRadius * c; - } - - /** - * Easy function but there's some measures behind: - * Guessing the range of the Vehicle on Map. If you can drive x kilometers with your Vehicle it's not feasible to - * project this x km Radius on Map. The roads to be taken are causing some overhead because they are not a straight - * line from Location A to B. - * I've taken some measurements to calculate the overhead factor based on Google Maps - * Berlin - Dresden: Road Distance: 193 air-line Distance 167 = Factor 87% - * Kassel - Frankfurt: Road Distance: 199 air-line Distance 143 = Factor 72% - * After measuring more distances you'll find out that the outcome is between 70% and 90%. So - * - * This depends also on the roads of a concrete route but this is only a guess without any Route Navigation behind - * - * In future it's foreseen to replace this with BMW RangeMap Service which isn't running at the moment. - * - * @param range - * @return mapping from air-line distance to "real road" distance - */ - public static double guessRangeRadius(float range) { - return range * 0.8; - } -} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleStatusTest.java.bak b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleStatusTest.java.bak deleted file mode 100644 index 2b5f2fd453862..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleStatusTest.java.bak +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.junit.jupiter.api.Test; -import org.openhab.binding.bmwconnecteddrive.internal.dto.status.CBSMessage; -import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Position; -import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; -import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; -import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; - -import com.google.gson.Gson; - -/** - * The {@link VehicleStatusTest} Test json responses from ConnectedDrive Portal - * - * @author Bernd Weymann - Initial contribution - */ -@NonNullByDefault -public class VehicleStatusTest { - private static final Gson GSON = new Gson(); - - @Test - public void testBevRexValues() { - String resource1 = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); - VehicleStatusContainer status = GSON.fromJson(resource1, VehicleStatusContainer.class); - VehicleStatus vStatus = status.vehicleStatus; - assertEquals(17273.0, vStatus.mileage, 0.1, "Mileage"); - Position p = vStatus.position; - assertEquals(219, p.heading, "Heading"); - - assertEquals("NA", vStatus.dcsCchActivation, "DCS Activation"); - assertEquals(false, vStatus.dcsCchOngoing, "DCS Ongoing"); - } - - @Test - public void testServices() { - String resource1 = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); - VehicleStatusContainer status = GSON.fromJson(resource1, VehicleStatusContainer.class); - VehicleStatus vStatus = status.vehicleStatus; - List services = vStatus.cbsData; - CBSMessage message = services.get(0); - assertEquals(15345, message.cbsRemainingMileage, "Service Mileage"); - message = services.get(1); - assertEquals(-1, message.cbsRemainingMileage, "Service Mileage "); - } -} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java index 4733e51ea0f41..ac700fd96ad49 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java @@ -51,12 +51,17 @@ public class VehicleTests { private final Logger logger = LoggerFactory.getLogger(VehicleHandler.class); - private static final int HYBRID_CALL_TIMES = 31; - private static final int CONV_CALL_TIMES = 25; - private static final int EV_CALL_TIMES = 26; - - private static final int LIST_UPDATES = 7; - private static final int CHECK_CONTROL_ACTIVE_CALLS = 3; + private static final int STATUS_ELECTRIC = 8; + private static final int STATUS_CONV = 7; + private static final int RANGE_HYBRID = 9; + private static final int RANGE_CONV = 4; + private static final int RANGE_ELECTRIC = 4; + private static final int DOORS = 12; + private static final int CHECK_EMPTY = 1; + private static final int CHECK_AVAILABLE = 4; + private static final int SERVICE_AVAILABLE = 5; + private static final int SERVICE_EMPTY = 0; + private static final int POSITION = 3; @Nullable ArgumentCaptor channelCaptor; @@ -114,78 +119,76 @@ private void trace() { } /** - * Sequence for BEV_REX + * Test various Vehicles from users which delivered their fingerprint. + * The tests are checking the chain from "JSON to Channel update". + * Checks are done in an automated way cross checking the data from JSON and data delivered via Channel. + * Also important the updates are counted in order to check if code changes are affecting Channel Updates. + * + * With the given output the updated Channels are visible. + * Example: + * + * testi3Rex + * [main] INFO org.eclipse.jetty.util.log - Logging initialized @3733ms * Channel testbinding::test:status#lock Secured - * Channel testbinding::test:status#doors Closed - * Channel testbinding::test:status#windows Closed - * Channel testbinding::test:status#check-control Ok - * Channel testbinding::test:status#service Nov 2021 - Brake Fluid - * Channel testbinding::test:status#charging-status Invalid + * Channel testbinding::test:status#service-date 2021-11-01T13:00:00.000+0100 + * Channel testbinding::test:status#service-mileage -1.0 km + * Channel testbinding::test:status#check-control Not Active + * Channel testbinding::test:status#last-update 2020-08-24T17:55:32.000+0200 + * Channel testbinding::test:status#doors CLOSED + * Channel testbinding::test:status#windows CLOSED + * Channel testbinding::test:doors#driver-front CLOSED + * Channel testbinding::test:doors#driver-rear CLOSED + * Channel testbinding::test:doors#passenger-front CLOSED + * Channel testbinding::test:doors#passenger-rear CLOSED + * Channel testbinding::test:doors#trunk CLOSED + * Channel testbinding::test:doors#hood CLOSED + * Channel testbinding::test:doors#window-driver-front CLOSED + * Channel testbinding::test:doors#window-driver-rear CLOSED + * Channel testbinding::test:doors#window-passenger-front CLOSED + * Channel testbinding::test:doors#window-passenger-rear CLOSED + * Channel testbinding::test:doors#window-rear INVALID + * Channel testbinding::test:doors#sunroof CLOSED * Channel testbinding::test:range#mileage 17273.0 km - * Channel testbinding::test:range#remaining-range-electric 148.0 km - * Channel testbinding::test:range#remaining-range-fuel 70.0 km - * Channel testbinding::test:range#remaining-range-hybrid 218.0 km - * Channel testbinding::test:location#range-radius 218000.0 - * Channel testbinding::test:range#remaining-soc 71.0 % + * Channel testbinding::test:range#electric 148.0 km + * Channel testbinding::test:range#radius-electric 118.4 km + * Channel testbinding::test:range#fuel 70.0 km + * Channel testbinding::test:range#radius-fuel 56.0 km + * Channel testbinding::test:range#hybrid 218.0 km + * Channel testbinding::test:range#radius-hybrid 174.4 km + * Channel testbinding::test:range#soc 71.0 % * Channel testbinding::test:range#remaining-fuel 4.0 l - * Channel testbinding::test:range#last-update 24.08.2020 17:55 - * Channel testbinding::test:location#latitude 50.55604934692383 - * Channel testbinding::test:location#longitude 8.4956693649292 - * Channel testbinding::test:location#latlong 50.55605,8.495669 + * Channel testbinding::test:status#charge Charging Goal Reached + * Channel testbinding::test:check#size 0 + * Channel testbinding::test:service#size 4 + * Channel testbinding::test:service#date 2021-11-01T13:00:00.000+0100 + * Channel testbinding::test:service#mileage 15345.0 km + * Channel testbinding::test:service#name Brake Fluid + * Channel testbinding::test:service#index 0 + * Channel testbinding::test:location#latitude 56.78900146484375 + * Channel testbinding::test:location#longitude 8.765000343322754 * Channel testbinding::test:location#heading 219.0 ° + * */ + @Test - public void testMyi3Rex() { + public void testi3Rex() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC_REX.toString(), false); String content = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES + LIST_UPDATES, Optional.empty())); + assertTrue(testVehicle(content, + STATUS_ELECTRIC + RANGE_HYBRID + DOORS + CHECK_EMPTY + SERVICE_AVAILABLE + POSITION, Optional.empty())); } - /** - * Channel testbinding::test:status#lock Secured - * Channel testbinding::test:status#doors Closed - * Channel testbinding::test:status#windows Closed - * Channel testbinding::test:status#check-control Ok - * Channel testbinding::test:status#service Nov 2021 - Brake Fluid - * Channel testbinding::test:status#charging-status Invalid - * Channel testbinding::test:range#mileage 17273.0 mi - * Channel testbinding::test:range#remaining-range-electric 91.0 mi - * Channel testbinding::test:range#remaining-range-fuel 43.0 mi - * Channel testbinding::test:range#remaining-range-hybrid 134.0 mi - * Channel testbinding::test:location#range-radius 707520.0 - * Channel testbinding::test:range#remaining-soc 71.0 % - * Channel testbinding::test:range#remaining-fuel 4.0 l - * Channel testbinding::test:range#last-update 24.08.2020 17:55 - * Channel testbinding::test:location#latitude 50.55604934692383 - * Channel testbinding::test:location#longitude 8.4956693649292 - * Channel testbinding::test:location#latlong 50.55605,8.495669 - * Channel testbinding::test:location#heading 219.0 ° - */ @Test - public void testMyi3RexMiles() { + public void testi3RexMiles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC_REX.toString(), true); String content = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES + LIST_UPDATES, Optional.empty())); + // assertTrue(testVehicle(content, HYBRID_CALL_TIMES + LIST_UPDATES, Optional.empty())); + assertTrue(testVehicle(content, + STATUS_ELECTRIC + RANGE_HYBRID + DOORS + CHECK_EMPTY + SERVICE_AVAILABLE + POSITION, Optional.empty())); } - /** - * Channel testbinding::test:status#lock Unlocked - * Channel testbinding::test:status#doors Closed - * Channel testbinding::test:status#windows Closed - * Channel testbinding::test:status#check-control Ok - * Channel testbinding::test:status#service Jun 2018 or in 12000 km - Oil - * Channel testbinding::test:range#mileage 1629.0 km - * Channel testbinding::test:range#remaining-range-fuel 249.0 km - * Channel testbinding::test:location#range-radius 249000.0 - * Channel testbinding::test:range#remaining-fuel 30.0 l - * Channel testbinding::test:range#last-update 09.03.2018 04:21 - * Channel testbinding::test:location#latitude 123.12300109863281 - * Channel testbinding::test:location#longitude -123.12300109863281 - * Channel testbinding::test:location#latlong 123.123,-123.123 - * Channel testbinding::test:location#heading 11.0 ° - */ @Test public void testF15() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); @@ -197,7 +200,8 @@ public void testF15() { // Check for cbsType which is "Oil" instead // m.put(ConnectedDriveConstants.SERVICE_DATE, DateTimeType.valueOf("2018-06-01T14:00:00.000+0200")); m.put(ConnectedDriveConstants.NAME, StringType.valueOf("Oil")); - assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES, Optional.of(m))); + assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + POSITION + SERVICE_AVAILABLE + CHECK_EMPTY, + Optional.of(m))); } @Test @@ -211,31 +215,16 @@ public void testF15Miles() { // Check for cbsType which is "Oil" instead // m.put(ConnectedDriveConstants.SERVICE_DATE, DateTimeType.valueOf("2018-06-01T14:00:00.000+0200")); m.put(ConnectedDriveConstants.NAME, StringType.valueOf("Oil")); - assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES, Optional.of(m))); + assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + POSITION + SERVICE_AVAILABLE + CHECK_EMPTY, + Optional.of(m))); } - /** - * Channel testbinding::test:status#lock Unkown - * Channel testbinding::test:status#doors Unkown - * Channel testbinding::test:status#windows Unkown - * Channel testbinding::test:status#check-control Unkown - * Channel testbinding::test:status#service Unkown - * Channel testbinding::test:range#mileage 0.0 km - * Channel testbinding::test:range#remaining-range-fuel 0.0 km - * Channel testbinding::test:location#range-radius 0.0 - * Channel testbinding::test:range#remaining-fuel 0.0 l - * Channel testbinding::test:range#last-update Unkown - * Channel testbinding::test:location#latitude 12.345600128173828 - * Channel testbinding::test:location#longitude 34.56779861450195 - * Channel testbinding::test:location#latlong 12.3456,34.5678 - * Channel testbinding::test:location#heading 0.0 ° @Test - */ @Test public void testF31() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F31/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + POSITION + CHECK_EMPTY, Optional.empty())); } @Test @@ -243,7 +232,7 @@ public void testF31Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F31/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + POSITION + CHECK_EMPTY, Optional.empty())); } @Test @@ -251,7 +240,7 @@ public void testF35() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F35/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + POSITION + CHECK_EMPTY, Optional.empty())); } @Test @@ -259,7 +248,7 @@ public void testF35Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F35/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + POSITION + CHECK_EMPTY, Optional.empty())); } @Test @@ -267,7 +256,9 @@ public void testF45() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F45/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); + // assertTrue(testVehicle(content, 27, Optional.empty())); + assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + SERVICE_EMPTY + CHECK_EMPTY + POSITION, + Optional.empty())); } @Test @@ -275,53 +266,17 @@ public void testF45Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F45/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); + assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + SERVICE_EMPTY + CHECK_EMPTY + POSITION, + Optional.empty())); } - /** - * testF48 - * Channel testbinding::test:status#lock Secured - * Channel testbinding::test:status#doors CLOSED - * Channel testbinding::test:doors#driver-front CLOSED - * Channel testbinding::test:doors#driver-rear CLOSED - * Channel testbinding::test:doors#passenger-front CLOSED - * Channel testbinding::test:doors#passenger-rear CLOSED - * Channel testbinding::test:doors#trunk CLOSED - * Channel testbinding::test:doors#hood CLOSED - * Channel testbinding::test:status#windows CLOSED - * Channel testbinding::test:doors#window-driver-front CLOSED - * Channel testbinding::test:doors#window-driver-rear CLOSED - * Channel testbinding::test:doors#window-passenger-front CLOSED - * Channel testbinding::test:doors#window-passenger-rear CLOSED - * Channel testbinding::test:doors#window-rear INVALID - * Channel testbinding::test:doors#sunroof UNKOWN - * Channel testbinding::test:status#service-date 2019-07-01T14:00:00.000+0200 - * Channel testbinding::test:status#service-mileage -1.0 km - * Channel testbinding::test:service#size 3 - * Channel testbinding::test:service#date 2019-07-01T14:00:00.000+0200 - * Channel testbinding::test:service#mileage 9000.0 km - * Channel testbinding::test:service#name Oil - * Channel testbinding::test:service#index 0 - * Channel testbinding::test:status#check-control Active - * Channel testbinding::test:check#size 1 - * Channel testbinding::test:check#name Tyre pressure notification - * Channel testbinding::test:check#mileage 41544.0 km - * Channel testbinding::test:check#index 0 - * Channel testbinding::test:range#mileage 21529.0 km - * Channel testbinding::test:range#fuel 590.0 km - * Channel testbinding::test:range#radius-fuel 472.0 km - * Channel testbinding::test:range#remaining-fuel 39.0 l - * Channel testbinding::test:status#last-update 2018-03-10T19:35:30.000+0100 - * Channel testbinding::test:location#latitude 50.50505065917969 - * Channel testbinding::test:location#longitude 10.1010103225708 - * Channel testbinding::test:location#heading 141.0 ° - **/ @Test public void testF48() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F48/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES + CHECK_CONTROL_ACTIVE_CALLS, Optional.empty())); + assertTrue(testVehicle(content, + STATUS_CONV + DOORS + RANGE_CONV + SERVICE_AVAILABLE + CHECK_AVAILABLE + POSITION, Optional.empty())); } @Test @@ -329,7 +284,8 @@ public void testF48Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F48/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES + CHECK_CONTROL_ACTIVE_CALLS, Optional.empty())); + assertTrue(testVehicle(content, + STATUS_CONV + DOORS + RANGE_CONV + SERVICE_AVAILABLE + CHECK_AVAILABLE + POSITION, Optional.empty())); } @Test @@ -337,7 +293,9 @@ public void testG31NBTEvo() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/G31_NBTevo/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES, Optional.empty())); + // assertTrue(testVehicle(content, 27, Optional.empty())); + assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + SERVICE_AVAILABLE + CHECK_EMPTY + POSITION, + Optional.empty())); } @Test @@ -345,7 +303,8 @@ public void testG31NBTEvoMiles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/G31_NBTevo/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES, Optional.empty())); + assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + SERVICE_AVAILABLE + CHECK_EMPTY + POSITION, + Optional.empty())); } @Test @@ -353,7 +312,9 @@ public void testI01NoRex() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/I01_NOREX/status.json"); - assertTrue(testVehicle(content, EV_CALL_TIMES + LIST_UPDATES, Optional.empty())); + assertTrue(testVehicle(content, + STATUS_ELECTRIC + DOORS + RANGE_ELECTRIC + SERVICE_AVAILABLE + CHECK_EMPTY + POSITION, + Optional.empty())); } @Test @@ -361,7 +322,9 @@ public void testI01NoRexMiles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/I01_NOREX/status.json"); - assertTrue(testVehicle(content, EV_CALL_TIMES + LIST_UPDATES, Optional.empty())); + assertTrue(testVehicle(content, + STATUS_ELECTRIC + DOORS + RANGE_ELECTRIC + SERVICE_AVAILABLE + CHECK_EMPTY + POSITION, + Optional.empty())); } @Test @@ -369,7 +332,8 @@ public void testI01Rex() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC_REX.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/I01_REX/status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES + LIST_UPDATES, Optional.empty())); + assertTrue(testVehicle(content, + STATUS_ELECTRIC + DOORS + RANGE_HYBRID + SERVICE_AVAILABLE + CHECK_EMPTY + POSITION, Optional.empty())); } @Test @@ -377,7 +341,8 @@ public void testI01RexMiles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC_REX.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/I01_REX/status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES + LIST_UPDATES, Optional.empty())); + assertTrue(testVehicle(content, + STATUS_ELECTRIC + DOORS + RANGE_HYBRID + SERVICE_AVAILABLE + CHECK_EMPTY + POSITION, Optional.empty())); } @Test @@ -387,61 +352,29 @@ public void test318iF31() { String content = FileReader.readFileInString("src/test/resources/responses/F31/status-318i.json"); Map m = new HashMap(); m.put(ConnectedDriveConstants.WINDOWS, StringType.valueOf(Constants.INTERMEDIATE)); - assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES, Optional.of(m))); + assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + SERVICE_AVAILABLE + CHECK_EMPTY + POSITION, + Optional.empty())); + } + + @Test + public void test318iF31Miles() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(VehicleType.CONVENTIONAL.toString(), true); + String content = FileReader.readFileInString("src/test/resources/responses/F31/status-318i.json"); + Map m = new HashMap(); + m.put(ConnectedDriveConstants.WINDOWS, StringType.valueOf(Constants.INTERMEDIATE)); + assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + SERVICE_AVAILABLE + CHECK_EMPTY + POSITION, + Optional.empty())); } - /** - * testI01RexCompat - * [main] INFO org.eclipse.jetty.util.log - Logging initialized @1797ms - * Channel testbinding::test:status#lock Secured - * Channel testbinding::test:status#doors CLOSED - * Channel testbinding::test:doors#driver-front CLOSED - * Channel testbinding::test:doors#driver-rear CLOSED - * Channel testbinding::test:doors#passenger-front CLOSED - * Channel testbinding::test:doors#passenger-rear CLOSED - * Channel testbinding::test:doors#trunk CLOSED - * Channel testbinding::test:doors#hood CLOSED - * Channel testbinding::test:status#windows CLOSED - * Channel testbinding::test:doors#window-driver-front CLOSED - * Channel testbinding::test:doors#window-driver-rear CLOSED - * Channel testbinding::test:doors#window-passenger-front CLOSED - * Channel testbinding::test:doors#window-passenger-rear CLOSED - * Channel testbinding::test:doors#window-rear UNKOWN - * Channel testbinding::test:doors#sunroof CLOSED - * Channel testbinding::test:status#service-date 2021-11-01T13:00:00.000+0100 - * Channel testbinding::test:status#service-mileage -1.0 km - * Channel testbinding::test:service#size 4 - * Channel testbinding::test:service#date 2021-11-01T13:00:00.000+0100 - * Channel testbinding::test:service#mileage 0.0 km - * Channel testbinding::test:service#name Bremsflüssigkeit - * Channel testbinding::test:service#index 0 - * Channel testbinding::test:status#check-control Active - * Channel testbinding::test:check#size 1 - * Channel testbinding::test:check#name Laden nicht möglich - * Channel testbinding::test:check#mileage 18312.0 km - * Channel testbinding::test:check#index 0 - * Channel testbinding::test:range#mileage 18313.0 km - * Channel testbinding::test:range#electric 100.0 km - * Channel testbinding::test:range#radius-electric 80.0 km - * Channel testbinding::test:range#fuel 65.0 km - * Channel testbinding::test:range#radius-fuel 52.0 km - * Channel testbinding::test:range#hybrid 165.0 km - * Channel testbinding::test:range#radius-hybrid 132.0 km - * Channel testbinding::test:range#soc 51.0 % - * Channel testbinding::test:range#remaining-fuel 4.0 l - * Channel testbinding::test:status#last-update 2020-09-27T15:18:00.000+0200 - * Channel testbinding::test:status#charge Error - * Channel testbinding::test:location#latitude 50.5560188293457 - * Channel testbinding::test:location#longitude 8.495611190795898 - * Channel testbinding::test:location#heading 39.0 ° - */ @Test public void testI01RexCompat() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.ELECTRIC_REX.toString(), false); String content = FileReader.readFileInString("src/test/resources/api/vehicle/vehicle-ccm.json"); VehicleAttributesContainer vac = Converter.getGson().fromJson(content, VehicleAttributesContainer.class); - assertTrue(testVehicle(vac.transform(), HYBRID_CALL_TIMES + LIST_UPDATES + CHECK_CONTROL_ACTIVE_CALLS, + assertTrue(testVehicle(vac.transform(), + STATUS_ELECTRIC + DOORS + RANGE_HYBRID + SERVICE_AVAILABLE + CHECK_AVAILABLE + POSITION, Optional.empty())); } @@ -451,58 +384,19 @@ public void testI01RexMilesCompat() { setup(VehicleType.ELECTRIC_REX.toString(), true); String content = FileReader.readFileInString("src/test/resources/api/vehicle/vehicle-ccm.json"); VehicleAttributesContainer vac = Converter.getGson().fromJson(content, VehicleAttributesContainer.class); - assertTrue(testVehicle(vac.transform(), HYBRID_CALL_TIMES + LIST_UPDATES + CHECK_CONTROL_ACTIVE_CALLS, + assertTrue(testVehicle(vac.transform(), + STATUS_ELECTRIC + DOORS + RANGE_HYBRID + SERVICE_AVAILABLE + CHECK_AVAILABLE + POSITION, Optional.empty())); } - /** - * testF11Compat - * [main] INFO org.eclipse.jetty.util.log - Logging initialized @1687ms - * Channel testbinding::test:status#lock Unkown - * Channel testbinding::test:status#doors UNKOWN - * Channel testbinding::test:doors#driver-front UNKOWN - * Channel testbinding::test:doors#driver-rear UNKOWN - * Channel testbinding::test:doors#passenger-front UNKOWN - * Channel testbinding::test:doors#passenger-rear UNKOWN - * Channel testbinding::test:doors#trunk UNKOWN - * Channel testbinding::test:doors#hood UNKOWN - * Channel testbinding::test:status#windows UNKOWN - * Channel testbinding::test:doors#window-driver-front UNKOWN - * Channel testbinding::test:doors#window-driver-rear UNKOWN - * Channel testbinding::test:doors#window-passenger-front UNKOWN - * Channel testbinding::test:doors#window-passenger-rear UNKOWN - * Channel testbinding::test:doors#window-rear UNKOWN - * Channel testbinding::test:doors#sunroof UNKOWN - * Channel testbinding::test:status#service-date 2021-08-01T14:00:00.000+0200 - * Channel testbinding::test:status#service-mileage 2000.0 km - * Channel testbinding::test:service#size 3 - * Channel testbinding::test:service#date 2021-08-01T14:00:00.000+0200 - * Channel testbinding::test:service#mileage 2000.0 km - * Channel testbinding::test:service#name Motorolie - * Channel testbinding::test:service#index 0 - * Channel testbinding::test:status#check-control Not Active - * Channel testbinding::test:check#size 0 - * Channel testbinding::test:range#mileage 113930.0 km - * Channel testbinding::test:range#electric 0.0 km - * Channel testbinding::test:range#radius-electric 0.0 km - * Channel testbinding::test:range#fuel 0.0 km - * Channel testbinding::test:range#radius-fuel 0.0 km - * Channel testbinding::test:range#hybrid 0.0 km - * Channel testbinding::test:range#radius-hybrid 0.0 km - * Channel testbinding::test:range#soc 0.0 % - * Channel testbinding::test:range#remaining-fuel 34.0 l - * Channel testbinding::test:status#last-update 1900-01-01T01:00:00.000+0100 - * Channel testbinding::test:location#latitude 0.0 - * Channel testbinding::test:location#longitude 0.0 - * Channel testbinding::test:location#heading 0.0 ° - */ @Test public void testF11Compat() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F11/vehicle-status.json"); VehicleAttributesContainer vac = Converter.getGson().fromJson(content, VehicleAttributesContainer.class); - assertTrue(testVehicle(vac.transform(), CONV_CALL_TIMES + LIST_UPDATES, Optional.empty())); + assertTrue(testVehicle(vac.transform(), + STATUS_CONV + DOORS + RANGE_CONV + SERVICE_AVAILABLE + CHECK_EMPTY + POSITION, Optional.empty())); } @Test @@ -511,6 +405,7 @@ public void testF11MilesCompat() { setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F11/vehicle-status.json"); VehicleAttributesContainer vac = Converter.getGson().fromJson(content, VehicleAttributesContainer.class); - assertTrue(testVehicle(vac.transform(), CONV_CALL_TIMES + LIST_UPDATES, Optional.empty())); + assertTrue(testVehicle(vac.transform(), + STATUS_CONV + DOORS + RANGE_CONV + SERVICE_AVAILABLE + CHECK_EMPTY + POSITION, Optional.empty())); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java.bak b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java.bak deleted file mode 100644 index c3be76495987a..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java.bak +++ /dev/null @@ -1,390 +0,0 @@ -/** - * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.jetty.client.HttpClient; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; -import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants; -import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; -import org.openhab.binding.bmwconnecteddrive.internal.dto.StatusWrapper; -import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; -import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; -import org.openhab.core.library.types.StringType; -import org.openhab.core.thing.ChannelUID; -import org.openhab.core.thing.Thing; -import org.openhab.core.thing.ThingUID; -import org.openhab.core.thing.binding.ThingHandlerCallback; -import org.openhab.core.types.State; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * The {@link VehicleTests} is responsible for handling commands, which are - * sent to one of the channels. - * - * @author Bernd Weymann - Initial contribution - */ -@NonNullByDefault -public class VehicleTests { - private final Logger logger = LoggerFactory.getLogger(VehicleHandler.class); - - private static final int HYBRID_CALL_TIMES = 31; - private static final int CONV_CALL_TIMES = 25; - private static final int EV_CALL_TIMES = 26; - - private static final int LIST_UPDATES = 7; - private static final int CHECK_CONTROL_ACTIVE_CALLS = 3; - - @Nullable - ArgumentCaptor channelCaptor; - @Nullable - ArgumentCaptor stateCaptor; - @Nullable - ThingHandlerCallback tc; - @Nullable - VehicleHandler cch; - @Nullable - List allChannels; - @Nullable - List allStates; - String driveTrain = Constants.EMPTY; - boolean imperial; - - /** - * Prepare environment for Vehicle Status Updates - */ - public void setup(String type, boolean imperial) { - driveTrain = type; - this.imperial = imperial; - Thing thing = mock(Thing.class); - when(thing.getUID()).thenReturn(new ThingUID("testbinding", "test")); - HttpClient hc = mock(HttpClient.class); - cch = new VehicleHandler(thing, hc, type, imperial); - tc = mock(ThingHandlerCallback.class); - cch.setCallback(tc); - channelCaptor = ArgumentCaptor.forClass(ChannelUID.class); - stateCaptor = ArgumentCaptor.forClass(State.class); - } - - private boolean testVehicle(String statusContent, int callbacksExpected, - Optional> concreteChecks) { - assertNotNull(statusContent); - cch.vehicleStatusCallback.onResponse(Optional.of(statusContent)); - verify(tc, times(callbacksExpected)).stateUpdated(channelCaptor.capture(), stateCaptor.capture()); - allChannels = channelCaptor.getAllValues(); - allStates = stateCaptor.getAllValues(); - - assertNotNull(driveTrain); - StatusWrapper checker = new StatusWrapper(driveTrain, imperial, statusContent); - trace(); - if (concreteChecks.isPresent()) { - return checker.append(concreteChecks.get()).checkResults(allChannels, allStates); - } else { - return checker.checkResults(allChannels, allStates); - } - } - - private void trace() { - for (int i = 0; i < allChannels.size(); i++) { - logger.info("Channel {} {}", allChannels.get(i), allStates.get(i)); - } - } - - /** - * Sequence for BEV_REX - * Channel testbinding::test:status#lock Secured - * Channel testbinding::test:status#doors Closed - * Channel testbinding::test:status#windows Closed - * Channel testbinding::test:status#check-control Ok - * Channel testbinding::test:status#service Nov 2021 - Brake Fluid - * Channel testbinding::test:status#charging-status Invalid - * Channel testbinding::test:range#mileage 17273.0 km - * Channel testbinding::test:range#remaining-range-electric 148.0 km - * Channel testbinding::test:range#remaining-range-fuel 70.0 km - * Channel testbinding::test:range#remaining-range-hybrid 218.0 km - * Channel testbinding::test:location#range-radius 218000.0 - * Channel testbinding::test:range#remaining-soc 71.0 % - * Channel testbinding::test:range#remaining-fuel 4.0 l - * Channel testbinding::test:range#last-update 24.08.2020 17:55 - * Channel testbinding::test:location#latitude 50.55604934692383 - * Channel testbinding::test:location#longitude 8.4956693649292 - * Channel testbinding::test:location#latlong 50.55605,8.495669 - * Channel testbinding::test:location#heading 219.0 ° - */ - @Test - public void testMyi3Rex() { - logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); - setup(VehicleType.ELECTRIC_REX.toString(), false); - String content = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES + LIST_UPDATES, Optional.empty())); - } - - /** - * Channel testbinding::test:status#lock Secured - * Channel testbinding::test:status#doors Closed - * Channel testbinding::test:status#windows Closed - * Channel testbinding::test:status#check-control Ok - * Channel testbinding::test:status#service Nov 2021 - Brake Fluid - * Channel testbinding::test:status#charging-status Invalid - * Channel testbinding::test:range#mileage 17273.0 mi - * Channel testbinding::test:range#remaining-range-electric 91.0 mi - * Channel testbinding::test:range#remaining-range-fuel 43.0 mi - * Channel testbinding::test:range#remaining-range-hybrid 134.0 mi - * Channel testbinding::test:location#range-radius 707520.0 - * Channel testbinding::test:range#remaining-soc 71.0 % - * Channel testbinding::test:range#remaining-fuel 4.0 l - * Channel testbinding::test:range#last-update 24.08.2020 17:55 - * Channel testbinding::test:location#latitude 50.55604934692383 - * Channel testbinding::test:location#longitude 8.4956693649292 - * Channel testbinding::test:location#latlong 50.55605,8.495669 - * Channel testbinding::test:location#heading 219.0 ° - */ - @Test - public void testMyi3RexMiles() { - logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); - setup(VehicleType.ELECTRIC_REX.toString(), true); - String content = FileReader.readFileInString("src/test/resources/webapi/vehicle-status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES + LIST_UPDATES, Optional.empty())); - } - - /** - * Channel testbinding::test:status#lock Unlocked - * Channel testbinding::test:status#doors Closed - * Channel testbinding::test:status#windows Closed - * Channel testbinding::test:status#check-control Ok - * Channel testbinding::test:status#service Jun 2018 or in 12000 km - Oil - * Channel testbinding::test:range#mileage 1629.0 km - * Channel testbinding::test:range#remaining-range-fuel 249.0 km - * Channel testbinding::test:location#range-radius 249000.0 - * Channel testbinding::test:range#remaining-fuel 30.0 l - * Channel testbinding::test:range#last-update 09.03.2018 04:21 - * Channel testbinding::test:location#latitude 123.12300109863281 - * Channel testbinding::test:location#longitude -123.12300109863281 - * Channel testbinding::test:location#latlong 123.123,-123.123 - * Channel testbinding::test:location#heading 11.0 ° - */ - @Test - public void testF15() { - logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); - setup(VehicleType.CONVENTIONAL.toString(), false); - String content = FileReader.readFileInString("src/test/resources/responses/F15/status.json"); - // Check earliest Service by hard - Map m = new HashMap(); - // Don>'t test on concrete timestamp - it's is different on each machine - // Check for cbsType which is "Oil" instead - // m.put(ConnectedDriveConstants.SERVICE_DATE, DateTimeType.valueOf("2018-06-01T14:00:00.000+0200")); - m.put(ConnectedDriveConstants.NAME, StringType.valueOf("Oil")); - assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES, Optional.of(m))); - } - - @Test - public void testF15Miles() { - logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); - setup(VehicleType.CONVENTIONAL.toString(), true); - String content = FileReader.readFileInString("src/test/resources/responses/F15/status.json"); - // Check earliest Service by hard - Map m = new HashMap(); - // Don>'t test on concrete timestamp - it's idfferent on each machine - // Check for cbsType which is "Oil" instead - // m.put(ConnectedDriveConstants.SERVICE_DATE, DateTimeType.valueOf("2018-06-01T14:00:00.000+0200")); - m.put(ConnectedDriveConstants.NAME, StringType.valueOf("Oil")); - assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES, Optional.of(m))); - } - - /** - * Channel testbinding::test:status#lock Unkown - * Channel testbinding::test:status#doors Unkown - * Channel testbinding::test:status#windows Unkown - * Channel testbinding::test:status#check-control Unkown - * Channel testbinding::test:status#service Unkown - * Channel testbinding::test:range#mileage 0.0 km - * Channel testbinding::test:range#remaining-range-fuel 0.0 km - * Channel testbinding::test:location#range-radius 0.0 - * Channel testbinding::test:range#remaining-fuel 0.0 l - * Channel testbinding::test:range#last-update Unkown - * Channel testbinding::test:location#latitude 12.345600128173828 - * Channel testbinding::test:location#longitude 34.56779861450195 - * Channel testbinding::test:location#latlong 12.3456,34.5678 - * Channel testbinding::test:location#heading 0.0 ° @Test - */ - @Test - public void testF31() { - logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); - setup(VehicleType.CONVENTIONAL.toString(), false); - String content = FileReader.readFileInString("src/test/resources/responses/F31/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); - } - - @Test - public void testF31Miles() { - logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); - setup(VehicleType.CONVENTIONAL.toString(), true); - String content = FileReader.readFileInString("src/test/resources/responses/F31/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); - } - - @Test - public void testF35() { - logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); - setup(VehicleType.CONVENTIONAL.toString(), false); - String content = FileReader.readFileInString("src/test/resources/responses/F35/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); - } - - @Test - public void testF35Miles() { - logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); - setup(VehicleType.CONVENTIONAL.toString(), true); - String content = FileReader.readFileInString("src/test/resources/responses/F35/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); - } - - @Test - public void testF45() { - logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); - setup(VehicleType.CONVENTIONAL.toString(), false); - String content = FileReader.readFileInString("src/test/resources/responses/F45/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); - } - - @Test - public void testF45Miles() { - logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); - setup(VehicleType.CONVENTIONAL.toString(), true); - String content = FileReader.readFileInString("src/test/resources/responses/F45/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES, Optional.empty())); - } - - /** - * testF48 - * Channel testbinding::test:status#lock Secured - * Channel testbinding::test:status#doors CLOSED - * Channel testbinding::test:doors#driver-front CLOSED - * Channel testbinding::test:doors#driver-rear CLOSED - * Channel testbinding::test:doors#passenger-front CLOSED - * Channel testbinding::test:doors#passenger-rear CLOSED - * Channel testbinding::test:doors#trunk CLOSED - * Channel testbinding::test:doors#hood CLOSED - * Channel testbinding::test:status#windows CLOSED - * Channel testbinding::test:doors#window-driver-front CLOSED - * Channel testbinding::test:doors#window-driver-rear CLOSED - * Channel testbinding::test:doors#window-passenger-front CLOSED - * Channel testbinding::test:doors#window-passenger-rear CLOSED - * Channel testbinding::test:doors#window-rear INVALID - * Channel testbinding::test:doors#sunroof UNKOWN - * Channel testbinding::test:status#service-date 2019-07-01T14:00:00.000+0200 - * Channel testbinding::test:status#service-mileage -1.0 km - * Channel testbinding::test:service#size 3 - * Channel testbinding::test:service#date 2019-07-01T14:00:00.000+0200 - * Channel testbinding::test:service#mileage 9000.0 km - * Channel testbinding::test:service#name Oil - * Channel testbinding::test:service#index 0 - * Channel testbinding::test:status#check-control Active - * Channel testbinding::test:check#size 1 - * Channel testbinding::test:check#name Tyre pressure notification - * Channel testbinding::test:check#mileage 41544.0 km - * Channel testbinding::test:check#index 0 - * Channel testbinding::test:range#mileage 21529.0 km - * Channel testbinding::test:range#fuel 590.0 km - * Channel testbinding::test:range#radius-fuel 472.0 km - * Channel testbinding::test:range#remaining-fuel 39.0 l - * Channel testbinding::test:status#last-update 2018-03-10T19:35:30.000+0100 - * Channel testbinding::test:location#latitude 50.50505065917969 - * Channel testbinding::test:location#longitude 10.1010103225708 - * Channel testbinding::test:location#heading 141.0 ° - **/ - @Test - public void testF48() { - logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); - setup(VehicleType.CONVENTIONAL.toString(), false); - String content = FileReader.readFileInString("src/test/resources/responses/F48/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES + CHECK_CONTROL_ACTIVE_CALLS, Optional.empty())); - } - - @Test - public void testF48Miles() { - logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); - setup(VehicleType.CONVENTIONAL.toString(), true); - String content = FileReader.readFileInString("src/test/resources/responses/F48/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES + CHECK_CONTROL_ACTIVE_CALLS, Optional.empty())); - } - - @Test - public void testG31NBTEvo() { - logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); - setup(VehicleType.CONVENTIONAL.toString(), false); - String content = FileReader.readFileInString("src/test/resources/responses/G31_NBTevo/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES, Optional.empty())); - } - - @Test - public void testG31NBTEvoMiles() { - logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); - setup(VehicleType.CONVENTIONAL.toString(), true); - String content = FileReader.readFileInString("src/test/resources/responses/G31_NBTevo/status.json"); - assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES, Optional.empty())); - } - - @Test - public void testI01NoRex() { - logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); - setup(VehicleType.ELECTRIC.toString(), false); - String content = FileReader.readFileInString("src/test/resources/responses/I01_NOREX/status.json"); - assertTrue(testVehicle(content, EV_CALL_TIMES + LIST_UPDATES, Optional.empty())); - } - - @Test - public void testI01NoRexMiles() { - logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); - setup(VehicleType.ELECTRIC.toString(), true); - String content = FileReader.readFileInString("src/test/resources/responses/I01_NOREX/status.json"); - assertTrue(testVehicle(content, EV_CALL_TIMES + LIST_UPDATES, Optional.empty())); - } - - @Test - public void testI01Rex() { - logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); - setup(VehicleType.ELECTRIC_REX.toString(), false); - String content = FileReader.readFileInString("src/test/resources/responses/I01_REX/status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES + LIST_UPDATES, Optional.empty())); - } - - @Test - public void testI01RexMiles() { - logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); - setup(VehicleType.ELECTRIC_REX.toString(), true); - String content = FileReader.readFileInString("src/test/resources/responses/I01_REX/status.json"); - assertTrue(testVehicle(content, HYBRID_CALL_TIMES + LIST_UPDATES, Optional.empty())); - } - - @Test - public void test318iF31() { - logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); - setup(VehicleType.CONVENTIONAL.toString(), false); - String content = FileReader.readFileInString("src/test/resources/responses/F31/status-318i.json"); - Map m = new HashMap(); - m.put(ConnectedDriveConstants.WINDOWS, StringType.valueOf(Constants.INTERMEDIATE)); - assertTrue(testVehicle(content, CONV_CALL_TIMES + LIST_UPDATES, Optional.of(m))); - } -} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java index 2444721e615bb..da02ac7682b0f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java @@ -73,8 +73,8 @@ public void testTimeUTCToLocaleTime() { @Test public void testDistance() { - double lat = 50.5560; - double lon = 8.4956; + double lat = 45.678; + double lon = 8.765; double distance = 0.005; double dist = Converter.measureDistance(lat, lon, lat + distance, lon + distance); assertTrue(dist < 1, "Distance below 1 km"); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/navigation.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/navigation.json index 54cbb6c82185c..995c6a5b37f9d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/navigation.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/navigation.json @@ -1,6 +1,6 @@ { - "latitude": 50.556164, - "longitude": 8.495482, + "latitude": 56.789, + "longitude": 8.765, "isoCountryCode": "DEU", "auxPowerRegular": 1.4, "auxPowerEcoPro": 1.2, diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/vehicle-ccm.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/vehicle-ccm.json index 2d5f51c0b725a..42e438f2e724c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/vehicle-ccm.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/vehicle-ccm.json @@ -38,10 +38,10 @@ "chargingSystemStatus": "CHARGINGERROR", "fuelPercent": "47", "unitOfCombustionConsumption": "l/100km", - "gps_lat": "50.55602", + "gps_lat": "56.789", "window_driver_front": "CLOSED", "Segment_LastTrip_ratio_electric_driven_distance": "100", - "gps_lng": "8.495611", + "gps_lng": "8.765", "condition_based_services": "00003,OK,2021-11,;00017,OK,2021-11,;00001,OK,2021-11,;00032,OK,2021-11,", "window_passenger_front": "CLOSED", "targetSoc": "100.0", diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/vehicle.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/vehicle.json index 7f160ad90e45b..129b58d1b03f2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/vehicle.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/vehicle.json @@ -38,10 +38,10 @@ "chargingSystemStatus": "NOCHARGING", "fuelPercent": "47", "unitOfCombustionConsumption": "l/100km", - "gps_lat": "50.556164", + "gps_lat": "56.789", "window_driver_front": "CLOSED", "Segment_LastTrip_ratio_electric_driven_distance": "100", - "gps_lng": "8.495482", + "gps_lng": "8.765", "condition_based_services": "00003,OK,2021-11,;00017,OK,2021-11,;00001,OK,2021-11,;00032,OK,2021-11,", "window_passenger_front": "CLOSED", "window_passenger_rear": "CLOSED", diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/webapi-status.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/webapi-status.json index 7846fdcb27c22..bfb14fe420763 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/webapi-status.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/api/vehicle/webapi-status.json @@ -33,8 +33,8 @@ "lastChargingEndReason": "END_REQUESTED_BY_DRIVER", "lastChargingEndResult": "SUCCESS", "position": { - "lat": 50.55603, - "lon": 8.4956, + "lat": 56.789, + "lon": 8.765, "heading": 41, "status": "OK" }, diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status-charging.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status-charging.json index a50cf866c36e0..1dd32fa4447ed 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status-charging.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status-charging.json @@ -34,8 +34,8 @@ "lastChargingEndReason": "UNKNOWN", "lastChargingEndResult": "UNKNOWN", "position": { - "lat": 50.55603, - "lon": 8.495625, + "lat": 56.789, + "lon": 8.765, "heading": 41, "status": "OK" }, diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status.json index f3dac76ea5b21..ec4235a7c4881 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status.json @@ -33,8 +33,8 @@ "lastChargingEndReason": "CHARGING_GOAL_REACHED", "lastChargingEndResult": "SUCCESS", "position": { - "lat": 50.55605, - "lon": 8.495669, + "lat": 56.789, + "lon": 8.765, "heading": 219, "status": "OK" }, From e29641239f9e21daf4da2fcc3140ceca15a2b4d8 Mon Sep 17 00:00:00 2001 From: Bernd Date: Mon, 28 Sep 2020 11:56:12 +0200 Subject: [PATCH 055/176] add backward compatibility unit tests Signed-off-by: Bernd --- .../internal/dto/VehicleStatusTest.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleStatusTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleStatusTest.java index 96380276f671c..a67589a294ff7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleStatusTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleStatusTest.java @@ -24,7 +24,6 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; import org.openhab.binding.bmwconnecteddrive.internal.util.FileReader; -import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import com.google.gson.Gson; @@ -66,13 +65,11 @@ public void testServices() { public void testCompatibility() { String resource = FileReader.readFileInString("src/test/resources/api/vehicle/vehicle-ccm.json"); VehicleAttributesContainer vac = GSON.fromJson(resource, VehicleAttributesContainer.class); - // String s = vac.transform(); - // System.out.println(s); assertEquals("Laden nicht möglich", vac.vehicleMessages.ccmMessages.get(0).text, "CCM"); - // Time - VehicleStatusContainer vsc = GSON.fromJson(vac.transform(), VehicleStatusContainer.class); - assertEquals("27.09.2020 13:18", vsc.vehicleStatus.getUpdateTime(), "UTC DateTime"); - String ldt = Converter.getLocalDateTime(vsc.vehicleStatus.getUpdateTime()); - assertEquals("2020-09-27T15:18:00", ldt.toString(), "Local DateTime"); + // Time Test to be removed - different Machines = different Time Zones + // VehicleStatusContainer vsc = GSON.fromJson(vac.transform(), VehicleStatusContainer.class); + // assertEquals("27.09.2020 13:18", vsc.vehicleStatus.getUpdateTime(), "UTC DateTime"); + // String ldt = Converter.getLocalDateTime(vsc.vehicleStatus.getUpdateTime()); + // assertEquals("2020-09-27T15:18:00", ldt.toString(), "Local DateTime"); } } From adb5a0a8873afc2b2d2accb328f7264b86546a5e Mon Sep 17 00:00:00 2001 From: Bernd Date: Mon, 28 Sep 2020 21:36:35 +0200 Subject: [PATCH 056/176] bugfix status channel types Signed-off-by: Bernd --- .../OH-INF/thing/vehicle-status-channel-types.xml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/vehicle-status-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/vehicle-status-channel-types.xml index c49568d9505c4..129fd3c13eb7c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/vehicle-status-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/vehicle-status-channel-types.xml @@ -15,20 +15,12 @@ String - - DateTime - - DateTime - - String - - - String + Number:Length From 2e4dc4206e6d9b503f44dd23ea58b475d0187621 Mon Sep 17 00:00:00 2001 From: Bernd Date: Mon, 28 Sep 2020 23:01:29 +0200 Subject: [PATCH 057/176] enable compatibility mode Signed-off-by: Bernd --- .../bmwconnecteddrive/internal/handler/VehicleHandler.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 7ded13a1e8b03..3fae27bfc8a89 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -615,6 +615,11 @@ public void onResponse(Optional content) { @Override public void onError(NetworkError error) { logger.debug("{}", error.toString()); + if (error.status == 404) { + compatibilityMode = true; + logger.debug("VehicleStatus not found - switch to old API"); + proxy.get().requestOldVehcileStatus(configuration.get(), oldVehicleStatusCallback); + } vehicleStatusCache = Optional.of(Converter.getGson().toJson(error)); setThingStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, error.reason); } From 8e1331863718bdfdcc04bcca7d8673371ae13ad0 Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 29 Sep 2020 17:02:32 +0200 Subject: [PATCH 058/176] clear list content after receiving empty list Signed-off-by: Bernd --- .../handler/VehicleChannelHandler.java | 41 +++++++-- .../internal/dto/StatusWrapper.java | 44 ++++++++-- .../internal/handler/VehicleTests.java | 27 +++--- .../webapi/vehicle-status-ccm-tyre.json | 87 +++++++++++++++++++ 4 files changed, 173 insertions(+), 26 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status-ccm-tyre.json diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index f8d39a57a7ff0..d6b6312c6adf9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -344,8 +344,19 @@ private void updateCheckControls() { updateState(checkControlMileage, QuantityType.valueOf(Converter.round(entry.ccmMileage), MetricPrefix.KILO(SIUnits.METRE))); } - // last update index - this is a sync point and you're sure that all data is valid noew + // last update index - this is a sync point and you're sure that all data is valid now updateState(checkControlIndex, new DecimalType(checkControlListIndex)); + } else { + // list is empty - set all fields to INVALID. If this isn't done the old values remain + updateState(checkControlName, StringType.valueOf(Constants.INVALID)); + if (imperial) { + updateState(checkControlMileage, QuantityType.valueOf(Converter.round(-1), ImperialUnits.MILE)); + } else { + updateState(checkControlMileage, + QuantityType.valueOf(Converter.round(-1), MetricPrefix.KILO(SIUnits.METRE))); + } + // last update index - this is a sync point and you're sure that all data is valid now + updateState(checkControlIndex, new DecimalType(-1)); } } @@ -367,6 +378,7 @@ private void updateService() { serviceListIndex = 0; } CBSMessage entry = serviceList.get(serviceListIndex); + updateState(serviceName, StringType.valueOf(Converter.toTitleCase(entry.getType()))); updateState(serviceDate, DateTimeType.valueOf(Converter.getLocalDateTime(entry.getDueDate()))); if (imperial) { updateState(serviceMileage, @@ -375,9 +387,19 @@ private void updateService() { updateState(serviceMileage, QuantityType.valueOf(Converter.round(entry.cbsRemainingMileage), MetricPrefix.KILO(SIUnits.METRE))); } - updateState(serviceName, StringType.valueOf(Converter.toTitleCase(entry.getType()))); - // last update index - this is a sync point and you're sure that all data is valid noew + // last update index - this is a sync point and you're sure that all data is valid now updateState(serviceIndex, new DecimalType(serviceListIndex)); + } else { + // list is empty - set all fields to INVALID. If this isn't done the old values remain + updateState(serviceName, StringType.valueOf(Constants.INVALID)); + updateState(serviceDate, DateTimeType.valueOf(Converter.getLocalDateTime(Constants.NULL_DATE))); + if (imperial) { + updateState(serviceMileage, QuantityType.valueOf(-1, ImperialUnits.MILE)); + } else { + updateState(serviceMileage, QuantityType.valueOf(-1, MetricPrefix.KILO(SIUnits.METRE))); + } + // last update index - this is a sync point and you're sure that all data is valid now + updateState(serviceIndex, new DecimalType(-1)); } } @@ -405,8 +427,15 @@ private void updateDestination() { updateState(destinationName, StringType.valueOf(entry.getAddress())); updateState(destinationLat, new DecimalType(entry.lat)); updateState(destinationLon, new DecimalType(entry.lon)); - // last update index - this is a sync point and you're sure that all data is valid noew + // last update index - this is a sync point and you're sure that all data is valid now updateState(destinationIndex, new DecimalType(destinationListIndex)); + } else { + // list is empty - set all fields to INVALID. If this isn't done the old values remain + updateState(destinationName, StringType.valueOf(Constants.INVALID)); + updateState(destinationLat, new DecimalType(-1)); + updateState(destinationLon, new DecimalType(-1)); + // last update index - this is a sync point and you're sure that all data is valid noew + updateState(destinationIndex, new DecimalType(-1)); } } @@ -498,9 +527,7 @@ protected void updateVehicleStatus(VehicleStatus vStatus) { // Service Updates String nextServiceDate = vStatus.getNextServiceDate(); - if (!nextServiceDate.equals(Constants.NULL_DATE)) { - updateState(serviceNextDate, DateTimeType.valueOf(Converter.getLocalDateTime(nextServiceDate))); - } + updateState(serviceNextDate, DateTimeType.valueOf(Converter.getLocalDateTime(nextServiceDate))); double nextServiceMileage = vStatus.getNextServiceMileage(); if (imperial) { updateState(serviceNextMileage, diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index 43ff48c76f632..5d42269f417f3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -125,10 +125,19 @@ private void checkResult(ChannelUID channelUID, State state) { assertEquals(qt.intValue(), vStatus.mileage, "Mileage"); break; case CHANNEL_GROUP_SERVICE: - assertEquals(qt.intValue(), vStatus.cbsData.get(0).cbsRemainingMileage, "Mileage"); + if (vStatus.cbsData.isEmpty()) { + assertEquals(qt.intValue(), -1, "Service Mileage"); + } else { + assertEquals(qt.intValue(), vStatus.cbsData.get(0).cbsRemainingMileage, "Service Mileage"); + } break; case CHANNEL_GROUP_CHECK_CONTROL: - assertEquals(qt.intValue(), vStatus.checkControlMessages.get(0).ccmMileage, "Mileage"); + if (vStatus.checkControlMessages.isEmpty()) { + assertEquals(qt.intValue(), -1, "CheckControl Mileage"); + } else { + assertEquals(qt.intValue(), vStatus.checkControlMessages.get(0).ccmMileage, + "CheckControl Mileage"); + } break; default: assertFalse(true, "Channel " + channelUID + " " + state + " not found"); @@ -393,10 +402,18 @@ private void checkResult(ChannelUID channelUID, State state) { dt = (DecimalType) state; switch (gUid) { case CHANNEL_GROUP_SERVICE: - assertEquals(0, dt.intValue(), "Index of Services"); + if (vStatus.cbsData.isEmpty()) { + assertEquals(-1, dt.intValue(), "Index of Services"); + } else { + assertEquals(0, dt.intValue(), "Index of Services"); + } break; case CHANNEL_GROUP_CHECK_CONTROL: - assertEquals(0, dt.intValue(), "Index of CheckControls"); + if (vStatus.checkControlMessages.isEmpty()) { + assertEquals(-1, dt.intValue(), "Index of CheckControls"); + } else { + assertEquals(0, dt.intValue(), "Index of CheckControls"); + } break; default: assertFalse(true, "Channel " + channelUID + " " + state + " not found"); @@ -448,12 +465,18 @@ private void checkResult(ChannelUID channelUID, State state) { st = (StringType) state; switch (gUid) { case CHANNEL_GROUP_SERVICE: - wanted = StringType.valueOf(Converter.toTitleCase(vStatus.cbsData.get(0).getType())); - assertEquals(wanted.toString(), st.toString(), "Service"); + wanted = StringType.valueOf(Constants.INVALID); + if (!vStatus.cbsData.isEmpty()) { + wanted = StringType.valueOf(Converter.toTitleCase(vStatus.cbsData.get(0).getType())); + } + assertEquals(wanted.toString(), st.toString(), "Service Name"); break; case CHANNEL_GROUP_CHECK_CONTROL: - wanted = StringType.valueOf(vStatus.checkControlMessages.get(0).ccmDescriptionShort); - assertEquals(wanted.toString(), st.toString(), "CheckControl"); + wanted = StringType.valueOf(Constants.INVALID); + if (!vStatus.checkControlMessages.isEmpty()) { + wanted = StringType.valueOf(vStatus.checkControlMessages.get(0).ccmDescriptionShort); + } + assertEquals(wanted.toString(), st.toString(), "CheckControl Name"); break; default: assertFalse(true, "Channel " + channelUID + " " + state + " not found"); @@ -465,7 +488,10 @@ private void checkResult(ChannelUID channelUID, State state) { dtt = (DateTimeType) state; switch (gUid) { case CHANNEL_GROUP_SERVICE: - String dueDateString = vStatus.cbsData.get(0).getDueDate(); + String dueDateString = Constants.NULL_DATE; + if (!vStatus.cbsData.isEmpty()) { + dueDateString = vStatus.cbsData.get(0).getDueDate(); + } DateTimeType expectedDTT = DateTimeType.valueOf(Converter.getLocalDateTime(dueDateString)); assertEquals(expectedDTT.toString(), dtt.toString(), "ServiceSate"); break; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java index ac700fd96ad49..2619f9dc3d89d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java @@ -57,10 +57,10 @@ public class VehicleTests { private static final int RANGE_CONV = 4; private static final int RANGE_ELECTRIC = 4; private static final int DOORS = 12; - private static final int CHECK_EMPTY = 1; + private static final int CHECK_EMPTY = 4; private static final int CHECK_AVAILABLE = 4; private static final int SERVICE_AVAILABLE = 5; - private static final int SERVICE_EMPTY = 0; + private static final int SERVICE_EMPTY = 5; private static final int POSITION = 3; @Nullable @@ -128,7 +128,7 @@ private void trace() { * Example: * * testi3Rex - * [main] INFO org.eclipse.jetty.util.log - Logging initialized @3733ms + * [main] INFO org.eclipse.jetty.util.log - Logging initialized @1731ms * Channel testbinding::test:status#lock Secured * Channel testbinding::test:status#service-date 2021-11-01T13:00:00.000+0100 * Channel testbinding::test:status#service-mileage -1.0 km @@ -159,13 +159,16 @@ private void trace() { * Channel testbinding::test:range#remaining-fuel 4.0 l * Channel testbinding::test:status#charge Charging Goal Reached * Channel testbinding::test:check#size 0 + * Channel testbinding::test:check#name INVALID + * Channel testbinding::test:check#mileage -1.0 km + * Channel testbinding::test:check#index -1 * Channel testbinding::test:service#size 4 + * Channel testbinding::test:service#name Brake Fluid * Channel testbinding::test:service#date 2021-11-01T13:00:00.000+0100 * Channel testbinding::test:service#mileage 15345.0 km - * Channel testbinding::test:service#name Brake Fluid * Channel testbinding::test:service#index 0 - * Channel testbinding::test:location#latitude 56.78900146484375 - * Channel testbinding::test:location#longitude 8.765000343322754 + * Channel testbinding::test:location#latitude 50.55604934692383 + * Channel testbinding::test:location#longitude 8.4956693649292 * Channel testbinding::test:location#heading 219.0 ° * */ @@ -224,7 +227,8 @@ public void testF31() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F31/status.json"); - assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + POSITION + CHECK_EMPTY, Optional.empty())); + assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + POSITION + SERVICE_AVAILABLE + CHECK_EMPTY, + Optional.empty())); } @Test @@ -232,7 +236,8 @@ public void testF31Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F31/status.json"); - assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + POSITION + CHECK_EMPTY, Optional.empty())); + assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + POSITION + SERVICE_AVAILABLE + CHECK_EMPTY, + Optional.empty())); } @Test @@ -240,7 +245,8 @@ public void testF35() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F35/status.json"); - assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + POSITION + CHECK_EMPTY, Optional.empty())); + assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + POSITION + SERVICE_EMPTY + CHECK_EMPTY, + Optional.empty())); } @Test @@ -248,7 +254,8 @@ public void testF35Miles() { logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F35/status.json"); - assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + POSITION + CHECK_EMPTY, Optional.empty())); + assertTrue(testVehicle(content, STATUS_CONV + DOORS + RANGE_CONV + POSITION + SERVICE_EMPTY + CHECK_EMPTY, + Optional.empty())); } @Test diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status-ccm-tyre.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status-ccm-tyre.json new file mode 100644 index 0000000000000..b8aed73939e24 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/webapi/vehicle-status-ccm-tyre.json @@ -0,0 +1,87 @@ +{ + "vehicleStatus": { + "mileage": 18390, + "remainingFuel": 4.0, + "remainingRangeElectric": 67.0, + "remainingRangeElectricMls": 41.0, + "remainingRangeFuel": 59.0, + "remainingRangeFuelMls": 36.0, + "maxRangeElectric": 211.0, + "maxRangeElectricMls": 131.0, + "maxFuel": 8.5, + "chargingLevelHv": 35.0, + "vin": "ANONYMOUS", + "updateReason": "VEHICLE_SHUTDOWN_SECURED", + "updateTime": "2020-09-29T12:52:12+0000", + "doorDriverFront": "CLOSED", + "doorDriverRear": "CLOSED", + "doorPassengerFront": "CLOSED", + "doorPassengerRear": "CLOSED", + "windowDriverFront": "CLOSED", + "windowDriverRear": "CLOSED", + "windowPassengerFront": "CLOSED", + "windowPassengerRear": "CLOSED", + "sunroof": "CLOSED", + "trunk": "CLOSED", + "rearWindow": "INVALID", + "hood": "CLOSED", + "doorLockState": "SECURED", + "parkingLight": "OFF", + "positionLight": "ON", + "connectionStatus": "DISCONNECTED", + "chargingStatus": "INVALID", + "lastChargingEndReason": "END_REQUESTED_BY_DRIVER", + "lastChargingEndResult": "SUCCESS", + "position": { + "lat": -1.0, + "lon": -1.0, + "heading": -1, + "status": "OK" + }, + "internalDataTimeUTC": "2020-09-29T12:52:12", + "singleImmediateCharging": false, + "chargingConnectionType": "CONDUCTIVE", + "chargingInductivePositioning": "NOT_POSITIONED", + "vehicleCountry": "DE", + "DCS_CCH_Activation": "NA", + "DCS_CCH_Ongoing": false, + "checkControlMessages": [ + { + "ccmDescriptionLong": "Check tyre pressure and correct if necessary. Afterwards, perform Tyre Pressure Monitor (RDC) reset. See Owner\u0027s Handbook for more information.", + "ccmDescriptionShort": "Check tyre pressure. Initialise RDC", + "ccmId": 142, + "ccmMileage": 18384 + } + ], + "cbsData": [ + { + "cbsType": "BRAKE_FLUID", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next change due at the latest by the stated date.", + "cbsRemainingMileage": -1 + }, + { + "cbsType": "VEHICLE_CHECK", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next visual inspection due when the stated distance has been covered or by the stated date.", + "cbsRemainingMileage": -1 + }, + { + "cbsType": "OIL", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next change due when the stated distance has been covered or by the specified date.", + "cbsRemainingMileage": -1 + }, + { + "cbsType": "VEHICLE_TUV", + "cbsState": "OK", + "cbsDueDate": "2021-11", + "cbsDescription": "Next statutory vehicle inspection due by the stated date.", + "cbsRemainingMileage": -1 + } + ] + } +} \ No newline at end of file From 6e3cd761353673ab3ee68960da0dafa484ca1072 Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 29 Sep 2020 22:40:05 +0200 Subject: [PATCH 059/176] bugfix refresh job cancel Signed-off-by: Bernd --- .../internal/handler/VehicleChannelHandler.java | 15 ++++++--------- .../internal/handler/VehicleHandler.java | 5 +++-- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index d6b6312c6adf9..acda3c83450f2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -329,7 +329,6 @@ public synchronized void setCheckControlList(List l) { } private void updateCheckControls() { - updateState(checkControlSize, new DecimalType(checkControlList.size())); if (!checkControlList.isEmpty()) { if (checkControlListIndex < 0 || checkControlListIndex >= checkControlList.size()) { // select first item @@ -344,7 +343,7 @@ private void updateCheckControls() { updateState(checkControlMileage, QuantityType.valueOf(Converter.round(entry.ccmMileage), MetricPrefix.KILO(SIUnits.METRE))); } - // last update index - this is a sync point and you're sure that all data is valid now + updateState(checkControlSize, new DecimalType(checkControlList.size())); updateState(checkControlIndex, new DecimalType(checkControlListIndex)); } else { // list is empty - set all fields to INVALID. If this isn't done the old values remain @@ -355,7 +354,7 @@ private void updateCheckControls() { updateState(checkControlMileage, QuantityType.valueOf(Converter.round(-1), MetricPrefix.KILO(SIUnits.METRE))); } - // last update index - this is a sync point and you're sure that all data is valid now + updateState(checkControlSize, new DecimalType(checkControlList.size())); updateState(checkControlIndex, new DecimalType(-1)); } } @@ -371,7 +370,6 @@ public synchronized void setServiceList(List l) { } private void updateService() { - updateState(serviceSize, new DecimalType(serviceList.size())); if (!serviceList.isEmpty()) { if (serviceListIndex < 0 || serviceListIndex >= serviceList.size()) { // select first item @@ -387,7 +385,7 @@ private void updateService() { updateState(serviceMileage, QuantityType.valueOf(Converter.round(entry.cbsRemainingMileage), MetricPrefix.KILO(SIUnits.METRE))); } - // last update index - this is a sync point and you're sure that all data is valid now + updateState(serviceSize, new DecimalType(serviceList.size())); updateState(serviceIndex, new DecimalType(serviceListIndex)); } else { // list is empty - set all fields to INVALID. If this isn't done the old values remain @@ -398,7 +396,7 @@ private void updateService() { } else { updateState(serviceMileage, QuantityType.valueOf(-1, MetricPrefix.KILO(SIUnits.METRE))); } - // last update index - this is a sync point and you're sure that all data is valid now + updateState(serviceSize, new DecimalType(serviceList.size())); updateState(serviceIndex, new DecimalType(-1)); } } @@ -417,7 +415,6 @@ public synchronized void nextDestination() { * needs to be synchronized with onResponse update */ private void updateDestination() { - updateState(destinationSize, new DecimalType(destinationList.size())); if (!destinationList.isEmpty()) { if (destinationListIndex < 0 || destinationListIndex >= destinationList.size()) { // select first item @@ -427,14 +424,14 @@ private void updateDestination() { updateState(destinationName, StringType.valueOf(entry.getAddress())); updateState(destinationLat, new DecimalType(entry.lat)); updateState(destinationLon, new DecimalType(entry.lon)); - // last update index - this is a sync point and you're sure that all data is valid now + updateState(destinationSize, new DecimalType(destinationList.size())); updateState(destinationIndex, new DecimalType(destinationListIndex)); } else { // list is empty - set all fields to INVALID. If this isn't done the old values remain updateState(destinationName, StringType.valueOf(Constants.INVALID)); updateState(destinationLat, new DecimalType(-1)); updateState(destinationLon, new DecimalType(-1)); - // last update index - this is a sync point and you're sure that all data is valid noew + updateState(destinationSize, new DecimalType(destinationList.size())); updateState(destinationIndex, new DecimalType(-1)); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 3fae27bfc8a89..bb85120e55753 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -352,10 +352,11 @@ public void switchRemoteServicesOff() { private void startSchedule(int interval) { if (refreshJob.isPresent()) { if (refreshJob.get().isCancelled()) { - Optional.of(scheduler.scheduleWithFixedDelay(this::getData, 0, interval, TimeUnit.MINUTES)); + refreshJob = Optional + .of(scheduler.scheduleWithFixedDelay(this::getData, 0, interval, TimeUnit.MINUTES)); } // else - scheduler is already running! } else { - Optional.of(scheduler.scheduleWithFixedDelay(this::getData, 0, interval, TimeUnit.MINUTES)); + refreshJob = Optional.of(scheduler.scheduleWithFixedDelay(this::getData, 0, interval, TimeUnit.MINUTES)); } } From fe3853a8a6a5e6068a109139c9aa2291681bf5f2 Mon Sep 17 00:00:00 2001 From: Bernd Date: Mon, 5 Oct 2020 09:14:18 +0200 Subject: [PATCH 060/176] Injector added to simulate different Vehicles Signed-off-by: Bernd --- .../internal/handler/ConnectedDriveProxy.java | 11 +++++ .../internal/handler/simulation/Injector.java | 44 +++++++++++++++++++ .../internal/handler/SimulationTest.java | 33 ++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/simulation/Injector.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/SimulationTest.java diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index e69c776256606..b2dbfac6d2dd2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -35,6 +35,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConfiguration; import org.openhab.binding.bmwconnecteddrive.internal.VehicleConfiguration; import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; +import org.openhab.binding.bmwconnecteddrive.internal.handler.simulation.Injector; import org.openhab.binding.bmwconnecteddrive.internal.utils.BimmerConstants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.ImageProperties; @@ -108,6 +109,16 @@ public ConnectedDriveProxy(HttpClientFactory httpClientFactory, ConnectedDriveCo private synchronized void call(String url, boolean post, Optional> params, ResponseCallback callback) { + if (Injector.isActive()) { + if (url.equals(baseUrl)) { + ((StringResponseCallback) callback).onResponse(Optional.of(Injector.getDiscovery())); + } else if (url.endsWith(vehicleStatusAPI)) { + ((StringResponseCallback) callback).onResponse(Optional.of(Injector.getStatus())); + } else { + logger.info("Simulation of {} not supported", url); + } + return; + } Request req; final StringBuffer completeUrl = new StringBuffer(url); if (post) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/simulation/Injector.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/simulation/Injector.java new file mode 100644 index 0000000000000..215348ae6c71b --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/simulation/Injector.java @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler.simulation; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link Injector} Simulates feedback of the ConnectedDrive Portal + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class Injector { + private static boolean active = false; + + // copy discovery json here + private static String discovery = ""; + + // copy vehicle status json here + private static String status = ""; + + public static boolean isActive() { + return active; + } + + public static String getDiscovery() { + return discovery; + } + + public static String getStatus() { + return status; + } + +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/SimulationTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/SimulationTest.java new file mode 100644 index 0000000000000..485c557224dc8 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/SimulationTest.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.junit.jupiter.api.Test; +import org.openhab.binding.bmwconnecteddrive.internal.handler.simulation.Injector; + +/** + * The {@link SimulationTest} Assures simulation is off + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class SimulationTest { + + @Test + public void testSimulationOff() { + assertFalse(Injector.isActive(), "Simulation off"); + } +} From a38ad21bcd14b5914c771e4c781b1343353d73eb Mon Sep 17 00:00:00 2001 From: Bernd Date: Mon, 5 Oct 2020 09:33:08 +0200 Subject: [PATCH 061/176] Injector added to simulate different Vehicles Signed-off-by: Bernd --- .../bmwconnecteddrive/internal/handler/simulation/Injector.java | 1 - 1 file changed, 1 deletion(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/simulation/Injector.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/simulation/Injector.java index 215348ae6c71b..d736d4dbef898 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/simulation/Injector.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/simulation/Injector.java @@ -40,5 +40,4 @@ public static String getDiscovery() { public static String getStatus() { return status; } - } From 8d61d7ae93063dca81447dce3e837137fbc94b05 Mon Sep 17 00:00:00 2001 From: Bernd Date: Sun, 11 Oct 2020 23:15:09 +0200 Subject: [PATCH 062/176] correct legacy mode Signed-off-by: Bernd --- .../internal/dto/status/VehicleStatus.java | 2 +- .../internal/handler/ConnectedDriveProxy.java | 10 +- .../internal/handler/VehicleHandler.java | 16 +-- .../internal/utils/BimmerConstants.java | 3 +- .../resources/responses/F31/status-318i.json | 122 ++++++++++-------- 5 files changed, 84 insertions(+), 69 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java index 84adaa9be7182..40b86de4a6579 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java @@ -160,7 +160,7 @@ public int getNextServiceMileage() { int serviceMileage = Integer.MAX_VALUE; for (int i = 0; i < cbsData.size(); i++) { CBSMessage entry = cbsData.get(i); - if (entry.cbsRemainingMileage != 0) { + if (entry.cbsRemainingMileage != -1) { if (entry.cbsRemainingMileage < serviceMileage) { serviceMileage = entry.cbsRemainingMileage; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index b2dbfac6d2dd2..f81730e0f5aff 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -109,6 +109,8 @@ public ConnectedDriveProxy(HttpClientFactory httpClientFactory, ConnectedDriveCo private synchronized void call(String url, boolean post, Optional> params, ResponseCallback callback) { + // only executed in "simulation mode" + // SimulationTest.testSimulationOff() assures Injector is off when releasing if (Injector.isActive()) { if (url.equals(baseUrl)) { ((StringResponseCallback) callback).onResponse(Optional.of(Injector.getDiscovery())); @@ -119,6 +121,7 @@ private synchronized void call(String url, boolean post, Optional proxy = Optional.empty(); private Optional remote = Optional.empty(); @@ -73,7 +73,7 @@ public class VehicleHandler extends VehicleChannelHandler { private ImageProperties imageProperties = new ImageProperties(); VehicleStatusCallback vehicleStatusCallback = new VehicleStatusCallback(); - StringResponseCallback oldVehicleStatusCallback = new OldVehicleStatusCallback(); + StringResponseCallback oldVehicleStatusCallback = new LegacyVehicleStatusCallback(); StringResponseCallback lastTripCallback = new LastTripCallback(); StringResponseCallback allTripsCallback = new AllTripsCallback(); StringResponseCallback chargeProfileCallback = new ChargeProfilesCallback(); @@ -369,10 +369,10 @@ public void dispose() { public void getData() { if (proxy.isPresent() && configuration.isPresent()) { - if (!compatibilityMode) { + if (!legacyMode) { proxy.get().requestVehcileStatus(configuration.get(), vehicleStatusCallback); } else { - proxy.get().requestOldVehcileStatus(configuration.get(), oldVehicleStatusCallback); + proxy.get().requestLegacyVehcileStatus(configuration.get(), oldVehicleStatusCallback); } if (isSupported(Constants.STATISTICS)) { proxy.get().requestLastTrip(configuration.get(), lastTripCallback); @@ -617,9 +617,9 @@ public void onResponse(Optional content) { public void onError(NetworkError error) { logger.debug("{}", error.toString()); if (error.status == 404) { - compatibilityMode = true; - logger.debug("VehicleStatus not found - switch to old API"); - proxy.get().requestOldVehcileStatus(configuration.get(), oldVehicleStatusCallback); + legacyMode = true; + logger.debug("VehicleStatus not found - switch to legacy API"); + proxy.get().requestLegacyVehcileStatus(configuration.get(), oldVehicleStatusCallback); } vehicleStatusCache = Optional.of(Converter.getGson().toJson(error)); setThingStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, error.reason); @@ -638,7 +638,7 @@ public void onError(NetworkError error) { * The delivered data is converted into the origin dto object so no changes in previous functional code needed */ @NonNullByDefault({}) - public class OldVehicleStatusCallback implements StringResponseCallback { + public class LegacyVehicleStatusCallback implements StringResponseCallback { @Override public void onResponse(Optional content) { if (content.isPresent()) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java index 69b5f55d76b94..78f01edcfb39a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java @@ -30,8 +30,9 @@ @NonNullByDefault public class BimmerConstants { + // https://github.com/bimmerconnected/bimmer_connected/blob/master/bimmer_connected/country_selector.py public static final String SERVER_NORTH_AMERICA = "b2vapi.bmwgroup.us"; - public static final String SERVER_CHINA = "b2vapi.bmwgroup.cn:859"; + public static final String SERVER_CHINA = "b2vapi.bmwgroup.cn:8592"; public static final String SERVER_ROW = "b2vapi.bmwgroup.com"; public static final Map SERVER_MAP = new HashMap() { { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F31/status-318i.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F31/status-318i.json index e3dcaf7beb5c8..211b8f934b751 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F31/status-318i.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F31/status-318i.json @@ -1,59 +1,67 @@ { - "vehicleStatus": { - "mileage": 25659, - "remainingFuel": 55.0, - "remainingRangeElectric": 0.0, - "remainingRangeElectricMls": 0.0, - "remainingRangeFuel": 794.0, - "remainingRangeFuelMls": 493.0, - "maxRangeElectric": 0.0, - "maxRangeElectricMls": 0.0, - "maxFuel": 0.0, - "chargingLevelHv": 0.0, - "vin": "ANONYMOUS", - "updateReason": "VEHICLE_SHUTDOWN", - "updateTime": "2020-09-18T12:11:38+0000", - "doorDriverFront": "CLOSED", - "doorDriverRear": "CLOSED", - "doorPassengerFront": "CLOSED", - "doorPassengerRear": "CLOSED", - "windowDriverFront": "INTERMEDIATE", - "windowDriverRear": "CLOSED", - "windowPassengerFront": "CLOSED", - "windowPassengerRear": "CLOSED", - "trunk": "CLOSED", - "rearWindow": "CLOSED", - "hood": "CLOSED", - "doorLockState": "SECURED", - "parkingLight": "OFF", - "positionLight": "OFF", - "position": { - "lat": -1.0, - "lon": -1.0, - "heading": -1, - "status": "OK" - }, - "internalDataTimeUTC": "2020-09-18T12:11:38", - "singleImmediateCharging": false, - "vehicleCountry": "NL", - "DCS_CCH_Activation": "NA", - "DCS_CCH_Ongoing": false, - "checkControlMessages": [], - "cbsData": [ - { - "cbsType": "OIL", - "cbsState": "OK", - "cbsDueDate": "2022-07", - "cbsDescription": "Next service due when the stated distance has been covered or by the specified date.", - "cbsRemainingMileage": 29000 - }, - { - "cbsType": "VEHICLE_CHECK", - "cbsState": "OK", - "cbsDueDate": "2022-07", - "cbsDescription": "Next visual inspection due when the stated distance has been covered or by the stated date.", - "cbsRemainingMileage": 29000 - } - ] - } + "vehicleStatus": { + "mileage": 26112, + "remainingFuel": 55.0, + "remainingRangeElectric": 0.0, + "remainingRangeElectricMls": 0.0, + "remainingRangeFuel": 879.0, + "remainingRangeFuelMls": 546.0, + "maxRangeElectric": 0.0, + "maxRangeElectricMls": 0.0, + "maxFuel": 0.0, + "chargingLevelHv": 0.0, + "vin": "ANONYMOUS", + "updateReason": "DOOR_STATE_CHANGED", + "updateTime": "2020-09-28T13:17:20+0000", + "doorDriverFront": "CLOSED", + "doorDriverRear": "CLOSED", + "doorPassengerFront": "CLOSED", + "doorPassengerRear": "CLOSED", + "windowDriverFront": "CLOSED", + "windowDriverRear": "CLOSED", + "windowPassengerFront": "CLOSED", + "windowPassengerRear": "CLOSED", + "sunroof": "UNKOWN", + "trunk": "CLOSED", + "rearWindow": "CLOSED", + "hood": "CLOSED", + "doorLockState": "SECURED", + "parkingLight": "OFF", + "positionLight": "OFF", + "position": { + "lat": -1.0, + "lon": -1.0, + "heading": -1, + "status": "OK" + }, + "internalDataTimeUTC": "2020-09-28T13:16:36", + "singleImmediateCharging": false, + "vehicleCountry": "NL", + "DCS_CCH_Activation": "NA", + "DCS_CCH_Ongoing": false, + "checkControlMessages": [], + "cbsData": [ + { + "cbsType": "OIL", + "cbsState": "OK", + "cbsDueDate": "2022-07", + "cbsDescription": "Next service due when the stated distance has been covered or by the specified date.", + "cbsRemainingMileage": 28000 + }, + { + "cbsType": "VEHICLE_CHECK", + "cbsState": "OK", + "cbsDueDate": "2022-07", + "cbsDescription": "Next visual inspection due when the stated distance has been covered or by the stated date.", + "cbsRemainingMileage": 28000 + }, + { + "cbsType": "BRAKE_FLUID", + "cbsState": "OK", + "cbsDueDate": "2022-01", + "cbsDescription": "Next change due at the latest by the stated date.", + "cbsRemainingMileage": -1 + } + ] + } } \ No newline at end of file From 5e74c52a5f6aa4a6f20559c027b3fb41c0c37f15 Mon Sep 17 00:00:00 2001 From: Bernd Date: Sun, 11 Oct 2020 23:22:27 +0200 Subject: [PATCH 063/176] bugfix fingerprint logging Signed-off-by: Bernd --- .../bmwconnecteddrive/internal/handler/VehicleHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 5cab816a86781..3bb82692d4ab9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -228,8 +228,8 @@ public void handleCommand(ChannelUID channelUID, Command command) { status.position.lat = -1; status.position.lon = -1; status.position.heading = -1; - logger.warn("{}", Converter.getGson().toJson(container)); } + logger.warn("{}", Converter.getGson().toJson(container)); } else { logger.warn("### Vehicle Status Empty ###"); } From 2dcb7533a7ee7c5d4d3bf3040066fd9440bd694c Mon Sep 17 00:00:00 2001 From: Bernd Date: Mon, 26 Oct 2020 19:47:17 +0100 Subject: [PATCH 064/176] add region constants Signed-off-by: Bernd --- .../internal/utils/BimmerConstants.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java index 78f01edcfb39a..e6e78abaecb4f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java @@ -31,14 +31,18 @@ public class BimmerConstants { // https://github.com/bimmerconnected/bimmer_connected/blob/master/bimmer_connected/country_selector.py + public static final String REGION_NORTH_AMERICA = "NORTH_AMERICA"; + public static final String REGION_CHINA = "CHINA"; + public static final String REGION_ROW = "ROW"; + public static final String SERVER_NORTH_AMERICA = "b2vapi.bmwgroup.us"; public static final String SERVER_CHINA = "b2vapi.bmwgroup.cn:8592"; public static final String SERVER_ROW = "b2vapi.bmwgroup.com"; public static final Map SERVER_MAP = new HashMap() { { - put("NORTH_AMERICA", SERVER_NORTH_AMERICA); - put("CHINA", SERVER_CHINA); - put("ROW", SERVER_ROW); + put(REGION_NORTH_AMERICA, SERVER_NORTH_AMERICA); + put(REGION_CHINA, SERVER_CHINA); + put(REGION_ROW, SERVER_ROW); } }; From 44f19e1e29c11591c38e03432678c4b638b0cdc2 Mon Sep 17 00:00:00 2001 From: Bernd Date: Sun, 22 Nov 2020 01:07:02 +0100 Subject: [PATCH 065/176] Switch to legacy auth like BimmerConnected project Signed-off-by: Bernd --- .../internal/dto/auth/AuthResponse.java | 24 ++++ .../internal/handler/ConnectedDriveProxy.java | 126 ++++++++++++++++-- .../internal/handler/VehicleHandler.java | 12 +- .../internal/utils/BimmerConstants.java | 16 +++ .../internal/utils/HTTPConstants.java | 1 + .../internal/handler/AuthTest.java | 17 +++ 6 files changed, 183 insertions(+), 13 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/auth/AuthResponse.java diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/auth/AuthResponse.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/auth/AuthResponse.java new file mode 100644 index 0000000000000..5b44051c3dde1 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/auth/AuthResponse.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.dto.auth; + +/** + * The {@link Timer} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +public class AuthResponse { + public String access_token; + public String token_type; + public int expires_in; +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index f81730e0f5aff..96dbe2bd8e51d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -14,6 +14,12 @@ import static org.openhab.binding.bmwconnecteddrive.internal.utils.HTTPConstants.*; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Optional; @@ -35,9 +41,11 @@ import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConfiguration; import org.openhab.binding.bmwconnecteddrive.internal.VehicleConfiguration; import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; +import org.openhab.binding.bmwconnecteddrive.internal.dto.auth.AuthResponse; import org.openhab.binding.bmwconnecteddrive.internal.handler.simulation.Injector; import org.openhab.binding.bmwconnecteddrive.internal.utils.BimmerConstants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.openhab.binding.bmwconnecteddrive.internal.utils.ImageProperties; import org.openhab.core.io.net.http.HttpClientFactory; import org.slf4j.Logger; @@ -58,7 +66,9 @@ public class ConnectedDriveProxy { private final Logger logger = LoggerFactory.getLogger(ConnectedDriveProxy.class); private final Token token = new Token(); private HttpClient httpClient; + private HttpClient authHttpClient; private String authUri; + private String legacyAuthUri; private ConnectedDriveConfiguration configuration; /** @@ -81,6 +91,7 @@ public class ConnectedDriveProxy { * } */ String baseUrl; + String legacyUrl; String vehicleStatusAPI = "/status"; String lastTripAPI = "/statistics/lastTrip"; String allTripsAPI = "/statistics/allTrips"; @@ -93,6 +104,13 @@ public class ConnectedDriveProxy { public ConnectedDriveProxy(HttpClientFactory httpClientFactory, ConnectedDriveConfiguration config) { httpClient = httpClientFactory.getCommonHttpClient(); + authHttpClient = httpClientFactory.createHttpClient(AUTH_HTTP_CLIENT_NAME); + authHttpClient.setFollowRedirects(false); + try { + authHttpClient.start(); + } catch (Exception e) { + logger.warn("Auth Http Client cannot be started"); + } configuration = config; // generate URI for Authorization // see https://customer.bmwgroup.com/one/app/oauth.js @@ -104,7 +122,14 @@ public ConnectedDriveProxy(HttpClientFactory httpClientFactory, ConnectedDriveCo uri.append("/gcdm/oauth/authenticate"); } authUri = uri.toString(); + + StringBuffer legacyAuth = new StringBuffer(); + legacyAuth.append("https://"); + legacyAuth.append(BimmerConstants.AUTH_SERVER_MAP.get(configuration.region)); + legacyAuth.append(BimmerConstants.OAUTH_ENDPOINT); + legacyAuthUri = legacyAuth.toString(); baseUrl = "https://" + getRegionServer() + "/webapi/v1/user/vehicles/"; + legacyUrl = "https://" + getRegionServer() + "/api/vehicle/dynamic/v1/"; } private synchronized void call(String url, boolean post, Optional> params, @@ -121,7 +146,6 @@ private synchronized void call(String url, boolean post, Optional dataMap = new MultiMap(); + dataMap.add(CLIENT_ID, BimmerConstants.CLIENT_ID_VALUE); + dataMap.add(RESPONSE_TYPE, TOKEN); + dataMap.add(REDIRECT_URI, BimmerConstants.REDIRECT_URI_VALUE); + dataMap.add(SCOPE, BimmerConstants.SCOPE_VALUES); + dataMap.add(USERNAME, configuration.userName); + dataMap.add(PASSWORD, configuration.password); + String urlEncodedData = UrlEncoded.encode(dataMap, Charset.defaultCharset(), false); + OutputStream os = con.getOutputStream(); + byte[] input = urlEncodedData.getBytes("utf-8"); + os.write(input, 0, input.length); + BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8")); + StringBuilder response = new StringBuilder(); + String responseLine = null; + while ((responseLine = br.readLine()) != null) { + response.append(responseLine.trim()); + } + logger.info("Response Code {} Message {} ", con.getResponseCode(), con.getResponseMessage()); + tokenFromUrl(con.getHeaderField(HttpHeader.LOCATION.toString())); + } catch (IOException e) { + logger.warn("{}", e.getMessage()); + } + } + + private synchronized void legacyUpdateToken() { + try { + logger.info("Auth {}", legacyAuthUri); + URL url = new URL(legacyAuthUri); + HttpURLConnection.setFollowRedirects(false); + HttpURLConnection con = (HttpURLConnection) url.openConnection(); + con.setRequestMethod("POST"); + + con.setRequestProperty(HttpHeader.CONTENT_TYPE.toString(), CONTENT_TYPE_URL_ENCODED); + con.setRequestProperty(HttpHeader.CONNECTION.toString(), KEEP_ALIVE); + con.setRequestProperty(HttpHeader.HOST.toString(), + BimmerConstants.SERVER_MAP.get(BimmerConstants.SERVER_ROW)); + con.setRequestProperty(HttpHeader.AUTHORIZATION.toString(), BimmerConstants.LEGACY_AUTHORIZATION_VALUE); + con.setRequestProperty(CREDENTIALS, BimmerConstants.LEGACY_CREDENTIAL_VALUES); + con.setDoOutput(true); + + MultiMap dataMap = new MultiMap(); + dataMap.add("grant_type", "password"); + dataMap.add(SCOPE, BimmerConstants.SCOPE_VALUES); + dataMap.add(USERNAME, configuration.userName); + dataMap.add(PASSWORD, configuration.password); + String urlEncodedData = UrlEncoded.encode(dataMap, Charset.defaultCharset(), false); + OutputStream os = con.getOutputStream(); + byte[] input = urlEncodedData.getBytes("utf-8"); + os.write(input, 0, input.length); + BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8")); + StringBuilder response = new StringBuilder(); + String responseLine = null; + while ((responseLine = br.readLine()) != null) { + response.append(responseLine.trim()); + } + logger.info("Response Code {} Message {} ", con.getResponseCode(), con.getResponseMessage()); + // logger.info("Response {}", response.toString()); + AuthResponse authResponse = Converter.getGson().fromJson(response.toString(), AuthResponse.class); + token.setToken(authResponse.access_token); + token.setType(authResponse.token_type); + token.setExpiration(authResponse.expires_in); + } catch (IOException e) { + logger.warn("{}", e.getMessage()); } - httpClient.setFollowRedirects(true); } void tokenFromUrl(String encodedUrl) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 3bb82692d4ab9..ce35b223b7a60 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -223,11 +223,13 @@ public void handleCommand(ChannelUID channelUID, Command command) { VehicleStatusContainer container = Converter.getGson().fromJson(vehicleStatusCache.get(), VehicleStatusContainer.class); VehicleStatus status = container.vehicleStatus; - status.vin = Constants.ANONYMOUS; - if (status.position != null) { - status.position.lat = -1; - status.position.lon = -1; - status.position.heading = -1; + if (status != null) { + status.vin = Constants.ANONYMOUS; + if (status.position != null) { + status.position.lat = -1; + status.position.lon = -1; + status.position.heading = -1; + } } logger.warn("{}", Converter.getGson().toJson(container)); } else { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java index e6e78abaecb4f..050461d5f5c8e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java @@ -35,6 +35,19 @@ public class BimmerConstants { public static final String REGION_CHINA = "CHINA"; public static final String REGION_ROW = "ROW"; + // https://github.com/bimmerconnected/bimmer_connected/blob/master/bimmer_connected/country_selector.py + public static final String AUTH_SERVER_NORTH_AMERICA = "customer.bmwgroup.com/gcdm/usa"; + public static final String AUTH_SERVER_CHINA = "customer.bmwgroup.cn/gcdm"; + public static final String AUTH_SERVER_ROW = "customer.bmwgroup.com/gcdm"; + public static final Map AUTH_SERVER_MAP = new HashMap() { + { + put(REGION_NORTH_AMERICA, AUTH_SERVER_NORTH_AMERICA); + put(REGION_CHINA, AUTH_SERVER_CHINA); + put(REGION_ROW, AUTH_SERVER_ROW); + } + }; + public static final String OAUTH_ENDPOINT = "/oauth/token"; + public static final String SERVER_NORTH_AMERICA = "b2vapi.bmwgroup.us"; public static final String SERVER_CHINA = "b2vapi.bmwgroup.cn:8592"; public static final String SERVER_ROW = "b2vapi.bmwgroup.com"; @@ -51,4 +64,7 @@ public class BimmerConstants { public static final String CLIENT_ID_VALUE = "dbf0a542-ebd1-4ff0-a9a7-55172fbfce35"; public static final String REDIRECT_URI_VALUE = "https://www.bmw-connecteddrive.com/app/static/external-dispatch.html"; public static final String SCOPE_VALUES = "authenticate_user vehicle_data remote_services"; + + public static final String LEGACY_AUTHORIZATION_VALUE = "Basic ZDc2NmI1MzctYTY1NC00Y2JkLWEzZGMtMGNhNTY3MmQ3ZjhkOjE1ZjY5N2Y2LWE1ZDUtNGNhZC05OWQ5LTNhMTViYzdmMzk3Mw=="; + public static final String LEGACY_CREDENTIAL_VALUES = "nQv6CqtxJuXWP74xf3CJwUEP:1zDHx6un4cDjybLENN3kyfumX2kEYigWPcQpdvDRpIBk7rOJ"; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/HTTPConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/HTTPConstants.java index 0b6b9280e084a..1d2062b757ed3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/HTTPConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/HTTPConstants.java @@ -23,6 +23,7 @@ public class HTTPConstants { public static final int HTTP_TIMEOUT_SEC = 10; + public static final String AUTH_HTTP_CLIENT_NAME = "AuthHttpClient"; public static final String CONTENT_TYPE_URL_ENCODED = "application/x-www-form-urlencoded"; public static final String CONTENT_TYPE_JSON = "application/json"; public static final String KEEP_ALIVE = "Keep-Alive"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java index bbc512aa6e537..d37906b16f144 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java @@ -19,6 +19,8 @@ import org.eclipse.jetty.client.HttpClient; import org.junit.jupiter.api.Test; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConfiguration; +import org.openhab.binding.bmwconnecteddrive.internal.utils.BimmerConstants; +import org.openhab.binding.bmwconnecteddrive.internal.utils.HTTPConstants; import org.openhab.core.io.net.http.HttpClientFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,9 +40,24 @@ public void testTokenDecoding() { String headerValue = "https://www.bmw-connecteddrive.com/app/static/external-dispatch.html#access_token=SfXKgkEXeeFJkVqdD4XMmfUU224MRuyh&token_type=Bearer&expires_in=7199"; HttpClientFactory hcf = mock(HttpClientFactory.class); when(hcf.getCommonHttpClient()).thenReturn(mock(HttpClient.class)); + when(hcf.createHttpClient(HTTPConstants.AUTH_HTTP_CLIENT_NAME)).thenReturn(mock(HttpClient.class)); ConnectedDriveProxy dcp = new ConnectedDriveProxy(hcf, mock(ConnectedDriveConfiguration.class)); dcp.tokenFromUrl(headerValue); Token t = dcp.getToken(); assertEquals("Bearer SfXKgkEXeeFJkVqdD4XMmfUU224MRuyh", t.getBearerToken(), "Token"); } + + public void testRealTokenUpdate() { + ConnectedDriveConfiguration config = new ConnectedDriveConfiguration(); + config.region = BimmerConstants.REGION_ROW; + config.userName = "bla"; + config.password = "blub"; + HttpClientFactory hcf = mock(HttpClientFactory.class); + when(hcf.getCommonHttpClient()).thenReturn(mock(HttpClient.class)); + when(hcf.createHttpClient(HTTPConstants.AUTH_HTTP_CLIENT_NAME)).thenReturn(mock(HttpClient.class)); + ConnectedDriveProxy dcp = new ConnectedDriveProxy(hcf, config); + Token t = dcp.getToken(); + logger.info("Token {}", t.getBearerToken()); + logger.info("Expires {}", t.isExpired()); + } } From 45b29dd746b8a019b97558db638c1f7b0a3902ec Mon Sep 17 00:00:00 2001 From: Bernd Date: Sun, 22 Nov 2020 12:38:45 +0100 Subject: [PATCH 066/176] remove auto generated files Signed-off-by: Bernd --- .../.classpath | 38 ------------------- .../.project | 23 ----------- 2 files changed, 61 deletions(-) delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/.classpath delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/.project diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/.classpath b/bundles/org.openhab.binding.bmwconnecteddrive/.classpath deleted file mode 100644 index 4d004b9ea7d59..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/.classpath +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/.project b/bundles/org.openhab.binding.bmwconnecteddrive/.project deleted file mode 100644 index fe8d304ee802e..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - org.openhab.binding.bmwconnecteddrive - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - From 0b5962a65cd6055acd0f9b7e833bb5e8640470b7 Mon Sep 17 00:00:00 2001 From: Bernd Date: Mon, 23 Nov 2020 23:37:12 +0100 Subject: [PATCH 067/176] correct structural review comments Signed-off-by: Bernd --- .../README.md | 6 +-- .../internal/ConnectedDriveConstants.java | 37 ++++--------------- .../internal/discovery/VehicleDiscovery.java | 34 ++++++++--------- .../internal/dto/Destination.java | 2 +- .../internal/dto/NetworkError.java | 2 +- .../internal/dto/charge/Timer.java | 2 +- .../internal/dto/status/CBSMessage.java | 2 +- .../internal/dto/status/Position.java | 2 +- .../handler/ConnectedDriveBridgeHandler.java | 8 ++-- .../internal/handler/ConnectedDriveProxy.java | 23 ++++++------ .../handler/RemoteServiceHandler.java | 2 +- .../internal/handler/Token.java | 2 +- .../internal/handler/VehicleHandler.java | 2 +- .../internal/utils/BimmerConstants.java | 19 ++-------- .../internal/utils/Converter.java | 6 +-- .../internal/utils/ImageProperties.java | 2 +- .../internal/handler/AuthTest.java | 14 ++++++- .../internal/util/FileReader.java | 2 +- 18 files changed, 73 insertions(+), 94 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 1e43ae6edd430..71694ce2d3852 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -105,7 +105,7 @@ Same Configuration is needed for all Things |-----------------|---------|---------------------------------------| | vin | text | Vehicle Identification Number (VIN) | | refreshInterval | integer | Refresh Interval in Minutes | -| units | text | Unit Selection | +| units | text | Unit Selection. See below. | | imageSize | integer | Image Size | | imageViewport | text | Image Viewport | @@ -375,8 +375,8 @@ In order to provide all data the lists are organized the following way based on - will observe differences in the Vehicle Range and Range Radius values. -While Range is indicating the possible distance to be driven on roads the range radius indicates the reachable range on the Map. +You will observe differences in the Vehicle Range and Range Radius values. +While range is indicating the possible distance to be driven on roads the range radius indicates the reachable range on the Map. The right picture shows the distance between Kassel and Frankfurt in Germany. While the Air-line Distance is ~145 Kilometer the Route Distance is ~192 Kilometer. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 45f1532331614..8498474e242e6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -12,7 +12,6 @@ */ package org.openhab.binding.bmwconnecteddrive.internal; -import java.util.HashSet; import java.util.Set; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -59,28 +58,13 @@ public String toString() { } } - public static final Set FUEL_VEHICLES = new HashSet() { - { - add(VehicleType.CONVENTIONAL.toString()); - add(VehicleType.PLUGIN_HYBRID.toString()); - add(VehicleType.ELECTRIC_REX.toString()); - } - }; - public static final Set ELECTRIC_VEHICLES = new HashSet() { - { - add(VehicleType.ELECTRIC.toString()); - add(VehicleType.PLUGIN_HYBRID.toString()); - add(VehicleType.ELECTRIC_REX.toString()); - } - }; + public static final Set FUEL_VEHICLES = Set.of(VehicleType.CONVENTIONAL.toString(), + VehicleType.PLUGIN_HYBRID.toString(), VehicleType.ELECTRIC_REX.toString()); + public static final Set ELECTRIC_VEHICLES = Set.of(VehicleType.ELECTRIC.toString(), + VehicleType.PLUGIN_HYBRID.toString(), VehicleType.ELECTRIC_REX.toString()); // Countries with Mileage display - public static final Set IMPERIAL_COUNTRIES = new HashSet() { - { - add("US"); - add("GB"); - } - }; + public static final Set IMPERIAL_COUNTRIES = Set.of("US", "GB"); // List of all Thing Type UIDs public static final ThingTypeUID THING_TYPE_CONNECTED_DRIVE_ACCOUNT = new ThingTypeUID(BINDING_ID, "account"); @@ -91,15 +75,8 @@ public String toString() { public static final ThingTypeUID THING_TYPE_BEV_REX = new ThingTypeUID(BINDING_ID, VehicleType.ELECTRIC_REX.toString()); public static final ThingTypeUID THING_TYPE_BEV = new ThingTypeUID(BINDING_ID, VehicleType.ELECTRIC.toString()); - public static final Set SUPPORTED_THING_SET = new HashSet() { - { - add(THING_TYPE_CONNECTED_DRIVE_ACCOUNT); - add(THING_TYPE_CONV); - add(THING_TYPE_PHEV); - add(THING_TYPE_BEV_REX); - add(THING_TYPE_BEV); - } - }; + public static final Set SUPPORTED_THING_SET = Set.of(THING_TYPE_CONNECTED_DRIVE_ACCOUNT, + THING_TYPE_CONV, THING_TYPE_PHEV, THING_TYPE_BEV_REX, THING_TYPE_BEV); // Thing Group definitions public static final String CHANNEL_GROUP_STATUS = "status"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java index 32d8ba8a74e6a..278f191219d0c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java @@ -73,13 +73,13 @@ public void onResponse(VehiclesContainer container) { // Dealer if (vehicle.dealer != null) { properties.put("Dealer", vehicle.dealer.name); - properties.put("Dealer Address", vehicle.dealer.street + " " + vehicle.dealer.country + " " + properties.put("DealerAddress", vehicle.dealer.street + " " + vehicle.dealer.country + " " + vehicle.dealer.postalCode + " " + vehicle.dealer.city); - properties.put("Dealer Phone", vehicle.dealer.phone); + properties.put("DealerPhone", vehicle.dealer.phone); } // Services & Support - properties.put("Services Activated", getObject(vehicle, Constants.ACTIVATED)); + properties.put("ServicesActivated", getObject(vehicle, Constants.ACTIVATED)); String servicesSupported = getObject(vehicle, Constants.SUPPORTED); String servicesNotSupported = getObject(vehicle, Constants.NOT_SUPPORTED); if (vehicle.statisticsAvailable) { @@ -88,30 +88,30 @@ public void onResponse(VehiclesContainer container) { servicesNotSupported += Constants.STATISTICS; } properties.put(Constants.SERVICES_SUPPORTED, servicesSupported); - properties.put("Services Not Supported", servicesNotSupported); - properties.put("Support Breakdown Number", vehicle.breakdownNumber); + properties.put("ServicesNotSupported", servicesNotSupported); + properties.put("SupportBreakdownNumber", vehicle.breakdownNumber); // Vehicle Properties if (vehicle.supportedChargingModes != null) { - StringBuffer chargingModes = new StringBuffer(); + StringBuilder chargingModes = new StringBuilder(); vehicle.supportedChargingModes.forEach(e -> { chargingModes.append(e).append(Constants.SPACE); }); - properties.put("Vehicle Charge Modes", chargingModes.toString()); + properties.put("VehicleChargeModes", chargingModes.toString()); } if (vehicle.hasAlarmSystem) { - properties.put("Vehicle Alarm System", "Available"); + properties.put("VehicleAlarmSystem", "Available"); } else { - properties.put("Vehicle Alarm System", "Not Available"); + properties.put("VehicleAlarmSystem", "Not Available"); } - properties.put("Vehicle Brand", vehicle.brand); - properties.put("Vehicle Bodytype", vehicle.bodytype); - properties.put("Vehicle Color", vehicle.color); - properties.put("Vehicle Construction Year", Short.toString(vehicle.yearOfConstruction)); - properties.put("Vehicle Drive Train", vehicle.driveTrain); - properties.put("Vehicle Model", vehicle.model); + properties.put("VehicleBrand", vehicle.brand); + properties.put("VehicleBodytype", vehicle.bodytype); + properties.put("VehicleColor", vehicle.color); + properties.put("VehicleConstructionYear", Short.toString(vehicle.yearOfConstruction)); + properties.put("VehicleDriveTrain", vehicle.driveTrain); + properties.put("VehicleModel", vehicle.model); if (vehicle.chargingControl != null) { - properties.put("Vehicle Charge Control", Converter.toTitleCase(vehicle.model)); + properties.put("VehicleChargeControl", Converter.toTitleCase(vehicle.model)); } // Check now if a thing with the same VIN exists @@ -159,7 +159,7 @@ public void onResponse(VehiclesContainer container) { * @return String with all field names matching this value separated with Spaces */ public String getObject(Object dto, String compare) { - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); for (Field field : dto.getClass().getDeclaredFields()) { try { if (field.get(dto) != null) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java index e8f4b5d4f6957..a8f2113f9ecfd 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java @@ -32,7 +32,7 @@ public class Destination { public String createdAt; public String getAddress() { - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); if (street != null) { buf.append(street); if (streetNumber != null) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/NetworkError.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/NetworkError.java index 8aff2306ef580..51b6d41699927 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/NetworkError.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/NetworkError.java @@ -28,7 +28,7 @@ public class NetworkError { @Override public String toString() { - return new StringBuffer(url).append(Constants.HYPHEN).append(status).append(Constants.HYPHEN).append(reason) + return new StringBuilder(url).append(Constants.HYPHEN).append(status).append(Constants.HYPHEN).append(reason) .append(params).toString(); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java index 0e58e95fc86e7..653e15df2fc05 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java @@ -39,7 +39,7 @@ public String getDays() { if (weekdays == null) { return Converter.toTitleCase(Constants.UNKNOWN); } - StringBuffer days = new StringBuffer(); + StringBuilder days = new StringBuilder(); weekdays.forEach(entry -> { if (days.length() == 0) { days.append(Constants.DAYS.get(entry)); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java index e8797b5ec6bfe..6d7862c92d635 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java @@ -44,7 +44,7 @@ public String getType() { @Override public String toString() { - return new StringBuffer(cbsDueDate).append(Constants.HYPHEN).append(cbsRemainingMileage) + return new StringBuilder(cbsDueDate).append(Constants.HYPHEN).append(cbsRemainingMileage) .append(Constants.HYPHEN).append(cbsType).toString(); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java index 5f081349a2c9f..c4ccc83dd2b69 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java @@ -25,6 +25,6 @@ public class Position { @Override public String toString() { - return new StringBuffer(Float.toString(lat)).append(",").append(Float.toString(lon)).toString(); + return new StringBuilder(Float.toString(lat)).append(",").append(Float.toString(lon)).toString(); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java index c38bb81bcd543..716acfffccec0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java @@ -56,7 +56,7 @@ public class ConnectedDriveBridgeHandler extends BaseBridgeHandler implements St private ServiceRegistration discoveryServiceRegstration; private Optional proxy = Optional.empty(); private Optional configuration = Optional.empty(); - private Optional> refreshJob = Optional.empty(); + private Optional> initializerJob = Optional.empty(); private Optional troubleshootFingerprint = Optional.empty(); private static final String DISCOVERY_FINGERPRINT = "discovery-fingerprint"; @@ -93,7 +93,7 @@ public void initialize() { if (configuration.isPresent()) { proxy = Optional.of(new ConnectedDriveProxy(httpClientFactory, configuration.get())); // give the system some time to create all predefined Vehicles - scheduler.schedule(this::requestVehicles, 5, TimeUnit.SECONDS); + initializerJob = Optional.of(scheduler.schedule(this::requestVehicles, 5, TimeUnit.SECONDS)); } else { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR); } @@ -102,8 +102,8 @@ public void initialize() { @Override public void dispose() { - if (refreshJob.isPresent()) { - refreshJob.get().cancel(true); + if (initializerJob.isPresent()) { + initializerJob.get().cancel(true); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index 96dbe2bd8e51d..fae2029dee08a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -114,7 +114,7 @@ public ConnectedDriveProxy(HttpClientFactory httpClientFactory, ConnectedDriveCo configuration = config; // generate URI for Authorization // see https://customer.bmwgroup.com/one/app/oauth.js - StringBuffer uri = new StringBuffer(); + StringBuilder uri = new StringBuilder(); uri.append("https://customer.bmwgroup.com"); if (BimmerConstants.SERVER_NORTH_AMERICA.equals(configuration.region)) { uri.append("/gcdm/usa/oauth/authenticate"); @@ -123,7 +123,7 @@ public ConnectedDriveProxy(HttpClientFactory httpClientFactory, ConnectedDriveCo } authUri = uri.toString(); - StringBuffer legacyAuth = new StringBuffer(); + StringBuilder legacyAuth = new StringBuilder(); legacyAuth.append("https://"); legacyAuth.append(BimmerConstants.AUTH_SERVER_MAP.get(configuration.region)); legacyAuth.append(BimmerConstants.OAUTH_ENDPOINT); @@ -147,7 +147,7 @@ private synchronized void call(String url, boolean post, Optional> params, StringResponseCallback callback) { - get(new StringBuffer(baseUrl).append(config.vin).append(rangeMapAPI).toString(), params, callback); + get(new StringBuilder(baseUrl).append(config.vin).append(rangeMapAPI).toString(), params, callback); } public void requestImage(VehicleConfiguration config, ImageProperties props, ByteResponseCallback callback) { - String localImageUrl = new StringBuffer(baseUrl).append(config.vin).append(imageAPI).toString(); + String localImageUrl = new StringBuilder(baseUrl).append(config.vin).append(imageAPI).toString(); MultiMap dataMap = new MultiMap(); dataMap.add("width", Integer.toString(props.size)); dataMap.add("height", Integer.toString(props.size)); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java index d6d0bf2ac8dc9..03c2f9225fc23 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -156,7 +156,7 @@ public void onResponse(Optional result) { @Override public void onError(NetworkError error) { - handler.updateRemoteExecutionStatus(serviceExecuting.get(), new StringBuffer(ExecutionState.ERROR.toString()) + handler.updateRemoteExecutionStatus(serviceExecuting.get(), new StringBuilder(ExecutionState.ERROR.toString()) .append(Constants.SPACE).append(Integer.toString(error.status)).toString()); reset(); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java index 2a99efde9a8da..309d0e006eed8 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java @@ -27,7 +27,7 @@ public class Token { private long expiration = 0; public String getBearerToken() { - return new StringBuffer(tokenType).append(Constants.SPACE).append(token).toString(); + return new StringBuilder(tokenType).append(Constants.SPACE).append(token).toString(); } public void setToken(String token) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index ce35b223b7a60..ef80cdf0699c3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -418,7 +418,7 @@ private boolean isSupported(String service) { public void updateRemoteExecutionStatus(String service, String status) { updateState(remoteStateChannel, StringType - .valueOf(Converter.toTitleCase(new StringBuffer(service).append(" ").append(status).toString()))); + .valueOf(Converter.toTitleCase(new StringBuilder(service).append(" ").append(status).toString()))); if (ExecutionState.EXECUTED.toString().equals(status)) { switchRemoteServicesOff(); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java index 050461d5f5c8e..9a3924c4a8849 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java @@ -12,7 +12,6 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.utils; -import java.util.HashMap; import java.util.Map; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -39,25 +38,15 @@ public class BimmerConstants { public static final String AUTH_SERVER_NORTH_AMERICA = "customer.bmwgroup.com/gcdm/usa"; public static final String AUTH_SERVER_CHINA = "customer.bmwgroup.cn/gcdm"; public static final String AUTH_SERVER_ROW = "customer.bmwgroup.com/gcdm"; - public static final Map AUTH_SERVER_MAP = new HashMap() { - { - put(REGION_NORTH_AMERICA, AUTH_SERVER_NORTH_AMERICA); - put(REGION_CHINA, AUTH_SERVER_CHINA); - put(REGION_ROW, AUTH_SERVER_ROW); - } - }; + public static final Map AUTH_SERVER_MAP = Map.of(REGION_NORTH_AMERICA, AUTH_SERVER_NORTH_AMERICA, + REGION_CHINA, AUTH_SERVER_CHINA, REGION_ROW, AUTH_SERVER_ROW); public static final String OAUTH_ENDPOINT = "/oauth/token"; public static final String SERVER_NORTH_AMERICA = "b2vapi.bmwgroup.us"; public static final String SERVER_CHINA = "b2vapi.bmwgroup.cn:8592"; public static final String SERVER_ROW = "b2vapi.bmwgroup.com"; - public static final Map SERVER_MAP = new HashMap() { - { - put(REGION_NORTH_AMERICA, SERVER_NORTH_AMERICA); - put(REGION_CHINA, SERVER_CHINA); - put(REGION_ROW, SERVER_ROW); - } - }; + public static final Map SERVER_MAP = Map.of(REGION_NORTH_AMERICA, SERVER_NORTH_AMERICA, + REGION_CHINA, SERVER_CHINA, REGION_ROW, SERVER_ROW); public static final String AUTHORIZATION_VALUE = "Basic blF2NkNxdHhKdVhXUDc0eGYzQ0p3VUVQOjF6REh4NnVuNGNEanliTEVOTjNreWZ1bVgya0VZaWdXUGNRcGR2RFJwSUJrN3JPSg=="; public static final String CREDENTIAL_VALUES = "nQv6CqtxJuXWP74xf3CJwUEP:1zDHx6un4cDjybLENN3kyfumX2kEYigWPcQpdvDRpIBk7rOJ"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java index cbebd39ae757d..b6be2991b8505 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java @@ -47,10 +47,10 @@ public class Converter { public static final DateTimeFormatter DATE_OUTPUT_PATTERN = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); private static final Gson GSON = new Gson(); + private static final double SCALE = 10; public static double round(double value) { - double scale = Math.pow(10, 1); - return Math.round(value * scale) / scale; + return Math.round(value * SCALE) / SCALE; } public static String getLocalDateTimeWithoutOffest(@Nullable String input) { @@ -92,7 +92,7 @@ public static String toTitleCase(@Nullable String input) { } else { String lower = input.replaceAll(Constants.UNDERLINE, Constants.SPACE).toLowerCase(); String[] arr = lower.split(Constants.SPACE); - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); for (int i = 0; i < arr.length; i++) { sb.append(Character.toUpperCase(arr[i].charAt(0))).append(arr[i].substring(1)).append(" "); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ImageProperties.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ImageProperties.java index 2471efe61571d..dbab740c95a27 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ImageProperties.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ImageProperties.java @@ -44,6 +44,6 @@ public boolean failLimitReached() { @Override public String toString() { - return new StringBuffer(viewport).append(Integer.toString(size)).toString(); + return new StringBuilder(viewport).append(Integer.toString(size)).toString(); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java index d37906b16f144..72a21044281eb 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java @@ -15,6 +15,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.*; +import java.util.Map; + import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jetty.client.HttpClient; import org.junit.jupiter.api.Test; @@ -35,13 +37,23 @@ public class AuthTest { private final Logger logger = LoggerFactory.getLogger(VehicleHandler.class); + @Test + public void testAtuthServerMap() { + Map authServers = BimmerConstants.AUTH_SERVER_MAP; + assertEquals(3, authServers.size(), "Number of Servers"); + Map api = BimmerConstants.SERVER_MAP; + assertEquals(3, api.size(), "Number of Servers"); + } + @Test public void testTokenDecoding() { String headerValue = "https://www.bmw-connecteddrive.com/app/static/external-dispatch.html#access_token=SfXKgkEXeeFJkVqdD4XMmfUU224MRuyh&token_type=Bearer&expires_in=7199"; HttpClientFactory hcf = mock(HttpClientFactory.class); when(hcf.getCommonHttpClient()).thenReturn(mock(HttpClient.class)); when(hcf.createHttpClient(HTTPConstants.AUTH_HTTP_CLIENT_NAME)).thenReturn(mock(HttpClient.class)); - ConnectedDriveProxy dcp = new ConnectedDriveProxy(hcf, mock(ConnectedDriveConfiguration.class)); + ConnectedDriveConfiguration config = new ConnectedDriveConfiguration(); + config.region = BimmerConstants.REGION_ROW; + ConnectedDriveProxy dcp = new ConnectedDriveProxy(hcf, config); dcp.tokenFromUrl(headerValue); Token t = dcp.getToken(); assertEquals("Bearer SfXKgkEXeeFJkVqdD4XMmfUU224MRuyh", t.getBearerToken(), "Token"); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/FileReader.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/FileReader.java index 0860b54b20284..31db15e452461 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/FileReader.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/FileReader.java @@ -32,7 +32,7 @@ public class FileReader { public static String readFileInString(String filename) { try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filename), "UTF-8"));) { - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); String sCurrentLine; while ((sCurrentLine = br.readLine()) != null) { From 3c0e233f07254d0f996fe95b9e0745155494d1a2 Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 24 Nov 2020 00:36:32 +0100 Subject: [PATCH 068/176] lower case thing type ids Signed-off-by: Bernd --- .../internal/ConnectedDriveConstants.java | 8 +- .../internal/discovery/VehicleDiscovery.java | 2 +- .../i18n/bmwconnecteddrive_de.properties | 166 +++++++++--------- .../main/resources/OH-INF/thing/thing-bev.xml | 2 +- .../resources/OH-INF/thing/thing-bev_rex.xml | 2 +- .../resources/OH-INF/thing/thing-conv.xml | 2 +- .../resources/OH-INF/thing/thing-phev.xml | 2 +- .../internal/discovery/DiscoveryTest.java | 2 +- 8 files changed, 93 insertions(+), 93 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 8498474e242e6..c30bc165faa6c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -41,10 +41,10 @@ public class ConnectedDriveConstants { // See constants from bimmer-connected // https://github.com/bimmerconnected/bimmer_connected/blob/master/bimmer_connected/vehicle.py public enum VehicleType { - CONVENTIONAL("CONV"), - PLUGIN_HYBRID("PHEV"), - ELECTRIC_REX("BEV_REX"), - ELECTRIC("BEV"); + CONVENTIONAL("conv"), + PLUGIN_HYBRID("phev"), + ELECTRIC_REX("bev_rex"), + ELECTRIC("bev"); private final String type; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java index 278f191219d0c..64d2e2832c9e0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java @@ -65,7 +65,7 @@ public void onResponse(VehiclesContainer container) { vehicles.forEach(vehicle -> { ThingUID bridgeUID = bridgeHandler.getThing().getUID(); // the DriveTrain field in the delivered json is defining the Vehicle Type - String vehicleType = vehicle.driveTrain; + String vehicleType = vehicle.driveTrain.toLowerCase(); SUPPORTED_THING_SET.forEach(entry -> { if (entry.getId().equals(vehicleType)) { ThingUID uid = new ThingUID(entry, vehicle.vin, bridgeUID.getId()); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties index 0c46a97b045f4..8735d21b15bad 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties @@ -13,89 +13,89 @@ thing-type.config.bmwconnecteddrive.account.region.option.CHINA = China thing-type.config.bmwconnecteddrive.account.region.option.ROW = Rest der Welt # thing types -thing-type.bmwconnecteddrive.BEV_REX.label = BMW Elektrofahrzeug mit REX -thing-type.bmwconnecteddrive.BEV_REX.description = BMW Elektrofahrzeug mit Range Extender (BEV_REX) -thing-type.config.bmwconnecteddrive.BEV_REX.vin.label = Fahrzeug Identifikationsnummer (VIN) -thing-type.config.bmwconnecteddrive.BEV_REX.vin.description = VIN des Fahrzeugs -thing-type.config.bmwconnecteddrive.BEV_REX.refreshInterval.label = Datenaktualisierung in Minuten -thing-type.config.bmwconnecteddrive.BEV_REX.refreshInterval.description = Rate der Datenaktualisierung Ihres Fahrzeugs -thing-type.config.bmwconnecteddrive.BEV_REX.units.label = Einheiten -thing-type.config.bmwconnecteddrive.BEV_REX.units.description = Automatische oder direkte Auswahl der Einheiten -thing-type.config.bmwconnecteddrive.BEV_REX.units.option.AUTODETECT = Automatische Auswahl -thing-type.config.bmwconnecteddrive.BEV_REX.units.option.IMPERIAL = Angloamerikanisches System -thing-type.config.bmwconnecteddrive.BEV_REX.units.option.METRIC = Metrisches System -thing-type.config.bmwconnecteddrive.BEV_REX.imageSize.label = Bildgröße -thing-type.config.bmwconnecteddrive.BEV_REX.imageSize.description = Bildgröße des Fahrzeugs für Länge und Breite -thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.label = Bild Ansicht -thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.description = Ansicht des Fahrzeugs -thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.option.FRONT = Vorderansicht -thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.option.REAR = Rückansicht -thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.option.SIDE = Seitenansicht -thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.option.DASHBOARD = Innenansicht Armaturen -thing-type.config.bmwconnecteddrive.BEV_REX.imageViewport.option.DRIVERDOOR = Seitenansicht Fahrertür - -thing-type.bmwconnecteddrive.BEV.label = BMW Elektrofahrzeug -thing-type.bmwconnecteddrive.BEV.description = Batterieelektrisches Fahrzeug (BEV) -thing-type.config.bmwconnecteddrive.BEV.vin.label = Fahrzeug Identifikationsnummer (VIN) -thing-type.config.bmwconnecteddrive.BEV.vin.description = VIN des Fahrzeugs -thing-type.config.bmwconnecteddrive.BEV.refreshInterval.label = Datenaktualisierung in Minuten -thing-type.config.bmwconnecteddrive.BEV.refreshInterval.description = Rate der Datenaktualisierung Ihres Fahrzeugs -thing-type.config.bmwconnecteddrive.BEV.units.label = Einheiten -thing-type.config.bmwconnecteddrive.BEV.units.description = Automatische oder direkte Auswahl der Einheiten -thing-type.config.bmwconnecteddrive.BEV.units.option.AUTODETECT = Automatische Auswahl -thing-type.config.bmwconnecteddrive.BEV.units.option.IMPERIAL = Angloamerikanisches System -thing-type.config.bmwconnecteddrive.BEV.units.option.METRIC = Metrisches System -thing-type.config.bmwconnecteddrive.BEV.imageSize.label = Bildgröße -thing-type.config.bmwconnecteddrive.BEV.imageSize.description = Bildgröße des Fahrzeugs für Länge und Breite -thing-type.config.bmwconnecteddrive.BEV.imageViewport.label = Bild Ansicht -thing-type.config.bmwconnecteddrive.BEV.imageViewport.description = Ansicht des Fahrzeugs -thing-type.config.bmwconnecteddrive.BEV.imageViewport.option.FRONT = Vorderansicht -thing-type.config.bmwconnecteddrive.BEV.imageViewport.option.REAR = Rückansicht -thing-type.config.bmwconnecteddrive.BEV.imageViewport.option.SIDE = Seitenansicht -thing-type.config.bmwconnecteddrive.BEV.imageViewport.option.DASHBOARD = Innenansicht Armaturen -thing-type.config.bmwconnecteddrive.BEV.imageViewport.option.DRIVERDOOR = Seitenansicht Fahrertür - -thing-type.bmwconnecteddrive.PHEV.label = BMW Plug-in-Hybrid Elektrofahrzeug -thing-type.bmwconnecteddrive.PHEV.description = Konventionelles Fahrzeug mit Elektromotor (PHEV) -thing-type.config.bmwconnecteddrive.PHEV.vin.label = Fahrzeug Identifikationsnummer (VIN) -thing-type.config.bmwconnecteddrive.PHEV.vin.description = VIN des Fahrzeugs -thing-type.config.bmwconnecteddrive.PHEV.refreshInterval.label = Datenaktualisierung in Minuten -thing-type.config.bmwconnecteddrive.PHEV.refreshInterval.description = Rate der Datenaktualisierung Ihres Fahrzeugs -thing-type.config.bmwconnecteddrive.PHEV.units.label = Einheiten -thing-type.config.bmwconnecteddrive.PHEV.units.description = Automatische oder direkte Auswahl der Einheiten -thing-type.config.bmwconnecteddrive.PHEV.units.option.AUTODETECT = Automatische Auswahl -thing-type.config.bmwconnecteddrive.PHEV.units.option.IMPERIAL = Angloamerikanisches System -thing-type.config.bmwconnecteddrive.PHEV.units.option.METRIC = Metrisches System -thing-type.config.bmwconnecteddrive.PHEV.imageSize.label = Bildgröße -thing-type.config.bmwconnecteddrive.PHEV.imageSize.description = Bildgröße des Fahrzeugs für Länge und Breite -thing-type.config.bmwconnecteddrive.PHEV.imageViewport.label = Bild Ansicht -thing-type.config.bmwconnecteddrive.PHEV.imageViewport.description = Ansicht des Fahrzeugs -thing-type.config.bmwconnecteddrive.PHEV.imageViewport.option.FRONT = Vorderansicht -thing-type.config.bmwconnecteddrive.PHEV.imageViewport.option.REAR = Rückansicht -thing-type.config.bmwconnecteddrive.PHEV.imageViewport.option.SIDE = Seitenansicht -thing-type.config.bmwconnecteddrive.PHEV.imageViewport.option.DASHBOARD = Innenansicht Armaturen -thing-type.config.bmwconnecteddrive.PHEV.imageViewport.option.DRIVERDOOR = Seitenansicht Fahrertür - -thing-type.bmwconnecteddrive.CONV.label = BMW Konventionelles Fahrzeug -thing-type.bmwconnecteddrive.CONV.description = Konventionelles Benzin/Diesel Fahrzeug (CONV) -thing-type.config.bmwconnecteddrive.CONV.vin.label = Fahrzeug Identifikationsnummer (VIN) -thing-type.config.bmwconnecteddrive.CONV.vin.description = VIN des Fahrzeugs -thing-type.config.bmwconnecteddrive.CONV.refreshInterval.label = Datenaktualisierung in Minuten -thing-type.config.bmwconnecteddrive.CONV.refreshInterval.description = Rate der Datenaktualisierung Ihres Fahrzeugs -thing-type.config.bmwconnecteddrive.CONV.units.label = Einheiten -thing-type.config.bmwconnecteddrive.CONV.units.description = Automatische oder direkte Auswahl der Einheiten -thing-type.config.bmwconnecteddrive.CONV.units.option.AUTODETECT = Automatische Auswahl -thing-type.config.bmwconnecteddrive.CONV.units.option.IMPERIAL = Angloamerikanisches System -thing-type.config.bmwconnecteddrive.CONV.units.option.METRIC = Metrisches System -thing-type.config.bmwconnecteddrive.CONV.imageSize.label = Bildgröße -thing-type.config.bmwconnecteddrive.CONV.imageSize.description = Bildgröße des Fahrzeugs für Länge und Breite -thing-type.config.bmwconnecteddrive.CONV.imageViewport.label = Bild Ansicht -thing-type.config.bmwconnecteddrive.CONV.imageViewport.description = Ansicht des Fahrzeugs -thing-type.config.bmwconnecteddrive.CONV.imageViewport.option.FRONT = Vorderansicht -thing-type.config.bmwconnecteddrive.CONV.imageViewport.option.REAR = Rückansicht -thing-type.config.bmwconnecteddrive.CONV.imageViewport.option.SIDE = Seitenansicht -thing-type.config.bmwconnecteddrive.CONV.imageViewport.option.DASHBOARD = Innenansicht Armaturen -thing-type.config.bmwconnecteddrive.CONV.imageViewport.option.DRIVERDOOR = Seitenansicht Fahrertür +thing-type.bmwconnecteddrive.bev_rex.label = BMW Elektrofahrzeug mit REX +thing-type.bmwconnecteddrive.bev_rex.description = BMW Elektrofahrzeug mit Range Extender (bev_rex) +thing-type.config.bmwconnecteddrive.bev_rex.vin.label = Fahrzeug Identifikationsnummer (VIN) +thing-type.config.bmwconnecteddrive.bev_rex.vin.description = VIN des Fahrzeugs +thing-type.config.bmwconnecteddrive.bev_rex.refreshInterval.label = Datenaktualisierung in Minuten +thing-type.config.bmwconnecteddrive.bev_rex.refreshInterval.description = Rate der Datenaktualisierung Ihres Fahrzeugs +thing-type.config.bmwconnecteddrive.bev_rex.units.label = Einheiten +thing-type.config.bmwconnecteddrive.bev_rex.units.description = Automatische oder direkte Auswahl der Einheiten +thing-type.config.bmwconnecteddrive.bev_rex.units.option.AUTODETECT = Automatische Auswahl +thing-type.config.bmwconnecteddrive.bev_rex.units.option.IMPERIAL = Angloamerikanisches System +thing-type.config.bmwconnecteddrive.bev_rex.units.option.METRIC = Metrisches System +thing-type.config.bmwconnecteddrive.bev_rex.imageSize.label = Bildgröße +thing-type.config.bmwconnecteddrive.bev_rex.imageSize.description = Bildgröße des Fahrzeugs für Länge und Breite +thing-type.config.bmwconnecteddrive.bev_rex.imageViewport.label = Bild Ansicht +thing-type.config.bmwconnecteddrive.bev_rex.imageViewport.description = Ansicht des Fahrzeugs +thing-type.config.bmwconnecteddrive.bev_rex.imageViewport.option.FRONT = Vorderansicht +thing-type.config.bmwconnecteddrive.bev_rex.imageViewport.option.REAR = Rückansicht +thing-type.config.bmwconnecteddrive.bev_rex.imageViewport.option.SIDE = Seitenansicht +thing-type.config.bmwconnecteddrive.bev_rex.imageViewport.option.DASHBOARD = Innenansicht Armaturen +thing-type.config.bmwconnecteddrive.bev_rex.imageViewport.option.DRIVERDOOR = Seitenansicht Fahrertür + +thing-type.bmwconnecteddrive.bev.label = BMW Elektrofahrzeug +thing-type.bmwconnecteddrive.bev.description = Batterieelektrisches Fahrzeug (bev) +thing-type.config.bmwconnecteddrive.bev.vin.label = Fahrzeug Identifikationsnummer (VIN) +thing-type.config.bmwconnecteddrive.bev.vin.description = VIN des Fahrzeugs +thing-type.config.bmwconnecteddrive.bev.refreshInterval.label = Datenaktualisierung in Minuten +thing-type.config.bmwconnecteddrive.bev.refreshInterval.description = Rate der Datenaktualisierung Ihres Fahrzeugs +thing-type.config.bmwconnecteddrive.bev.units.label = Einheiten +thing-type.config.bmwconnecteddrive.bev.units.description = Automatische oder direkte Auswahl der Einheiten +thing-type.config.bmwconnecteddrive.bev.units.option.AUTODETECT = Automatische Auswahl +thing-type.config.bmwconnecteddrive.bev.units.option.IMPERIAL = Angloamerikanisches System +thing-type.config.bmwconnecteddrive.bev.units.option.METRIC = Metrisches System +thing-type.config.bmwconnecteddrive.bev.imageSize.label = Bildgröße +thing-type.config.bmwconnecteddrive.bev.imageSize.description = Bildgröße des Fahrzeugs für Länge und Breite +thing-type.config.bmwconnecteddrive.bev.imageViewport.label = Bild Ansicht +thing-type.config.bmwconnecteddrive.bev.imageViewport.description = Ansicht des Fahrzeugs +thing-type.config.bmwconnecteddrive.bev.imageViewport.option.FRONT = Vorderansicht +thing-type.config.bmwconnecteddrive.bev.imageViewport.option.REAR = Rückansicht +thing-type.config.bmwconnecteddrive.bev.imageViewport.option.SIDE = Seitenansicht +thing-type.config.bmwconnecteddrive.bev.imageViewport.option.DASHBOARD = Innenansicht Armaturen +thing-type.config.bmwconnecteddrive.bev.imageViewport.option.DRIVERDOOR = Seitenansicht Fahrertür + +thing-type.bmwconnecteddrive.phev.label = BMW Plug-in-Hybrid Elektrofahrzeug +thing-type.bmwconnecteddrive.phev.description = Konventionelles Fahrzeug mit Elektromotor (phev) +thing-type.config.bmwconnecteddrive.phev.vin.label = Fahrzeug Identifikationsnummer (VIN) +thing-type.config.bmwconnecteddrive.phev.vin.description = VIN des Fahrzeugs +thing-type.config.bmwconnecteddrive.phev.refreshInterval.label = Datenaktualisierung in Minuten +thing-type.config.bmwconnecteddrive.phev.refreshInterval.description = Rate der Datenaktualisierung Ihres Fahrzeugs +thing-type.config.bmwconnecteddrive.phev.units.label = Einheiten +thing-type.config.bmwconnecteddrive.phev.units.description = Automatische oder direkte Auswahl der Einheiten +thing-type.config.bmwconnecteddrive.phev.units.option.AUTODETECT = Automatische Auswahl +thing-type.config.bmwconnecteddrive.phev.units.option.IMPERIAL = Angloamerikanisches System +thing-type.config.bmwconnecteddrive.phev.units.option.METRIC = Metrisches System +thing-type.config.bmwconnecteddrive.phev.imageSize.label = Bildgröße +thing-type.config.bmwconnecteddrive.phev.imageSize.description = Bildgröße des Fahrzeugs für Länge und Breite +thing-type.config.bmwconnecteddrive.phev.imageViewport.label = Bild Ansicht +thing-type.config.bmwconnecteddrive.phev.imageViewport.description = Ansicht des Fahrzeugs +thing-type.config.bmwconnecteddrive.phev.imageViewport.option.FRONT = Vorderansicht +thing-type.config.bmwconnecteddrive.phev.imageViewport.option.REAR = Rückansicht +thing-type.config.bmwconnecteddrive.phev.imageViewport.option.SIDE = Seitenansicht +thing-type.config.bmwconnecteddrive.phev.imageViewport.option.DASHBOARD = Innenansicht Armaturen +thing-type.config.bmwconnecteddrive.phev.imageViewport.option.DRIVERDOOR = Seitenansicht Fahrertür + +thing-type.bmwconnecteddrive.conv.label = BMW Konventionelles Fahrzeug +thing-type.bmwconnecteddrive.conv.description = Konventionelles Benzin/Diesel Fahrzeug (conv) +thing-type.config.bmwconnecteddrive.conv.vin.label = Fahrzeug Identifikationsnummer (VIN) +thing-type.config.bmwconnecteddrive.conv.vin.description = VIN des Fahrzeugs +thing-type.config.bmwconnecteddrive.conv.refreshInterval.label = Datenaktualisierung in Minuten +thing-type.config.bmwconnecteddrive.conv.refreshInterval.description = Rate der Datenaktualisierung Ihres Fahrzeugs +thing-type.config.bmwconnecteddrive.conv.units.label = Einheiten +thing-type.config.bmwconnecteddrive.conv.units.description = Automatische oder direkte Auswahl der Einheiten +thing-type.config.bmwconnecteddrive.conv.units.option.AUTODETECT = Automatische Auswahl +thing-type.config.bmwconnecteddrive.conv.units.option.IMPERIAL = Angloamerikanisches System +thing-type.config.bmwconnecteddrive.conv.units.option.METRIC = Metrisches System +thing-type.config.bmwconnecteddrive.conv.imageSize.label = Bildgröße +thing-type.config.bmwconnecteddrive.conv.imageSize.description = Bildgröße des Fahrzeugs für Länge und Breite +thing-type.config.bmwconnecteddrive.conv.imageViewport.label = Bild Ansicht +thing-type.config.bmwconnecteddrive.conv.imageViewport.description = Ansicht des Fahrzeugs +thing-type.config.bmwconnecteddrive.conv.imageViewport.option.FRONT = Vorderansicht +thing-type.config.bmwconnecteddrive.conv.imageViewport.option.REAR = Rückansicht +thing-type.config.bmwconnecteddrive.conv.imageViewport.option.SIDE = Seitenansicht +thing-type.config.bmwconnecteddrive.conv.imageViewport.option.DASHBOARD = Innenansicht Armaturen +thing-type.config.bmwconnecteddrive.conv.imageViewport.option.DRIVERDOOR = Seitenansicht Fahrertür # Channel Groups channel-group-type.bmwconnecteddrive.charge-values.label = Elektrisches Laden diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml index a6632ca6b6ca1..81b931299acc6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml @@ -4,7 +4,7 @@ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml index c2ae7a6ab72f5..05b8aba25b93a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml @@ -4,7 +4,7 @@ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml index d16ef96e7d706..0777dc89b5b85 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml @@ -4,7 +4,7 @@ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml index 21c4d32525f13..77b5cf6aedb7b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml @@ -4,7 +4,7 @@ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java index 4cab9704d2cd3..3e0102d328d20 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java @@ -63,7 +63,7 @@ public void testDiscovery() { List results = discoveries.getAllValues(); assertEquals(1, results.size(), "Found Vehicles"); DiscoveryResult result = results.get(0); - assertEquals("bmwconnecteddrive:BEV_REX:abc:MY_REAL_VIN", result.getThingUID().getAsString(), "Thing UID"); + assertEquals("bmwconnecteddrive:bev_rex:abc:MY_REAL_VIN", result.getThingUID().getAsString(), "Thing UID"); } @Test From b2444d8060c648106aa3b43345aab77fa0114e1d Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 24 Nov 2020 01:31:25 +0100 Subject: [PATCH 069/176] introduce Location type for GPS coordinates Signed-off-by: Bernd --- .../internal/ConnectedDriveConstants.java | 3 +-- .../internal/dto/Destination.java | 5 +++++ .../internal/dto/status/Position.java | 8 ++++++- .../handler/VehicleChannelHandler.java | 22 +++++++------------ .../i18n/bmwconnecteddrive_de.properties | 6 ++--- .../thing/destination-channel-types.xml | 10 +++------ .../OH-INF/thing/destination-group.xml | 3 +-- .../OH-INF/thing/location-channel-group.xml | 3 +-- .../OH-INF/thing/loction-channel-types.xml | 10 +++------ .../internal/dto/StatusWrapper.java | 17 +++++--------- .../internal/handler/VehicleTests.java | 2 +- .../test/resources/responses/F15/status.json | 4 ++-- 12 files changed, 40 insertions(+), 53 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index c30bc165faa6c..4651069076a2b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -102,8 +102,7 @@ public String toString() { public static final String NAME = "name"; public static final String DATE = "date"; public static final String MILEAGE = "mileage"; - public static final String LONGITUDE = "longitude"; - public static final String LATITUDE = "latitude"; + public static final String GPS = "gps"; public static final String HEADING = "heading"; // Status diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java index a8f2113f9ecfd..e7421a2ccc5c6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java @@ -14,6 +14,7 @@ import static org.openhab.binding.bmwconnecteddrive.internal.utils.Constants.*; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; /** @@ -52,4 +53,8 @@ public String getAddress() { return Converter.toTitleCase(buf.toString()); } } + + public String getCoordinates() { + return new StringBuilder().append(lat).append(Constants.COMMA).append(lon).toString(); + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java index c4ccc83dd2b69..83e4d44930d07 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java @@ -12,6 +12,8 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.dto.status; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; + /** * The {@link Position} Data Transfer Object * @@ -23,8 +25,12 @@ public class Position { public int heading;// ": 219, public String status;// ": "OK" + public String getCoordinates() { + return new StringBuilder(Float.toString(lat)).append(Constants.COMMA).append(Float.toString(lon)).toString(); + } + @Override public String toString() { - return new StringBuilder(Float.toString(lat)).append(",").append(Float.toString(lon)).toString(); + return new StringBuilder(Float.toString(lat)).append(Constants.COMMA).append(Float.toString(lon)).toString(); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index acda3c83450f2..61049eb500ab5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -38,6 +38,7 @@ import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; +import org.openhab.core.library.types.PointType; import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.StringType; import org.openhab.core.library.unit.ImperialUnits; @@ -134,8 +135,7 @@ public class VehicleChannelHandler extends BaseThingHandler { protected ChannelUID tripAvgRecuperation; // Location Channels - protected ChannelUID longitude; - protected ChannelUID latitude; + protected ChannelUID gpsLocation; protected ChannelUID heading; // Remote Services @@ -149,8 +149,7 @@ public class VehicleChannelHandler extends BaseThingHandler { // Remote Services protected ChannelUID destinationName; - protected ChannelUID destinationLat; - protected ChannelUID destinationLon; + protected ChannelUID destinationLocation; protected ChannelUID destinationSize; protected ChannelUID destinationIndex; protected ChannelUID destinationNext; @@ -265,8 +264,7 @@ public VehicleChannelHandler(Thing thing, String type, boolean imperial) { lifeTimeSingleLongestDistance = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, SINGLE_LONGEST_DISTANCE); // Location Channels - longitude = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, LONGITUDE); - latitude = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, LATITUDE); + gpsLocation = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, GPS); heading = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, HEADING); // Charge Channels @@ -293,8 +291,7 @@ public VehicleChannelHandler(Thing thing, String type, boolean imperial) { remoteStateChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_STATE); destinationName = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, NAME); - destinationLat = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, LATITUDE); - destinationLon = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, LONGITUDE); + destinationLocation = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, GPS); destinationSize = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, SIZE); destinationIndex = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, INDEX); destinationNext = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, NEXT); @@ -422,15 +419,13 @@ private void updateDestination() { } Destination entry = destinationList.get(destinationListIndex); updateState(destinationName, StringType.valueOf(entry.getAddress())); - updateState(destinationLat, new DecimalType(entry.lat)); - updateState(destinationLon, new DecimalType(entry.lon)); + updateState(destinationLocation, PointType.valueOf(entry.getCoordinates())); updateState(destinationSize, new DecimalType(destinationList.size())); updateState(destinationIndex, new DecimalType(destinationListIndex)); } else { // list is empty - set all fields to INVALID. If this isn't done the old values remain updateState(destinationName, StringType.valueOf(Constants.INVALID)); - updateState(destinationLat, new DecimalType(-1)); - updateState(destinationLon, new DecimalType(-1)); + updateState(destinationLocation, PointType.valueOf("-1,-1")); updateState(destinationSize, new DecimalType(destinationList.size())); updateState(destinationIndex, new DecimalType(-1)); } @@ -513,8 +508,7 @@ protected void updateWindows(Windows windowState) { } protected void updatePosition(Position pos) { - updateState(latitude, new DecimalType(pos.lat)); - updateState(longitude, new DecimalType(pos.lon)); + updateState(gpsLocation, PointType.valueOf(pos.getCoordinates())); updateState(heading, QuantityType.valueOf(pos.heading, SmartHomeUnits.DEGREE_ANGLE)); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties index 8735d21b15bad..c3b85c1a2e0f1 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties @@ -196,14 +196,12 @@ channel-type.bmwconnecteddrive.timer3-days-channel.label = Zeitprofil 3 - Tage channel-type.bmwconnecteddrive.timer3-enabled-channel.label = Zeitprofil 3 - Aktiviert channel-type.bmwconnecteddrive.destination-name-channel.label = Zieladresse -channel-type.bmwconnecteddrive.destination-latitude-channel.label = Ziel Breitengrad -channel-type.bmwconnecteddrive.destination-longitude-channel.label = Ziel Längengrad +channel-type.bmwconnecteddrive.destination-gps-channel.label = Ziel Koordinaten channel-type.bmwconnecteddrive.destination-size-channel.label = Anzahl der Fahrzeugziele channel-type.bmwconnecteddrive.destination-index-channel.label = Index des Ausgewählten Ziels channel-type.bmwconnecteddrive.destination-next-channel.label = Nächstes Ziel -channel-type.bmwconnecteddrive.longitude-channel.label = Längengrad -channel-type.bmwconnecteddrive.latitude-channel.label = Breitengrad +channel-type.bmwconnecteddrive.gps-channel.label = Koordinaten channel-type.bmwconnecteddrive.heading-channel.label = Ausrichtung channel-type.bmwconnecteddrive.trip-date-time-channel.label = Datum diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-channel-types.xml index b513d0bf5e8eb..618dbcf061377 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-channel-types.xml @@ -7,13 +7,9 @@ String - - Number - - - - Number - + + Location + String diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-group.xml index 3d01bab32d197..81a3306b55391 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-group.xml @@ -8,8 +8,7 @@ Shows Your Destinations in a List - - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/location-channel-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/location-channel-group.xml index a9c3b0b1990e8..8c038588f2706 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/location-channel-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/location-channel-group.xml @@ -7,8 +7,7 @@ Coordinates and Heading of the Vehcile - - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/loction-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/loction-channel-types.xml index bac8b5441d712..e49d26256ba40 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/loction-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/loction-channel-types.xml @@ -3,13 +3,9 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - - Number - - - - Number - + + Location + Number:Angle diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index 5d42269f417f3..a234276a698fc 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -33,6 +33,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DecimalType; +import org.openhab.core.library.types.PointType; import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.StringType; import org.openhab.core.library.unit.ImperialUnits; @@ -111,6 +112,7 @@ private void checkResult(ChannelUID channelUID, State state) { StringType wanted; DateTimeType dtt; DecimalType dt; + PointType pt; switch (cUid) { case MILEAGE: assertTrue(state instanceof QuantityType); @@ -250,18 +252,11 @@ private void checkResult(ChannelUID channelUID, State state) { DateTimeType expected = DateTimeType.valueOf(Converter.getLocalDateTime(vStatus.getUpdateTime())); assertEquals(expected.toString(), dtt.toString(), "Last Update"); break; - case LATITUDE: - assertTrue(state instanceof DecimalType); - dt = (DecimalType) state; - assertNotNull(vStatus.position); - assertEquals(Converter.round(vStatus.position.lat), Converter.round(dt.floatValue()), 0.01, "Latitude"); - break; - case LONGITUDE: - assertTrue(state instanceof DecimalType); - dt = (DecimalType) state; + case GPS: + assertTrue(state instanceof PointType); + pt = (PointType) state; assertNotNull(vStatus.position); - assertEquals(Converter.round(vStatus.position.lon), Converter.round(dt.floatValue()), 0.01, - "Longitude"); + assertEquals(vStatus.position.getCoordinates(), pt.toString(), "Coordinates"); break; case HEADING: assertTrue(state instanceof QuantityType); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java index 2619f9dc3d89d..6e6d07e8b877f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java @@ -61,7 +61,7 @@ public class VehicleTests { private static final int CHECK_AVAILABLE = 4; private static final int SERVICE_AVAILABLE = 5; private static final int SERVICE_EMPTY = 5; - private static final int POSITION = 3; + private static final int POSITION = 2; @Nullable ArgumentCaptor channelCaptor; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F15/status.json b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F15/status.json index 6d55f0bfbbd4c..801f41501451e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F15/status.json +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/resources/responses/F15/status.json @@ -58,8 +58,8 @@ "sunroof" : "CLOSED", "position" : { "heading" : 11, - "lon" : -123.123, - "lat" : 123.123, + "lon" : -23.123, + "lat" : 23.123, "status" : "OK" } } From 80001e89d8b03ea633b2279dcff81f322a5ad6aa Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 24 Nov 2020 17:37:41 +0100 Subject: [PATCH 070/176] satisfy null checker Signed-off-by: Bernd --- .../internal/handler/ConnectedDriveProxy.java | 5 +++-- .../OH-INF/thing/bridge-connected-drive.xml | 1 + .../internal/discovery/DiscoveryTest.java | 19 +++++++++++-------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index fae2029dee08a..d19b53f2c3d8a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -246,8 +246,9 @@ public void requestImage(VehicleConfiguration config, ImageProperties props, Byt } private String getRegionServer() { - if (BimmerConstants.SERVER_MAP.containsKey(configuration.region)) { - return BimmerConstants.SERVER_MAP.get(configuration.region); + String retVal = BimmerConstants.SERVER_MAP.get(configuration.region); + if (retVal != null) { + return retVal; } else { return Constants.INVALID; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/bridge-connected-drive.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/bridge-connected-drive.xml index 5bdf4c14c0838..50d9d669fc088 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/bridge-connected-drive.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/bridge-connected-drive.xml @@ -19,6 +19,7 @@ BMW Connected Drive Username + password BMW Connected Drive Password diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java index 3e0102d328d20..60d7b7ceb5867 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java @@ -12,7 +12,7 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.discovery; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; import java.util.List; @@ -57,13 +57,16 @@ public void testDiscovery() { VehiclesContainer container = GSON.fromJson(content, VehiclesContainer.class); ArgumentCaptor discoveries = ArgumentCaptor.forClass(DiscoveryResult.class); ArgumentCaptor services = ArgumentCaptor.forClass(DiscoveryService.class); - - discovery.onResponse(container); - verify(listener, times(1)).thingDiscovered(services.capture(), discoveries.capture()); - List results = discoveries.getAllValues(); - assertEquals(1, results.size(), "Found Vehicles"); - DiscoveryResult result = results.get(0); - assertEquals("bmwconnecteddrive:bev_rex:abc:MY_REAL_VIN", result.getThingUID().getAsString(), "Thing UID"); + if (container != null) { + discovery.onResponse(container); + verify(listener, times(1)).thingDiscovered(services.capture(), discoveries.capture()); + List results = discoveries.getAllValues(); + assertEquals(1, results.size(), "Found Vehicles"); + DiscoveryResult result = results.get(0); + assertEquals("bmwconnecteddrive:bev_rex:abc:MY_REAL_VIN", result.getThingUID().getAsString(), "Thing UID"); + } else { + assertTrue(false); + } } @Test From 974e914074a4296e13f26888e1a8b3adbead5019 Mon Sep 17 00:00:00 2001 From: Bernd Date: Tue, 24 Nov 2020 19:51:11 +0100 Subject: [PATCH 071/176] introduce VehicleStatusUtils Signed-off-by: Bernd --- .../internal/dto/status/VehicleStatus.java | 176 ------------------ .../handler/VehicleChannelHandler.java | 15 +- .../internal/handler/VehicleHandler.java | 4 +- .../internal/utils/VehicleStatusUtils.java | 144 ++++++++++++++ .../thing/destination-channel-types.xml | 2 +- .../internal/dto/StatusWrapper.java | 17 +- 6 files changed, 167 insertions(+), 191 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/VehicleStatusUtils.java diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java index 40b86de4a6579..7168a6ad72d91 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java @@ -12,15 +12,10 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.dto.status; -import static org.openhab.binding.bmwconnecteddrive.internal.utils.Constants.*; - -import java.lang.reflect.Field; -import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; -import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import com.google.gson.annotations.SerializedName; @@ -74,175 +69,4 @@ public class VehicleStatus { public boolean dcsCchOngoing;// ":false public List checkControlMessages = new ArrayList();// ":[], public List cbsData = new ArrayList(); - - /** - * Get Next Service for Date and / or Mileage - * - * @param imperial - * @return - */ - public CBSMessage getNextService() { - CBSMessage cbs = new CBSMessage(); - if (cbsData == null) { - return cbs; - } - if (cbsData.isEmpty()) { - return cbs; - } else { - int serviceMileage = Integer.MAX_VALUE; - LocalDateTime serviceDate = LocalDateTime.now().plusYears(100); - - for (int i = 0; i < cbsData.size(); i++) { - CBSMessage entry = cbsData.get(i); - if (entry.cbsRemainingMileage != 0 && entry.cbsDueDate != null) { - LocalDateTime d = LocalDateTime.parse(entry.cbsDueDate + Constants.UTC_APPENDIX); - // LocalDate d = LocalDate.parse(entry.cbsDueDate + APPENDIX_DAY, - // Converter.SERVICE_DATE_INPUT_PATTERN); - if ((entry.cbsRemainingMileage < serviceMileage) || (d.isBefore(serviceDate))) { - serviceDate = d; - serviceMileage = entry.cbsRemainingMileage; - cbs = entry; - } - } else if (entry.cbsRemainingMileage != 0) { - if (entry.cbsRemainingMileage < serviceMileage) { - serviceMileage = entry.cbsRemainingMileage; - cbs = entry; - } - } else if (entry.cbsDueDate != null) { - LocalDateTime d = LocalDateTime.parse(entry.cbsDueDate + Constants.UTC_APPENDIX); - // LocalDate d = LocalDate.parse(entry.cbsDueDate + APPENDIX_DAY, - // Converter.SERVICE_DATE_INPUT_PATTERN); - if (d.isBefore(serviceDate)) { - serviceDate = d; - cbs = entry; - } - } - } - } - return cbs; - } - - public String getNextServiceDate() { - if (cbsData == null) { - return Constants.NULL_DATE; - } - if (cbsData.isEmpty()) { - return Constants.NULL_DATE; - } else { - LocalDateTime farFuture = LocalDateTime.now().plusYears(100); - LocalDateTime serviceDate = farFuture; - for (int i = 0; i < cbsData.size(); i++) { - CBSMessage entry = cbsData.get(i); - if (entry.cbsDueDate != null) { - LocalDateTime d = LocalDateTime.parse(entry.cbsDueDate + Constants.UTC_APPENDIX); - // LocalDate d = LocalDate.parse(entry.cbsDueDate + APPENDIX_DAY, - // Converter.SERVICE_DATE_INPUT_PATTERN); - if (d.isBefore(serviceDate)) { - serviceDate = d; - } - } - } - if (serviceDate.equals(farFuture)) { - return Constants.NULL_DATE; - } else { - return serviceDate.format(Converter.DATE_INPUT_PATTERN); - } - } - } - - public int getNextServiceMileage() { - if (cbsData == null) { - return -1; - } - if (cbsData.isEmpty()) { - return -1; - } else { - int serviceMileage = Integer.MAX_VALUE; - for (int i = 0; i < cbsData.size(); i++) { - CBSMessage entry = cbsData.get(i); - if (entry.cbsRemainingMileage != -1) { - if (entry.cbsRemainingMileage < serviceMileage) { - serviceMileage = entry.cbsRemainingMileage; - } - } - } - if (serviceMileage != Integer.MAX_VALUE) { - return serviceMileage; - } else { - return -1; - } - } - } - - public String checkControlActive() { - if (checkControlMessages == null) { - return UNKNOWN; - } - if (checkControlMessages.isEmpty()) { - return NOT_ACTIVE; - } else { - return ACTIVE; - } - } - - public String getCheckControl() { - if (checkControlMessages == null) { - return Converter.toTitleCase(UNKNOWN); - } - if (checkControlMessages.isEmpty()) { - return OK; - } else { - return Converter.toTitleCase(checkControlMessages.get(0).ccmDescriptionShort); - } - } - - public String getUpdateTime() { - if (internalDataTimeUTC != null) { - return internalDataTimeUTC; - } else if (updateTime != null) { - return updateTime; - } else { - return Constants.NULL_DATE; - } - } - - /** - * Check for certain Windows or Doors DTO object the "Closed" Status - * INVALID values will be ignored - * - * @param dto - * @return Closed if all "Closed", "Open" otherwise - */ - public static String checkClosed(Object dto) { - String overallState = Constants.UNKNOWN; - for (Field field : dto.getClass().getDeclaredFields()) { - try { - Object d = field.get(dto); - if (d != null) { - String state = d.toString(); - // skip invalid entries - they don't apply to this Vehicle - if (!state.equalsIgnoreCase(INVALID)) { - if (state.equalsIgnoreCase(OPEN)) { - overallState = OPEN; - // stop searching for more open items - overall Doors / Windows are OPEN - break; - } else if (state.equalsIgnoreCase(INTERMEDIATE)) { - if (!overallState.equalsIgnoreCase(OPEN)) { - overallState = INTERMEDIATE; - // continue searching - maybe another Door / Window is OPEN - } - } else if (state.equalsIgnoreCase(CLOSED)) { - // at least one valid object needs to be found in order to reply "CLOSED" - if (overallState.equalsIgnoreCase(UNKNOWN)) { - overallState = CLOSED; - } - } - } - } - } catch (IllegalArgumentException | IllegalAccessException e) { - return UNKNOWN; - } - } - return overallState; - } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 61049eb500ab5..b5eeb3edef0a5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -35,6 +35,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Windows; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; +import org.openhab.binding.bmwconnecteddrive.internal.utils.VehicleStatusUtils; import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; @@ -517,9 +518,9 @@ protected void updateVehicleStatus(VehicleStatus vStatus) { updateState(lock, StringType.valueOf(Converter.toTitleCase(vStatus.doorLockState))); // Service Updates - String nextServiceDate = vStatus.getNextServiceDate(); + String nextServiceDate = VehicleStatusUtils.getNextServiceDate(vStatus); updateState(serviceNextDate, DateTimeType.valueOf(Converter.getLocalDateTime(nextServiceDate))); - double nextServiceMileage = vStatus.getNextServiceMileage(); + double nextServiceMileage = VehicleStatusUtils.getNextServiceMileage(vStatus); if (imperial) { updateState(serviceNextMileage, QuantityType.valueOf(Converter.round(nextServiceMileage), ImperialUnits.MILE)); @@ -528,14 +529,16 @@ protected void updateVehicleStatus(VehicleStatus vStatus) { QuantityType.valueOf(Converter.round(nextServiceMileage), MetricPrefix.KILO(SIUnits.METRE))); } // CheckControl Active? - updateState(checkControl, StringType.valueOf(Converter.toTitleCase(vStatus.checkControlActive()))); + updateState(checkControl, + StringType.valueOf(Converter.toTitleCase(VehicleStatusUtils.checkControlActive(vStatus)))); // last update Time - updateState(lastUpdate, DateTimeType.valueOf(Converter.getLocalDateTime(vStatus.getUpdateTime()))); + updateState(lastUpdate, + DateTimeType.valueOf(Converter.getLocalDateTime(VehicleStatusUtils.getUpdateTime(vStatus)))); Doors doorState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Doors.class); Windows windowState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Windows.class); - updateState(doors, StringType.valueOf(VehicleStatus.checkClosed(doorState))); - updateState(windows, StringType.valueOf(VehicleStatus.checkClosed(windowState))); + updateState(doors, StringType.valueOf(VehicleStatusUtils.checkClosed(doorState))); + updateState(windows, StringType.valueOf(VehicleStatusUtils.checkClosed(windowState))); updateDoors(doorState); updateWindows(windowState); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index ef80cdf0699c3..71778a8f14232 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -445,7 +445,9 @@ public void onResponse(Optional content) { chargeProfileCache = content; if (content.isPresent()) { ChargeProfile cp = Converter.getGson().fromJson(content.get(), ChargeProfile.class); - updateChargeProfile(cp); + if (cp != null) { + updateChargeProfile(cp); + } } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/VehicleStatusUtils.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/VehicleStatusUtils.java new file mode 100644 index 0000000000000..d0d45b6af7107 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/VehicleStatusUtils.java @@ -0,0 +1,144 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.utils; + +import static org.openhab.binding.bmwconnecteddrive.internal.utils.Constants.*; + +import java.lang.reflect.Field; +import java.time.LocalDateTime; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.CBSMessage; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; + +/** + * The {@link VehicleStatusUtils} Data Transfer Object + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class VehicleStatusUtils { + + public static String getNextServiceDate(VehicleStatus vStatus) { + if (vStatus.cbsData == null) { + return Constants.NULL_DATE; + } + if (vStatus.cbsData.isEmpty()) { + return Constants.NULL_DATE; + } else { + LocalDateTime farFuture = LocalDateTime.now().plusYears(100); + LocalDateTime serviceDate = farFuture; + for (int i = 0; i < vStatus.cbsData.size(); i++) { + CBSMessage entry = vStatus.cbsData.get(i); + if (entry.cbsDueDate != null) { + LocalDateTime d = LocalDateTime.parse(entry.cbsDueDate + Constants.UTC_APPENDIX); + // LocalDate d = LocalDate.parse(entry.cbsDueDate + APPENDIX_DAY, + // Converter.SERVICE_DATE_INPUT_PATTERN); + if (d.isBefore(serviceDate)) { + serviceDate = d; + } + } + } + if (serviceDate.equals(farFuture)) { + return Constants.NULL_DATE; + } else { + return serviceDate.format(Converter.DATE_INPUT_PATTERN); + } + } + } + + public static int getNextServiceMileage(VehicleStatus vStatus) { + if (vStatus.cbsData == null) { + return -1; + } + if (vStatus.cbsData.isEmpty()) { + return -1; + } else { + int serviceMileage = Integer.MAX_VALUE; + for (int i = 0; i < vStatus.cbsData.size(); i++) { + CBSMessage entry = vStatus.cbsData.get(i); + if (entry.cbsRemainingMileage != -1) { + if (entry.cbsRemainingMileage < serviceMileage) { + serviceMileage = entry.cbsRemainingMileage; + } + } + } + if (serviceMileage != Integer.MAX_VALUE) { + return serviceMileage; + } else { + return -1; + } + } + } + + public static String checkControlActive(VehicleStatus vStatus) { + if (vStatus.checkControlMessages == null) { + return UNKNOWN; + } + if (vStatus.checkControlMessages.isEmpty()) { + return NOT_ACTIVE; + } else { + return ACTIVE; + } + } + + public static String getUpdateTime(VehicleStatus vStatus) { + if (vStatus.internalDataTimeUTC != null) { + return vStatus.internalDataTimeUTC; + } else if (vStatus.updateTime != null) { + return vStatus.updateTime; + } else { + return Constants.NULL_DATE; + } + } + + /** + * Check for certain Windows or Doors DTO object the "Closed" Status + * INVALID values will be ignored + * + * @param dto + * @return Closed if all "Closed", "Open" otherwise + */ + public static String checkClosed(Object dto) { + String overallState = Constants.UNKNOWN; + for (Field field : dto.getClass().getDeclaredFields()) { + try { + Object d = field.get(dto); + if (d != null) { + String state = d.toString(); + // skip invalid entries - they don't apply to this Vehicle + if (!state.equalsIgnoreCase(INVALID)) { + if (state.equalsIgnoreCase(OPEN)) { + overallState = OPEN; + // stop searching for more open items - overall Doors / Windows are OPEN + break; + } else if (state.equalsIgnoreCase(INTERMEDIATE)) { + if (!overallState.equalsIgnoreCase(OPEN)) { + overallState = INTERMEDIATE; + // continue searching - maybe another Door / Window is OPEN + } + } else if (state.equalsIgnoreCase(CLOSED)) { + // at least one valid object needs to be found in order to reply "CLOSED" + if (overallState.equalsIgnoreCase(UNKNOWN)) { + overallState = CLOSED; + } + } + } + } + } catch (IllegalArgumentException | IllegalAccessException e) { + return UNKNOWN; + } + } + return overallState; + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-channel-types.xml index 618dbcf061377..a9d900f3a5995 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-channel-types.xml @@ -12,7 +12,7 @@ - String + Number diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index a234276a698fc..2a005632f60bc 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -31,6 +31,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Windows; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; +import org.openhab.binding.bmwconnecteddrive.internal.utils.VehicleStatusUtils; import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.PointType; @@ -215,7 +216,7 @@ private void checkResult(ChannelUID channelUID, State state) { assertTrue(state instanceof StringType); st = (StringType) state; Doors doorState = GSON.fromJson(GSON.toJson(vStatus), Doors.class); - assertEquals(VehicleStatus.checkClosed(doorState), st.toString(), "Doors Closed"); + assertEquals(VehicleStatusUtils.checkClosed(doorState), st.toString(), "Doors Closed"); break; case WINDOWS: assertTrue(state instanceof StringType); @@ -224,7 +225,7 @@ private void checkResult(ChannelUID channelUID, State state) { if (specialHandlingMap.containsKey(WINDOWS)) { assertEquals(specialHandlingMap.get(WINDOWS).toString(), st.toString(), "Windows"); } else { - assertEquals(VehicleStatus.checkClosed(windowState), st.toString(), "Windows"); + assertEquals(VehicleStatusUtils.checkClosed(windowState), st.toString(), "Windows"); } break; case CHECK_CONTROL: @@ -233,7 +234,8 @@ private void checkResult(ChannelUID channelUID, State state) { if (specialHandlingMap.containsKey(CHECK_CONTROL)) { assertEquals(specialHandlingMap.get(CHECK_CONTROL).toString(), st.toString(), "Check Control"); } else { - assertEquals(Converter.toTitleCase(vStatus.checkControlActive()), st.toString(), "Check Control"); + assertEquals(Converter.toTitleCase(VehicleStatusUtils.checkControlActive(vStatus)), st.toString(), + "Check Control"); } break; case CHARGE_STATUS: @@ -249,7 +251,8 @@ private void checkResult(ChannelUID channelUID, State state) { case LAST_UPDATE: assertTrue(state instanceof DateTimeType); dtt = (DateTimeType) state; - DateTimeType expected = DateTimeType.valueOf(Converter.getLocalDateTime(vStatus.getUpdateTime())); + DateTimeType expected = DateTimeType + .valueOf(Converter.getLocalDateTime(VehicleStatusUtils.getUpdateTime(vStatus))); assertEquals(expected.toString(), dtt.toString(), "Last Update"); break; case GPS: @@ -422,7 +425,7 @@ private void checkResult(ChannelUID channelUID, State state) { if (specialHandlingMap.containsKey(SERVICE_DATE)) { assertEquals(specialHandlingMap.get(SERVICE_DATE).toString(), dtt.toString(), "Next Service"); } else { - String dueDateString = vStatus.getNextServiceDate(); + String dueDateString = VehicleStatusUtils.getNextServiceDate(vStatus); DateTimeType expectedDTT = DateTimeType.valueOf(Converter.getLocalDateTime(dueDateString)); assertEquals(expectedDTT.toString(), dtt.toString(), "Next Service"); } @@ -438,10 +441,10 @@ private void checkResult(ChannelUID channelUID, State state) { if (gUid.contentEquals(CHANNEL_GROUP_STATUS)) { if (imperial) { assertEquals(ImperialUnits.MILE, qt.getUnit(), "Next Service Miles"); - assertEquals(vStatus.getNextServiceMileage(), qt.intValue(), "Mileage"); + assertEquals(VehicleStatusUtils.getNextServiceMileage(vStatus), qt.intValue(), "Mileage"); } else { assertEquals(KILOMETRE, qt.getUnit(), "Next Service KM"); - assertEquals(vStatus.getNextServiceMileage(), qt.intValue(), "Mileage"); + assertEquals(VehicleStatusUtils.getNextServiceMileage(vStatus), qt.intValue(), "Mileage"); } } else if (gUid.equals(CHANNEL_GROUP_SERVICE)) { if (imperial) { From c483c85a6694858cd7e8f495bc6032f36c8cf628 Mon Sep 17 00:00:00 2001 From: Bernd Date: Thu, 24 Dec 2020 14:49:55 +0100 Subject: [PATCH 072/176] introduce ThingHandlerService Signed-off-by: Bernd --- .../ConnectedDriveHandlerFactory.java | 3 +- .../internal/discovery/VehicleDiscovery.java | 60 +++++++++++++++---- .../handler/ConnectedDriveBridgeHandler.java | 24 ++++---- .../handler/VehicleChannelHandler.java | 12 ++-- .../internal/discovery/DiscoveryTest.java | 22 ++++--- .../internal/dto/StatusWrapper.java | 18 ++++-- 6 files changed, 99 insertions(+), 40 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java index c947bf6a1a8a8..2651a0f2bd748 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java @@ -75,8 +75,7 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { @Override protected void removeHandler(ThingHandler thingHandler) { if (thingHandler instanceof ConnectedDriveBridgeHandler) { - // close Handler and remove Discovery Service - ((ConnectedDriveBridgeHandler) thingHandler).close(); + // nothing to cleanup } else { VEHICLE_HANDLER_REGISTRY.remove(thingHandler); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java index 64d2e2832c9e0..a5893e2f12e99 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java @@ -21,6 +21,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveHandlerFactory; import org.openhab.binding.bmwconnecteddrive.internal.dto.discovery.Vehicle; @@ -32,8 +33,11 @@ import org.openhab.core.config.core.Configuration; import org.openhab.core.config.discovery.AbstractDiscoveryService; import org.openhab.core.config.discovery.DiscoveryResultBuilder; +import org.openhab.core.config.discovery.DiscoveryService; import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingUID; +import org.openhab.core.thing.binding.ThingHandler; +import org.openhab.core.thing.binding.ThingHandlerService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,21 +47,14 @@ * @author Bernd Weymann - Initial contribution */ @NonNullByDefault -// @Component(service = DiscoveryService.class, immediate = true, configurationPid = "discovery.bmwconnecteddrive") -public class VehicleDiscovery extends AbstractDiscoveryService { +public class VehicleDiscovery extends AbstractDiscoveryService implements DiscoveryService, ThingHandlerService { private final Logger logger = LoggerFactory.getLogger(VehicleDiscovery.class); private static final int DISCOVERY_TIMEOUT = 10; - private ConnectedDriveBridgeHandler bridgeHandler; + private @Nullable ConnectedDriveBridgeHandler bridgeHandler; - public VehicleDiscovery(ConnectedDriveBridgeHandler bh) { + public VehicleDiscovery() { super(SUPPORTED_THING_SET, DISCOVERY_TIMEOUT, false); - bridgeHandler = bh; - } - - @Override - protected void startScan() { - bridgeHandler.requestVehicles(); } public void onResponse(VehiclesContainer container) { @@ -175,4 +172,47 @@ public String getObject(Object dto, String compare) { } return buf.toString(); } + + @Override + public void setThingHandler(ThingHandler handler) { + if (handler instanceof ConnectedDriveBridgeHandler) { + bridgeHandler = (ConnectedDriveBridgeHandler) handler; + bridgeHandler.setDiscoveryService(this); + } + } + + @Override + public @Nullable ThingHandler getThingHandler() { + return bridgeHandler; + } + + @Override + public int getScanTimeout() { + return DISCOVERY_TIMEOUT; + } + + @Override + public boolean isBackgroundDiscoveryEnabled() { + return false; + } + + @Override + protected void startScan() { + bridgeHandler.requestVehicles(); + } + + @Override + public void abortScan() { + // nothing to abort + } + + @Override + public void activate() { + super.activate(null); + } + + @Override + public void deactivate() { + super.deactivate(); + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java index 716acfffccec0..9dac337a7d95f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java @@ -14,12 +14,14 @@ import static org.openhab.binding.bmwconnecteddrive.internal.utils.Constants.ANONYMOUS; -import java.util.Hashtable; +import java.util.Collection; +import java.util.Collections; import java.util.Optional; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConfiguration; import org.openhab.binding.bmwconnecteddrive.internal.discovery.VehicleDiscovery; import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; @@ -27,7 +29,6 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.discovery.VehiclesContainer; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; -import org.openhab.core.config.discovery.DiscoveryService; import org.openhab.core.io.net.http.HttpClientFactory; import org.openhab.core.library.types.OnOffType; import org.openhab.core.thing.Bridge; @@ -35,9 +36,9 @@ import org.openhab.core.thing.ThingStatus; import org.openhab.core.thing.ThingStatusDetail; import org.openhab.core.thing.binding.BaseBridgeHandler; +import org.openhab.core.thing.binding.ThingHandlerService; import org.openhab.core.types.Command; import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceRegistration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,10 +51,8 @@ @NonNullByDefault public class ConnectedDriveBridgeHandler extends BaseBridgeHandler implements StringResponseCallback { private final Logger logger = LoggerFactory.getLogger(ConnectedDriveBridgeHandler.class); + private @Nullable VehicleDiscovery discoveryService; private HttpClientFactory httpClientFactory; - private BundleContext bundleContext; - private VehicleDiscovery discoveryService; - private ServiceRegistration discoveryServiceRegstration; private Optional proxy = Optional.empty(); private Optional configuration = Optional.empty(); private Optional> initializerJob = Optional.empty(); @@ -65,10 +64,6 @@ public class ConnectedDriveBridgeHandler extends BaseBridgeHandler implements St public ConnectedDriveBridgeHandler(Bridge bridge, HttpClientFactory hcf, BundleContext bc) { super(bridge); httpClientFactory = hcf; - bundleContext = bc; - discoveryService = new VehicleDiscovery(this); - discoveryServiceRegstration = bundleContext.registerService(DiscoveryService.class.getName(), discoveryService, - new Hashtable<>()); discoveryFingerprintChannel = new ChannelUID(bridge.getUID(), DISCOVERY_FINGERPRINT); } @@ -182,11 +177,16 @@ public void onError(NetworkError error) { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, error.reason); } + @Override + public Collection> getServices() { + return Collections.singleton(VehicleDiscovery.class); + } + public Optional getProxy() { return proxy; } - public void close() { - discoveryServiceRegstration.unregister(); + public void setDiscoveryService(VehicleDiscovery discoveryService) { + this.discoveryService = discoveryService; } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index b5eeb3edef0a5..5d6b3e4a80755 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -537,10 +537,14 @@ protected void updateVehicleStatus(VehicleStatus vStatus) { Doors doorState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Doors.class); Windows windowState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Windows.class); - updateState(doors, StringType.valueOf(VehicleStatusUtils.checkClosed(doorState))); - updateState(windows, StringType.valueOf(VehicleStatusUtils.checkClosed(windowState))); - updateDoors(doorState); - updateWindows(windowState); + if (doorState != null) { + updateState(doors, StringType.valueOf(VehicleStatusUtils.checkClosed(doorState))); + updateDoors(doorState); + } + if (windowState != null) { + updateState(windows, StringType.valueOf(VehicleStatusUtils.checkClosed(windowState))); + updateWindows(windowState); + } // Range values // based on unit of length decide if range shall be reported in km or miles diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java index 60d7b7ceb5867..679a9bb6cce0f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java @@ -51,7 +51,8 @@ public void testDiscovery() { Bridge b = mock(Bridge.class); when(bh.getThing()).thenReturn(b); when(b.getUID()).thenReturn(new ThingUID("bmwconnecteddrive", "account", "abc")); - VehicleDiscovery discovery = new VehicleDiscovery(bh); + VehicleDiscovery discovery = new VehicleDiscovery(); + discovery.setThingHandler(bh); DiscoveryListener listener = mock(DiscoveryListener.class); discovery.addDiscoveryListener(listener); VehiclesContainer container = GSON.fromJson(content, VehiclesContainer.class); @@ -76,18 +77,23 @@ public void testBimmerDiscovery() { Bridge b = mock(Bridge.class); when(bh.getThing()).thenReturn(b); when(b.getUID()).thenReturn(new ThingUID("bmwconnecteddrive", "account", "abc")); - VehicleDiscovery discovery = new VehicleDiscovery(bh); + VehicleDiscovery discovery = new VehicleDiscovery(); + discovery.setThingHandler(bh); DiscoveryListener listener = mock(DiscoveryListener.class); discovery.addDiscoveryListener(listener); VehiclesContainer container = GSON.fromJson(content, VehiclesContainer.class); ArgumentCaptor discoveries = ArgumentCaptor.forClass(DiscoveryResult.class); ArgumentCaptor services = ArgumentCaptor.forClass(DiscoveryService.class); - discovery.onResponse(container); - verify(listener, times(DISCOVERY_VEHICLES)).thingDiscovered(services.capture(), discoveries.capture()); - List results = discoveries.getAllValues(); - results.forEach(entry -> { - logger.info("{}", entry.toString()); - }); + if (container != null) { + discovery.onResponse(container); + verify(listener, times(DISCOVERY_VEHICLES)).thingDiscovered(services.capture(), discoveries.capture()); + List results = discoveries.getAllValues(); + results.forEach(entry -> { + logger.info("{}", entry.toString()); + }); + } else { + assertTrue(false); + } } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index 2a005632f60bc..c599062e57e45 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -216,17 +216,27 @@ private void checkResult(ChannelUID channelUID, State state) { assertTrue(state instanceof StringType); st = (StringType) state; Doors doorState = GSON.fromJson(GSON.toJson(vStatus), Doors.class); - assertEquals(VehicleStatusUtils.checkClosed(doorState), st.toString(), "Doors Closed"); + if (doorState != null) { + assertEquals(VehicleStatusUtils.checkClosed(doorState), st.toString(), "Doors Closed"); + } else { + assertTrue(false); + } + break; case WINDOWS: assertTrue(state instanceof StringType); st = (StringType) state; Windows windowState = GSON.fromJson(GSON.toJson(vStatus), Windows.class); - if (specialHandlingMap.containsKey(WINDOWS)) { - assertEquals(specialHandlingMap.get(WINDOWS).toString(), st.toString(), "Windows"); + if (windowState != null) { + if (specialHandlingMap.containsKey(WINDOWS)) { + assertEquals(specialHandlingMap.get(WINDOWS).toString(), st.toString(), "Windows"); + } else { + assertEquals(VehicleStatusUtils.checkClosed(windowState), st.toString(), "Windows"); + } } else { - assertEquals(VehicleStatusUtils.checkClosed(windowState), st.toString(), "Windows"); + assertTrue(false); } + break; case CHECK_CONTROL: assertTrue(state instanceof StringType); From bb64ada314e3bf8f4b29426337c717af3431e334 Mon Sep 17 00:00:00 2001 From: Bernd Date: Thu, 24 Dec 2020 16:05:23 +0100 Subject: [PATCH 073/176] update Units import Signed-off-by: Bernd --- .../handler/VehicleChannelHandler.java | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 5d6b3e4a80755..c9a1a6c788092 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -45,7 +45,7 @@ import org.openhab.core.library.unit.ImperialUnits; import org.openhab.core.library.unit.MetricPrefix; import org.openhab.core.library.unit.SIUnits; -import org.openhab.core.library.unit.SmartHomeUnits; +import org.openhab.core.library.unit.Units; import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.Thing; import org.openhab.core.thing.binding.BaseThingHandler; @@ -442,11 +442,11 @@ protected void updateAllTrips(AllTrips allTrips) { updateState(lifeTimeSingleLongestDistance, QuantityType .valueOf(Converter.round(allTrips.chargecycleRange.userHigh), MetricPrefix.KILO(SIUnits.METRE))); updateState(lifeTimeAverageConsumption, QuantityType - .valueOf(Converter.round(allTrips.avgElectricConsumption.userAverage), SmartHomeUnits.KILOWATT_HOUR)); + .valueOf(Converter.round(allTrips.avgElectricConsumption.userAverage), Units.KILOWATT_HOUR)); updateState(lifetimeAvgCombinedConsumption, - QuantityType.valueOf(allTrips.avgCombinedConsumption.userAverage, SmartHomeUnits.LITRE)); - updateState(lifeTimeAverageRecuperation, QuantityType - .valueOf(Converter.round(allTrips.avgRecuperation.userAverage), SmartHomeUnits.KILOWATT_HOUR)); + QuantityType.valueOf(allTrips.avgCombinedConsumption.userAverage, Units.LITRE)); + updateState(lifeTimeAverageRecuperation, + QuantityType.valueOf(Converter.round(allTrips.avgRecuperation.userAverage), Units.KILOWATT_HOUR)); updateState(tripDistanceSinceCharging, QuantityType.valueOf( Converter.round(allTrips.chargecycleRange.userCurrentChargeCycle), MetricPrefix.KILO(SIUnits.METRE))); } @@ -454,15 +454,14 @@ protected void updateAllTrips(AllTrips allTrips) { protected void updateLastTrip(LastTrip trip) { // Whyever the Last Trip DateTime is delivered without offest - so LocalTime updateState(tripDateTime, DateTimeType.valueOf(Converter.getLocalDateTimeWithoutOffest(trip.date))); - updateState(tripDuration, QuantityType.valueOf(trip.duration, SmartHomeUnits.MINUTE)); + updateState(tripDuration, QuantityType.valueOf(trip.duration, Units.MINUTE)); updateState(tripDistance, QuantityType.valueOf(Converter.round(trip.totalDistance), MetricPrefix.KILO(SIUnits.METRE))); updateState(tripAvgConsumption, - QuantityType.valueOf(Converter.round(trip.avgElectricConsumption), SmartHomeUnits.KILOWATT_HOUR)); - updateState(tripAvgCombinedConsumption, - QuantityType.valueOf(trip.avgCombinedConsumption, SmartHomeUnits.LITRE)); + QuantityType.valueOf(Converter.round(trip.avgElectricConsumption), Units.KILOWATT_HOUR)); + updateState(tripAvgCombinedConsumption, QuantityType.valueOf(trip.avgCombinedConsumption, Units.LITRE)); updateState(tripAvgRecuperation, - QuantityType.valueOf(Converter.round(trip.avgRecuperation), SmartHomeUnits.KILOWATT_HOUR)); + QuantityType.valueOf(Converter.round(trip.avgRecuperation), Units.KILOWATT_HOUR)); } protected void updateChargeProfile(ChargeProfile cp) { @@ -510,7 +509,7 @@ protected void updateWindows(Windows windowState) { protected void updatePosition(Position pos) { updateState(gpsLocation, PointType.valueOf(pos.getCoordinates())); - updateState(heading, QuantityType.valueOf(pos.heading, SmartHomeUnits.DEGREE_ANGLE)); + updateState(heading, QuantityType.valueOf(pos.heading, Units.DEGREE_ANGLE)); } protected void updateVehicleStatus(VehicleStatus vStatus) { @@ -596,10 +595,10 @@ protected void updateVehicleStatus(VehicleStatus vStatus) { } } if (isElectric) { - updateState(remainingSoc, QuantityType.valueOf(vStatus.chargingLevelHv, SmartHomeUnits.PERCENT)); + updateState(remainingSoc, QuantityType.valueOf(vStatus.chargingLevelHv, Units.PERCENT)); } if (hasFuel) { - updateState(remainingFuel, QuantityType.valueOf(vStatus.remainingFuel, SmartHomeUnits.LITRE)); + updateState(remainingFuel, QuantityType.valueOf(vStatus.remainingFuel, Units.LITRE)); } // Charge Values From d523ec52b34c854e519e72345e0bdab4e0ee585d Mon Sep 17 00:00:00 2001 From: Bernd Date: Thu, 24 Dec 2020 16:08:27 +0100 Subject: [PATCH 074/176] update Units import Signed-off-by: Bernd --- .../internal/dto/LifetimeWrapper.java | 8 ++++---- .../bmwconnecteddrive/internal/dto/StatusWrapper.java | 8 ++++---- .../bmwconnecteddrive/internal/dto/TripWrapper.java | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java index 6991a5b29b69a..4e2c85c752636 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java @@ -33,7 +33,7 @@ import org.openhab.core.library.types.StringType; import org.openhab.core.library.unit.MetricPrefix; import org.openhab.core.library.unit.SIUnits; -import org.openhab.core.library.unit.SmartHomeUnits; +import org.openhab.core.library.unit.Units; import org.openhab.core.thing.ChannelUID; import org.openhab.core.types.State; @@ -129,21 +129,21 @@ private void checkResult(ChannelUID channelUID, State state) { assertTrue(isElectric, "Is Electric"); assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); - assertEquals(SmartHomeUnits.KILOWATT_HOUR, qt.getUnit(), "kw"); + assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw"); assertEquals(allTrips.avgElectricConsumption.userAverage, qt.floatValue(), 0.1, "Avg Consumption"); break; case AVG_RECUPERATION: assertTrue(isElectric, "Is Electric"); assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); - assertEquals(SmartHomeUnits.KILOWATT_HOUR, qt.getUnit(), "kw"); + assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw"); assertEquals(allTrips.avgRecuperation.userAverage, qt.floatValue(), 0.1, "Avg Recuperation"); break; case AVG_COMBINED_CONSUMPTION: assertTrue(isHybrid, "Is Hybrid"); assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); - assertEquals(SmartHomeUnits.LITRE, qt.getUnit(), "Liter"); + assertEquals(Units.LITRE, qt.getUnit(), "Liter"); assertEquals(allTrips.avgCombinedConsumption.userAverage, qt.floatValue(), 0.01, "Avg Combined Consumption"); break; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index c599062e57e45..c3ce7367ba3e2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -40,7 +40,7 @@ import org.openhab.core.library.unit.ImperialUnits; import org.openhab.core.library.unit.MetricPrefix; import org.openhab.core.library.unit.SIUnits; -import org.openhab.core.library.unit.SmartHomeUnits; +import org.openhab.core.library.unit.Units; import org.openhab.core.thing.ChannelUID; import org.openhab.core.types.State; @@ -195,7 +195,7 @@ private void checkResult(ChannelUID channelUID, State state) { assertTrue(hasFuel, "Has Fuel"); assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); - assertEquals(SmartHomeUnits.LITRE, qt.getUnit(), "Liter Unit"); + assertEquals(Units.LITRE, qt.getUnit(), "Liter Unit"); assertEquals(Converter.round(vStatus.remainingFuel), Converter.round(qt.floatValue()), 0.01, "Fuel Level"); break; @@ -203,7 +203,7 @@ private void checkResult(ChannelUID channelUID, State state) { assertTrue(isElectric, "Is Eelctric"); assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); - assertEquals(SmartHomeUnits.PERCENT, qt.getUnit(), "Percent"); + assertEquals(Units.PERCENT, qt.getUnit(), "Percent"); assertEquals(Converter.round(vStatus.chargingLevelHv), Converter.round(qt.floatValue()), 0.01, "Charge Level"); break; @@ -274,7 +274,7 @@ private void checkResult(ChannelUID channelUID, State state) { case HEADING: assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); - assertEquals(SmartHomeUnits.DEGREE_ANGLE, qt.getUnit(), "Angle Unit"); + assertEquals(Units.DEGREE_ANGLE, qt.getUnit(), "Angle Unit"); assertNotNull(vStatus.position); assertEquals(vStatus.position.heading, qt.intValue(), 0.01, "Heading"); break; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java index e80fe6b7f0926..d2b531dee2bee 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java @@ -34,7 +34,7 @@ import org.openhab.core.library.types.StringType; import org.openhab.core.library.unit.MetricPrefix; import org.openhab.core.library.unit.SIUnits; -import org.openhab.core.library.unit.SmartHomeUnits; +import org.openhab.core.library.unit.Units; import org.openhab.core.thing.ChannelUID; import org.openhab.core.types.State; @@ -116,7 +116,7 @@ private void checkResult(ChannelUID channelUID, State state) { case DURATION: assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); - assertEquals(SmartHomeUnits.MINUTE, qt.getUnit(), "Minute"); + assertEquals(Units.MINUTE, qt.getUnit(), "Minute"); assertEquals(lastTrip.duration, qt.floatValue(), 0.1, "Duration"); break; case DISTANCE: @@ -128,20 +128,20 @@ private void checkResult(ChannelUID channelUID, State state) { case AVG_CONSUMPTION: assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); - assertEquals(SmartHomeUnits.KILOWATT_HOUR, qt.getUnit(), "kw"); + assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw"); assertEquals(lastTrip.avgElectricConsumption, qt.floatValue(), 0.1, "Avg Consumption"); break; case AVG_COMBINED_CONSUMPTION: assertTrue(isHybrid, "Is Hybrid"); assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); - assertEquals(SmartHomeUnits.LITRE, qt.getUnit(), "Liter"); + assertEquals(Units.LITRE, qt.getUnit(), "Liter"); assertEquals(Converter.round(lastTrip.avgCombinedConsumption), qt.floatValue(), 0.01, "Percent"); break; case AVG_RECUPERATION: assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); - assertEquals(SmartHomeUnits.KILOWATT_HOUR, qt.getUnit(), "kw"); + assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw"); assertEquals(lastTrip.avgRecuperation, qt.floatValue(), 0.1, "Avg Recuperation"); break; default: From 8870834f2c0f595272fa6d8784e10dc49b398b33 Mon Sep 17 00:00:00 2001 From: Bernd Date: Thu, 24 Dec 2020 17:10:11 +0100 Subject: [PATCH 075/176] introduce command description for remote services Signed-off-by: Bernd --- .../README.md | 9 +-- .../pom.xml | 2 +- .../internal/ConnectedDriveConstants.java | 1 + .../handler/RemoteServiceHandler.java | 1 - .../handler/VehicleChannelHandler.java | 14 +--- .../internal/handler/VehicleHandler.java | 74 +++++++------------ .../thing/remote-services-channel-group.xml | 7 +- .../thing/remote-services-channel-types.xml | 36 ++++----- 8 files changed, 48 insertions(+), 96 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 71694ce2d3852..a5edb7cfe588e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -308,13 +308,8 @@ State *Executed* is the final State when Execution is finished. | Channel Label | Channel Group ID | Channel ID | Type | |-------------------------|------------------|---------------------|---------| -| Activate Flash Lights | remote | light | Switch | -| Find Vehicle | remote | finder | Switch | -| Lock Doors | remote | lock | Switch | -| Unlock Doors | remote | unlock | Switch | -| Horn Blow | remote | horn | Switch | -| Active Air Conditioning | remote | climate | Switch | -| Service Execution State | remote | state | STring | +| Remote Service Command | remote | command | String | +| Service Execution State | remote | state | String | #### Destinations diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/pom.xml b/bundles/org.openhab.binding.bmwconnecteddrive/pom.xml index f0212290d3d97..36567a62351ea 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/pom.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/pom.xml @@ -7,7 +7,7 @@ org.openhab.addons.bundles org.openhab.addons.reactor.bundles - 3.0.0-SNAPSHOT + 3.1.0-SNAPSHOT org.openhab.binding.bmwconnecteddrive diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 4651069076a2b..03c9f7fde273f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -178,6 +178,7 @@ public String toString() { public static final String REMOTE_SERVICE_DOOR_UNLOCK = "unlock"; public static final String REMOTE_SERVICE_HORN = "horn"; public static final String REMOTE_SERVICE_AIR_CONDITIONING = "climate"; + public static final String REMOTE_SERVICE_COMMAND = "command"; public static final String REMOTE_STATE = "state"; // Troubleshoot diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java index 03c2f9225fc23..3cc5dc7a7c74b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -166,6 +166,5 @@ private void reset() { serviceExecuting = Optional.empty(); counter = 0; } - handler.switchRemoteServicesOff(); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index c9a1a6c788092..5e98d7724ed6e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -140,12 +140,7 @@ public class VehicleChannelHandler extends BaseThingHandler { protected ChannelUID heading; // Remote Services - protected ChannelUID remoteLightChannel; - protected ChannelUID remoteFinderChannel; - protected ChannelUID remoteLockChannel; - protected ChannelUID remoteUnlockChannel; - protected ChannelUID remoteHornChannel; - protected ChannelUID remoteClimateChannel; + protected ChannelUID remoteCommandChannel; protected ChannelUID remoteStateChannel; // Remote Services @@ -283,12 +278,7 @@ public VehicleChannelHandler(Thing thing, String type, boolean imperial) { timer3Enabled = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAYS); timer3Days = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_ENABLED); - remoteLightChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_LIGHT_FLASH); - remoteFinderChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_VEHICLE_FINDER); - remoteLockChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_DOOR_LOCK); - remoteUnlockChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_DOOR_UNLOCK); - remoteHornChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_HORN); - remoteClimateChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_AIR_CONDITIONING); + remoteCommandChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_COMMAND); remoteStateChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_STATE); destinationName = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, NAME); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 71778a8f14232..1359e8d347ad7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -32,7 +32,6 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTripContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; -import org.openhab.binding.bmwconnecteddrive.internal.handler.RemoteServiceHandler.ExecutionState; import org.openhab.binding.bmwconnecteddrive.internal.handler.RemoteServiceHandler.RemoteService; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; @@ -111,40 +110,37 @@ public void handleCommand(ChannelUID channelUID, Command command) { // Check for Channel Group and corresponding Actions if (CHANNEL_GROUP_REMOTE.equals(group)) { // Executing Remote Services - if (command instanceof OnOffType) { - if (command.equals(OnOffType.ON)) { - if (remote.isPresent()) { - switch (channelUID.getIdWithoutGroup()) { - case REMOTE_SERVICE_LIGHT_FLASH: - updateState(remoteLightChannel, - OnOffType.from(remote.get().execute(RemoteService.LIGHT_FLASH))); - break; - case REMOTE_SERVICE_AIR_CONDITIONING: - updateState(remoteClimateChannel, - OnOffType.from(remote.get().execute(RemoteService.AIR_CONDITIONING))); - break; - case REMOTE_SERVICE_DOOR_LOCK: - updateState(remoteLockChannel, - OnOffType.from(remote.get().execute(RemoteService.DOOR_LOCK))); - break; - case REMOTE_SERVICE_DOOR_UNLOCK: - updateState(remoteUnlockChannel, - OnOffType.from(remote.get().execute(RemoteService.DOOR_UNLOCK))); - break; - case REMOTE_SERVICE_HORN: - updateState(remoteHornChannel, - OnOffType.from(remote.get().execute(RemoteService.HORN))); - break; - case REMOTE_SERVICE_VEHICLE_FINDER: - updateState(remoteFinderChannel, - OnOffType.from(remote.get().execute(RemoteService.VEHICLE_FINDER))); - break; - } + if (command instanceof StringType) { + String serviceCommand = ((StringType) command).toFullString(); + if (remote.isPresent()) { + switch (serviceCommand) { + case REMOTE_SERVICE_LIGHT_FLASH: + remote.get().execute(RemoteService.LIGHT_FLASH); + break; + case REMOTE_SERVICE_AIR_CONDITIONING: + remote.get().execute(RemoteService.AIR_CONDITIONING); + break; + case REMOTE_SERVICE_DOOR_LOCK: + remote.get().execute(RemoteService.DOOR_LOCK); + break; + case REMOTE_SERVICE_DOOR_UNLOCK: + remote.get().execute(RemoteService.DOOR_UNLOCK); + break; + case REMOTE_SERVICE_HORN: + remote.get().execute(RemoteService.HORN); + break; + case REMOTE_SERVICE_VEHICLE_FINDER: + remote.get().execute(RemoteService.VEHICLE_FINDER); + break; + default: + logger.info("Remote service execution {} unknown", serviceCommand); + break; } - updateState(vehicleFingerPrint, OnOffType.OFF); } } - } else if (CHANNEL_GROUP_VEHICLE_IMAGE.equals(group)) { + } else if (CHANNEL_GROUP_VEHICLE_IMAGE.equals(group)) + + { // Image Change if (configuration.isPresent()) { if (command instanceof StringType) { @@ -314,7 +310,6 @@ public void initialize() { } // Switch all Remote Service Channels and other Switches Off - switchRemoteServicesOff(); updateState(vehicleFingerPrint, OnOffType.OFF); updateState(serviceNext, OnOffType.OFF); updateState(checkControlNext, OnOffType.OFF); @@ -341,16 +336,6 @@ public void initialize() { } } - public void switchRemoteServicesOff() { - updateState(remoteLightChannel, OnOffType.from(false)); - updateState(remoteFinderChannel, OnOffType.from(false)); - updateState(remoteLockChannel, OnOffType.from(false)); - updateState(remoteUnlockChannel, OnOffType.from(false)); - updateState(remoteHornChannel, OnOffType.from(false)); - updateState(remoteClimateChannel, OnOffType.from(false)); - updateState(remoteStateChannel, OnOffType.from(false)); - } - private void startSchedule(int interval) { if (refreshJob.isPresent()) { if (refreshJob.get().isCancelled()) { @@ -419,9 +404,6 @@ private boolean isSupported(String service) { public void updateRemoteExecutionStatus(String service, String status) { updateState(remoteStateChannel, StringType .valueOf(Converter.toTitleCase(new StringBuilder(service).append(" ").append(status).toString()))); - if (ExecutionState.EXECUTED.toString().equals(status)) { - switchRemoteServicesOff(); - } } public Optional getConfiguration() { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-group.xml index c2596de44800a..b96bce38ad99b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-group.xml @@ -7,12 +7,7 @@ Services can be executed via BMW Server like Door lock/unlock, Air Conditioning and more - - - - - - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-types.xml index 98dafa4ab8b83..dc2b7b99ff6d8 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-types.xml @@ -3,29 +3,19 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - - Switch - - - - Switch - - - - Switch - - - - Switch - - - - Switch - - - - Switch - + + String + + + + + + + + + + + String From 9d9ba93361c70955d3f112f328d6dda7154b9380 Mon Sep 17 00:00:00 2001 From: Bernd Date: Fri, 25 Dec 2020 02:40:50 +0100 Subject: [PATCH 076/176] handle destination list as option list Signed-off-by: Bernd --- .../internal/ConnectedDriveConstants.java | 5 -- .../ConnectedDriveHandlerFactory.java | 9 ++- .../internal/dto/Destination.java | 8 ++ .../BMWConnectedDriveOptionProvider.java | 46 +++++++++++ .../handler/VehicleChannelHandler.java | 79 +++---------------- .../internal/handler/VehicleHandler.java | 75 +++++++----------- .../internal/utils/Constants.java | 2 +- .../thing/destination-channel-types.xml | 12 --- .../OH-INF/thing/destination-group.xml | 3 - .../internal/dto/StatusWrapper.java | 39 --------- .../internal/handler/AllTripTests.java | 5 +- .../internal/handler/ChargeProfileTest.java | 5 +- .../internal/handler/ErrorResponseTest.java | 5 +- .../internal/handler/LastTripTests.java | 5 +- .../internal/handler/VehicleTests.java | 13 ++- 15 files changed, 113 insertions(+), 198 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BMWConnectedDriveOptionProvider.java diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 03c9f7fde273f..0d1d41c9ebbff 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -93,11 +93,6 @@ public String toString() { public static final String CHANNEL_GROUP_DESTINATION = "destination"; public static final String CHANNEL_GROUP_TROUBLESHOOT = "troubleshoot"; - // List Interface Constants - public static final String SIZE = "size"; - public static final String INDEX = "index"; - public static final String NEXT = "next"; - // Generic Constants for several groups public static final String NAME = "name"; public static final String DATE = "date"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java index 2651a0f2bd748..c844b6db11780 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java @@ -19,6 +19,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.bmwconnecteddrive.internal.handler.BMWConnectedDriveOptionProvider; import org.openhab.binding.bmwconnecteddrive.internal.handler.ConnectedDriveBridgeHandler; import org.openhab.binding.bmwconnecteddrive.internal.handler.VehicleHandler; import org.openhab.core.i18n.LocaleProvider; @@ -44,12 +45,15 @@ public class ConnectedDriveHandlerFactory extends BaseThingHandlerFactory { private final HttpClientFactory httpClientFactory; + private final BMWConnectedDriveOptionProvider optionProvider; private static final List VEHICLE_HANDLER_REGISTRY = new ArrayList(); private boolean imperial = false; @Activate - public ConnectedDriveHandlerFactory(final @Reference HttpClientFactory hcf, final @Reference LocaleProvider lp) { + public ConnectedDriveHandlerFactory(final @Reference HttpClientFactory hcf, + final @Reference BMWConnectedDriveOptionProvider op, final @Reference LocaleProvider lp) { httpClientFactory = hcf; + optionProvider = op; imperial = IMPERIAL_COUNTRIES.contains(lp.getLocale().getCountry()); } @@ -64,8 +68,7 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { if (THING_TYPE_CONNECTED_DRIVE_ACCOUNT.equals(thingTypeUID)) { return new ConnectedDriveBridgeHandler((Bridge) thing, httpClientFactory, bundleContext); } else if (SUPPORTED_THING_SET.contains(thingTypeUID)) { - VehicleHandler vh = new VehicleHandler(thing, httpClientFactory.getCommonHttpClient(), thingTypeUID.getId(), - imperial); + VehicleHandler vh = new VehicleHandler(thing, optionProvider, thingTypeUID.getId(), imperial); VEHICLE_HANDLER_REGISTRY.add(vh); return vh; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java index e7421a2ccc5c6..b3ee67ab2715d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java @@ -57,4 +57,12 @@ public String getAddress() { public String getCoordinates() { return new StringBuilder().append(lat).append(Constants.COMMA).append(lon).toString(); } + + public static Destination getUndefined() { + Destination dest = new Destination(); + dest.lat = -1; + dest.lon = -1; + dest.city = "Undefined"; + return dest; + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BMWConnectedDriveOptionProvider.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BMWConnectedDriveOptionProvider.java new file mode 100644 index 0000000000000..885f949878de9 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BMWConnectedDriveOptionProvider.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.handler; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.core.thing.binding.BaseDynamicStateDescriptionProvider; +import org.openhab.core.thing.i18n.ChannelTypeI18nLocalizationService; +import org.openhab.core.thing.type.DynamicStateDescriptionProvider; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Dynamic provider of state options while leaving other state description fields as original. + * + * @author Bernd Weymann - Initial contribution + */ +@Component(service = { DynamicStateDescriptionProvider.class, BMWConnectedDriveOptionProvider.class }) +@NonNullByDefault +public class BMWConnectedDriveOptionProvider extends BaseDynamicStateDescriptionProvider { + protected final Logger logger = LoggerFactory.getLogger(BMWConnectedDriveOptionProvider.class); + + @Reference + protected void setChannelTypeI18nLocalizationService( + final ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) { + logger.info("LocalizationService set"); + this.channelTypeI18nLocalizationService = channelTypeI18nLocalizationService; + } + + protected void unsetChannelTypeI18nLocalizationService( + final ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) { + logger.info("LocalizationService unset"); + this.channelTypeI18nLocalizationService = null; + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 5e98d7724ed6e..1793f43902912 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -37,7 +37,6 @@ import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.openhab.binding.bmwconnecteddrive.internal.utils.VehicleStatusUtils; import org.openhab.core.library.types.DateTimeType; -import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.PointType; import org.openhab.core.library.types.QuantityType; @@ -50,6 +49,8 @@ import org.openhab.core.thing.Thing; import org.openhab.core.thing.binding.BaseThingHandler; import org.openhab.core.types.Command; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The {@link VehicleChannelHandler} is responsible for handling commands, which are @@ -59,18 +60,20 @@ */ @NonNullByDefault public class VehicleChannelHandler extends BaseThingHandler { + protected final Logger logger = LoggerFactory.getLogger(VehicleChannelHandler.class); protected boolean imperial = false; protected boolean hasFuel = false; protected boolean isElectric = false; protected boolean isHybrid = false; // List Interfaces - private List serviceList = new ArrayList(); + protected List serviceList = new ArrayList(); private int serviceListIndex = -1; - private List checkControlList = new ArrayList(); + protected List checkControlList = new ArrayList(); private int checkControlListIndex = -1; - private List destinationList = new ArrayList(); - private int destinationListIndex = -1; + protected List destinationList = new ArrayList(); + + protected BMWConnectedDriveOptionProvider optionProvider; // Vahicle Status Channels protected ChannelUID doors; @@ -84,15 +87,9 @@ public class VehicleChannelHandler extends BaseThingHandler { protected ChannelUID serviceDate; protected ChannelUID serviceMileage; protected ChannelUID serviceName; - protected ChannelUID serviceSize; - protected ChannelUID serviceIndex; - protected ChannelUID serviceNext; protected ChannelUID checkControlMileage; protected ChannelUID checkControlName; - protected ChannelUID checkControlSize; - protected ChannelUID checkControlIndex; - protected ChannelUID checkControlNext; protected ChannelUID doorDriverFront; protected ChannelUID doorDriverRear; @@ -146,9 +143,6 @@ public class VehicleChannelHandler extends BaseThingHandler { // Remote Services protected ChannelUID destinationName; protected ChannelUID destinationLocation; - protected ChannelUID destinationSize; - protected ChannelUID destinationIndex; - protected ChannelUID destinationNext; // Charging protected ChannelUID chargingStatus; @@ -183,8 +177,9 @@ public class VehicleChannelHandler extends BaseThingHandler { protected Optional destinationCache = Optional.empty(); protected Optional imageCache = Optional.empty(); - public VehicleChannelHandler(Thing thing, String type, boolean imperial) { + public VehicleChannelHandler(Thing thing, BMWConnectedDriveOptionProvider op, String type, boolean imperial) { super(thing); + optionProvider = op; this.imperial = imperial; hasFuel = type.equals(VehicleType.CONVENTIONAL.toString()) || type.equals(VehicleType.PLUGIN_HYBRID.toString()) @@ -206,15 +201,9 @@ public VehicleChannelHandler(Thing thing, String type, boolean imperial) { serviceDate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, DATE); serviceMileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, MILEAGE); serviceName = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, NAME); - serviceSize = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, SIZE); - serviceIndex = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, INDEX); - serviceNext = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, NEXT); checkControlMileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHECK_CONTROL, MILEAGE); checkControlName = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHECK_CONTROL, NAME); - checkControlSize = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHECK_CONTROL, SIZE); - checkControlIndex = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHECK_CONTROL, INDEX); - checkControlNext = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHECK_CONTROL, NEXT); doorDriverFront = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, DOOR_DRIVER_FRONT); doorDriverRear = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, DOOR_DRIVER_REAR); @@ -283,9 +272,6 @@ public VehicleChannelHandler(Thing thing, String type, boolean imperial) { destinationName = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, NAME); destinationLocation = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, GPS); - destinationSize = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, SIZE); - destinationIndex = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, INDEX); - destinationNext = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, NEXT); imageChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_FORMAT); imageViewportChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_VIEWPORT); @@ -331,8 +317,6 @@ private void updateCheckControls() { updateState(checkControlMileage, QuantityType.valueOf(Converter.round(entry.ccmMileage), MetricPrefix.KILO(SIUnits.METRE))); } - updateState(checkControlSize, new DecimalType(checkControlList.size())); - updateState(checkControlIndex, new DecimalType(checkControlListIndex)); } else { // list is empty - set all fields to INVALID. If this isn't done the old values remain updateState(checkControlName, StringType.valueOf(Constants.INVALID)); @@ -342,8 +326,6 @@ private void updateCheckControls() { updateState(checkControlMileage, QuantityType.valueOf(Converter.round(-1), MetricPrefix.KILO(SIUnits.METRE))); } - updateState(checkControlSize, new DecimalType(checkControlList.size())); - updateState(checkControlIndex, new DecimalType(-1)); } } @@ -373,8 +355,6 @@ private void updateService() { updateState(serviceMileage, QuantityType.valueOf(Converter.round(entry.cbsRemainingMileage), MetricPrefix.KILO(SIUnits.METRE))); } - updateState(serviceSize, new DecimalType(serviceList.size())); - updateState(serviceIndex, new DecimalType(serviceListIndex)); } else { // list is empty - set all fields to INVALID. If this isn't done the old values remain updateState(serviceName, StringType.valueOf(Constants.INVALID)); @@ -384,48 +364,9 @@ private void updateService() { } else { updateState(serviceMileage, QuantityType.valueOf(-1, MetricPrefix.KILO(SIUnits.METRE))); } - updateState(serviceSize, new DecimalType(serviceList.size())); - updateState(serviceIndex, new DecimalType(-1)); } } - public synchronized void setDestinationList(List l) { - destinationList = l; - updateDestination(); - } - - public synchronized void nextDestination() { - destinationListIndex++; - updateDestination(); - } - - /** - * needs to be synchronized with onResponse update - */ - private void updateDestination() { - if (!destinationList.isEmpty()) { - if (destinationListIndex < 0 || destinationListIndex >= destinationList.size()) { - // select first item - destinationListIndex = 0; - } - Destination entry = destinationList.get(destinationListIndex); - updateState(destinationName, StringType.valueOf(entry.getAddress())); - updateState(destinationLocation, PointType.valueOf(entry.getCoordinates())); - updateState(destinationSize, new DecimalType(destinationList.size())); - updateState(destinationIndex, new DecimalType(destinationListIndex)); - } else { - // list is empty - set all fields to INVALID. If this isn't done the old values remain - updateState(destinationName, StringType.valueOf(Constants.INVALID)); - updateState(destinationLocation, PointType.valueOf("-1,-1")); - updateState(destinationSize, new DecimalType(destinationList.size())); - updateState(destinationIndex, new DecimalType(-1)); - } - } - - /** - * Channel Groups - */ - protected void updateAllTrips(AllTrips allTrips) { updateState(lifeTimeCumulatedDrivenDistance, QuantityType .valueOf(Converter.round(allTrips.totalElectricDistance.userTotal), MetricPrefix.KILO(SIUnits.METRE))); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 1359e8d347ad7..9cbd0a6aace32 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -14,14 +14,16 @@ import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jetty.client.HttpClient; import org.openhab.binding.bmwconnecteddrive.internal.VehicleConfiguration; +import org.openhab.binding.bmwconnecteddrive.internal.dto.Destination; import org.openhab.binding.bmwconnecteddrive.internal.dto.DestinationContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.ChargeProfile; @@ -39,6 +41,7 @@ import org.openhab.core.io.net.http.HttpUtil; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; +import org.openhab.core.library.types.PointType; import org.openhab.core.library.types.RawType; import org.openhab.core.library.types.StringType; import org.openhab.core.thing.Bridge; @@ -49,8 +52,7 @@ import org.openhab.core.thing.binding.BridgeHandler; import org.openhab.core.types.Command; import org.openhab.core.types.RefreshType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.openhab.core.types.StateOption; /** * The {@link VehicleHandler} is responsible for handling commands, which are @@ -60,7 +62,6 @@ */ @NonNullByDefault public class VehicleHandler extends VehicleChannelHandler { - private final Logger logger = LoggerFactory.getLogger(VehicleHandler.class); private boolean legacyMode = false; // switch to legacy API in case of 404 Errors private Optional proxy = Optional.empty(); @@ -70,7 +71,6 @@ public class VehicleHandler extends VehicleChannelHandler { private Optional> refreshJob = Optional.empty(); private ImageProperties imageProperties = new ImageProperties(); - VehicleStatusCallback vehicleStatusCallback = new VehicleStatusCallback(); StringResponseCallback oldVehicleStatusCallback = new LegacyVehicleStatusCallback(); StringResponseCallback lastTripCallback = new LastTripCallback(); @@ -80,8 +80,8 @@ public class VehicleHandler extends VehicleChannelHandler { DestinationsCallback destinationCallback = new DestinationsCallback(); ByteResponseCallback imageCallback = new ImageCallback(); - public VehicleHandler(Thing thing, HttpClient hc, String type, boolean imperial) { - super(thing, type, imperial); + public VehicleHandler(Thing thing, BMWConnectedDriveOptionProvider op, String type, boolean imperial) { + super(thing, op, type, imperial); } @Override @@ -138,9 +138,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { } } } - } else if (CHANNEL_GROUP_VEHICLE_IMAGE.equals(group)) - - { + } else if (CHANNEL_GROUP_VEHICLE_IMAGE.equals(group)) { // Image Change if (configuration.isPresent()) { if (command instanceof StringType) { @@ -172,36 +170,15 @@ public void handleCommand(ChannelUID channelUID, Command command) { } } } - } - if (channelUID.getIdWithoutGroup().equals(NEXT)) { - String gUid = channelUID.getGroupId(); - if (gUid != null) { - switch (gUid) { - case CHANNEL_GROUP_SERVICE: - if (command instanceof OnOffType) { - if (command.equals(OnOffType.ON)) { - nextService(); - updateState(channelUID, OnOffType.OFF); - } - } - break; - case CHANNEL_GROUP_DESTINATION: - if (command instanceof OnOffType) { - if (command.equals(OnOffType.ON)) { - nextDestination(); - updateState(channelUID, OnOffType.OFF); - } - } - break; - case CHANNEL_GROUP_CHECK_CONTROL: - if (command instanceof OnOffType) { - if (command.equals(OnOffType.ON)) { - nextCheckControl(); - updateState(channelUID, OnOffType.OFF); - } - } - break; - } + } else if (CHANNEL_GROUP_DESTINATION.equals(group)) { + // receive new destination location + if (command instanceof StringType) { + destinationList.forEach(entry -> { + if (((StringType) command).toFullString().equals(entry.getAddress())) { + // update coordinates according to new set location + updateState(destinationLocation, PointType.valueOf(entry.getCoordinates())); + } + }); } } if (channelUID.getIdWithoutGroup().equals(VEHICLE_FINGERPRINT)) { @@ -309,12 +286,6 @@ public void initialize() { logger.debug("Bridge null"); } - // Switch all Remote Service Channels and other Switches Off - updateState(vehicleFingerPrint, OnOffType.OFF); - updateState(serviceNext, OnOffType.OFF); - updateState(checkControlNext, OnOffType.OFF); - updateState(destinationNext, OnOffType.OFF); - // get Image after init with config values synchronized (imageProperties) { imageProperties = new ImageProperties(configuration.get().imageViewport, @@ -470,7 +441,17 @@ public void onResponse(Optional content) { DestinationContainer dc = Converter.getGson().fromJson(content.get(), DestinationContainer.class); if (dc.destinations != null) { - setDestinationList(dc.destinations); + destinationList = dc.destinations; + List options = new ArrayList<>(); + if (destinationList.size() == 0) { + destinationList.add(Destination.getUndefined()); + } + destinationList.forEach(destination -> { + options.add(new StateOption(destination.getAddress(), destination.getAddress())); + }); + logger.info("Added {} options to {}", destinationList.size(), destinationName.getAsString()); + logger.info("Options {}", options.toArray()); + optionProvider.setStateOptions(destinationName, options); } } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java index 6c44779ff94ba..6740edc2e5867 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -32,7 +32,7 @@ public class Constants { public static final String INVALID = "INVALID"; public static final String CLOSED = "CLOSED"; public static final String INTERMEDIATE = "INTERMEDIATE"; - public static final String UNKNOWN = "UNKOWN"; + public static final String UNKNOWN = "UNKNOWN"; public static final String NO_SERVICE_REQUEST = "No Service Requests"; public static final String UTC_APPENDIX = "-01T12:00:00"; public static final String NULL_DATE = "1900-01-01T00:00:00"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-channel-types.xml index a9d900f3a5995..94c4ad3f5e479 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-channel-types.xml @@ -11,16 +11,4 @@ Location - - Number - - - - Number - - - - Switch - - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-group.xml index 81a3306b55391..0e4dc95998066 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-group.xml @@ -9,9 +9,6 @@ - - - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index c3ce7367ba3e2..09609d9df3486 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -389,45 +389,6 @@ private void checkResult(ChannelUID channelUID, State state) { wanted = StringType.valueOf(vStatus.sunroof); assertEquals(wanted.toString(), st.toString(), "Window"); break; - case SIZE: - assertTrue(state instanceof DecimalType); - dt = (DecimalType) state; - switch (gUid) { - case CHANNEL_GROUP_CHECK_CONTROL: - assertEquals(vStatus.checkControlMessages.size(), dt.intValue(), - "Number CheckControl Messages"); - break; - case CHANNEL_GROUP_SERVICE: - assertEquals(vStatus.cbsData.size(), dt.intValue(), "Number of Services"); - break; - default: - assertFalse(true, "Channel " + channelUID + " " + state + " not found"); - break; - } - break; - case INDEX: - assertTrue(state instanceof DecimalType); - dt = (DecimalType) state; - switch (gUid) { - case CHANNEL_GROUP_SERVICE: - if (vStatus.cbsData.isEmpty()) { - assertEquals(-1, dt.intValue(), "Index of Services"); - } else { - assertEquals(0, dt.intValue(), "Index of Services"); - } - break; - case CHANNEL_GROUP_CHECK_CONTROL: - if (vStatus.checkControlMessages.isEmpty()) { - assertEquals(-1, dt.intValue(), "Index of CheckControls"); - } else { - assertEquals(0, dt.intValue(), "Index of CheckControls"); - } - break; - default: - assertFalse(true, "Channel " + channelUID + " " + state + " not found"); - break; - } - break; case SERVICE_DATE: assertTrue(state instanceof DateTimeType); dtt = (DateTimeType) state; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AllTripTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AllTripTests.java index ee1a0a2799312..e606a82887934 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AllTripTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AllTripTests.java @@ -21,7 +21,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.jetty.client.HttpClient; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; @@ -71,8 +70,8 @@ public void setup(String type, boolean imperial) { this.imperial = imperial; Thing thing = mock(Thing.class); when(thing.getUID()).thenReturn(new ThingUID("testbinding", "test")); - HttpClient hc = mock(HttpClient.class); - cch = new VehicleHandler(thing, hc, type, imperial); + BMWConnectedDriveOptionProvider op = mock(BMWConnectedDriveOptionProvider.class); + cch = new VehicleHandler(thing, op, type, imperial); tc = mock(ThingHandlerCallback.class); cch.setCallback(tc); channelCaptor = ArgumentCaptor.forClass(ChannelUID.class); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java index 7e49e9da69a45..4abf3b24cc228 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java @@ -20,7 +20,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.jetty.client.HttpClient; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; @@ -69,8 +68,8 @@ public void setup(String type, boolean imperial) { this.imperial = imperial; Thing thing = mock(Thing.class); when(thing.getUID()).thenReturn(new ThingUID("testbinding", "test")); - HttpClient hc = mock(HttpClient.class); - cch = new VehicleHandler(thing, hc, type, imperial); + BMWConnectedDriveOptionProvider op = mock(BMWConnectedDriveOptionProvider.class); + cch = new VehicleHandler(thing, op, type, imperial); tc = mock(ThingHandlerCallback.class); cch.setCallback(tc); channelCaptor = ArgumentCaptor.forClass(ChannelUID.class); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ErrorResponseTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ErrorResponseTest.java index 3186c9852dc86..9c00a2aae42f8 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ErrorResponseTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ErrorResponseTest.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.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.openhab.core.thing.ChannelUID; @@ -64,8 +63,8 @@ public void setup(String type, boolean imperial) { this.imperial = imperial; Thing thing = mock(Thing.class); when(thing.getUID()).thenReturn(new ThingUID("testbinding", "test")); - HttpClient hc = mock(HttpClient.class); - cch = new VehicleHandler(thing, hc, type, imperial); + BMWConnectedDriveOptionProvider op = mock(BMWConnectedDriveOptionProvider.class); + cch = new VehicleHandler(thing, op, type, imperial); tc = mock(ThingHandlerCallback.class); cch.setCallback(tc); channelCaptor = ArgumentCaptor.forClass(ChannelUID.class); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/LastTripTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/LastTripTests.java index d11ecc7851202..2ca6eecf68caf 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/LastTripTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/LastTripTests.java @@ -21,7 +21,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.jetty.client.HttpClient; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; @@ -71,8 +70,8 @@ public void setup(String type, boolean imperial) { this.imperial = imperial; Thing thing = mock(Thing.class); when(thing.getUID()).thenReturn(new ThingUID("testbinding", "test")); - HttpClient hc = mock(HttpClient.class); - cch = new VehicleHandler(thing, hc, type, imperial); + BMWConnectedDriveOptionProvider op = mock(BMWConnectedDriveOptionProvider.class); + cch = new VehicleHandler(thing, op, type, imperial); tc = mock(ThingHandlerCallback.class); cch.setCallback(tc); channelCaptor = ArgumentCaptor.forClass(ChannelUID.class); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java index 6e6d07e8b877f..3e47a3740658e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java @@ -22,7 +22,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.jetty.client.HttpClient; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants; @@ -57,10 +56,10 @@ public class VehicleTests { private static final int RANGE_CONV = 4; private static final int RANGE_ELECTRIC = 4; private static final int DOORS = 12; - private static final int CHECK_EMPTY = 4; - private static final int CHECK_AVAILABLE = 4; - private static final int SERVICE_AVAILABLE = 5; - private static final int SERVICE_EMPTY = 5; + private static final int CHECK_EMPTY = 2; + private static final int CHECK_AVAILABLE = 2; + private static final int SERVICE_AVAILABLE = 3; + private static final int SERVICE_EMPTY = 3; private static final int POSITION = 2; @Nullable @@ -86,8 +85,8 @@ public void setup(String type, boolean imperial) { this.imperial = imperial; Thing thing = mock(Thing.class); when(thing.getUID()).thenReturn(new ThingUID("testbinding", "test")); - HttpClient hc = mock(HttpClient.class); - cch = new VehicleHandler(thing, hc, type, imperial); + BMWConnectedDriveOptionProvider op = mock(BMWConnectedDriveOptionProvider.class); + cch = new VehicleHandler(thing, op, type, imperial); tc = mock(ThingHandlerCallback.class); cch.setCallback(tc); channelCaptor = ArgumentCaptor.forClass(ChannelUID.class); From 257dfee502ed36179b17512ae4f3c7d708e3a44d Mon Sep 17 00:00:00 2001 From: Bernd Date: Fri, 25 Dec 2020 12:22:59 +0100 Subject: [PATCH 077/176] update list item after first call Signed-off-by: Bernd --- .../handler/VehicleChannelHandler.java | 31 +++++++++++++------ .../internal/handler/VehicleHandler.java | 16 +--------- .../OH-INF/thing/service-channel-types.xml | 12 ------- .../resources/OH-INF/thing/service-group.xml | 3 -- 4 files changed, 22 insertions(+), 40 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 1793f43902912..22376c4c1b695 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -49,6 +49,7 @@ import org.openhab.core.thing.Thing; import org.openhab.core.thing.binding.BaseThingHandler; import org.openhab.core.types.Command; +import org.openhab.core.types.StateOption; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -329,16 +330,6 @@ private void updateCheckControls() { } } - public synchronized void nextService() { - serviceListIndex++; - updateService(); - } - - public synchronized void setServiceList(List l) { - serviceList = l; - updateService(); - } - private void updateService() { if (!serviceList.isEmpty()) { if (serviceListIndex < 0 || serviceListIndex >= serviceList.size()) { @@ -367,6 +358,26 @@ private void updateService() { } } + protected void updateDestinations(List dl) { + boolean isFirstUpdate = destinationList.isEmpty(); + destinationList = dl; + List options = new ArrayList<>(); + if (destinationList.size() == 0) { + destinationList.add(Destination.getUndefined()); + } else { + destinationList.forEach(destination -> { + options.add(new StateOption(destination.getAddress(), destination.getAddress())); + }); + } + logger.info("Added {} options to {}", destinationList.size(), destinationName.getAsString()); + logger.info("Options {}", options.toArray()); + optionProvider.setStateOptions(destinationName, options); + if (isFirstUpdate) { + updateState(destinationName, StringType.valueOf(destinationList.get(0).getAddress())); + updateState(destinationLocation, PointType.valueOf(destinationList.get(0).getCoordinates())); + } + } + protected void updateAllTrips(AllTrips allTrips) { updateState(lifeTimeCumulatedDrivenDistance, QuantityType .valueOf(Converter.round(allTrips.totalElectricDistance.userTotal), MetricPrefix.KILO(SIUnits.METRE))); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 9cbd0a6aace32..1af6575af9f84 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -14,8 +14,6 @@ import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; -import java.util.ArrayList; -import java.util.List; import java.util.Optional; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -23,7 +21,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.binding.bmwconnecteddrive.internal.VehicleConfiguration; -import org.openhab.binding.bmwconnecteddrive.internal.dto.Destination; import org.openhab.binding.bmwconnecteddrive.internal.dto.DestinationContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.ChargeProfile; @@ -52,7 +49,6 @@ import org.openhab.core.thing.binding.BridgeHandler; import org.openhab.core.types.Command; import org.openhab.core.types.RefreshType; -import org.openhab.core.types.StateOption; /** * The {@link VehicleHandler} is responsible for handling commands, which are @@ -441,17 +437,7 @@ public void onResponse(Optional content) { DestinationContainer dc = Converter.getGson().fromJson(content.get(), DestinationContainer.class); if (dc.destinations != null) { - destinationList = dc.destinations; - List options = new ArrayList<>(); - if (destinationList.size() == 0) { - destinationList.add(Destination.getUndefined()); - } - destinationList.forEach(destination -> { - options.add(new StateOption(destination.getAddress(), destination.getAddress())); - }); - logger.info("Added {} options to {}", destinationList.size(), destinationName.getAsString()); - logger.info("Options {}", options.toArray()); - optionProvider.setStateOptions(destinationName, options); + updateDestinations(dc.destinations); } } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-channel-types.xml index 07fe8ec5456ad..a2a7c074c84de 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-channel-types.xml @@ -15,16 +15,4 @@ Number:Length - - Number - - - - Number - - - - Switch - - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-group.xml index c560655a98318..30ddcb6c3d2ee 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-group.xml @@ -10,9 +10,6 @@ - - - From 987f6a6caea3b5836aff0f2a8af22641a92d02de Mon Sep 17 00:00:00 2001 From: Bernd Date: Fri, 25 Dec 2020 13:13:45 +0100 Subject: [PATCH 078/176] check if selected item is in updated list Signed-off-by: Bernd --- .../handler/VehicleChannelHandler.java | 71 ++++++++++++++----- .../internal/handler/VehicleHandler.java | 10 +-- .../internal/handler/VehicleTests.java | 4 +- 3 files changed, 56 insertions(+), 29 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 22376c4c1b695..7c2a316660fa9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -69,10 +69,13 @@ public class VehicleChannelHandler extends BaseThingHandler { // List Interfaces protected List serviceList = new ArrayList(); + protected String selectedService = Constants.INVALID; private int serviceListIndex = -1; protected List checkControlList = new ArrayList(); + protected String selectedCC = Constants.INVALID; private int checkControlListIndex = -1; protected List destinationList = new ArrayList(); + protected String selectedDestination = Constants.INVALID; protected BMWConnectedDriveOptionProvider optionProvider; @@ -289,15 +292,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { public void initialize() { } - /** - * Update List Interfaces - */ - - public synchronized void nextCheckControl() { - checkControlListIndex++; - updateService(); - } - public synchronized void setCheckControlList(List l) { checkControlList = l; updateCheckControls(); @@ -330,7 +324,26 @@ private void updateCheckControls() { } } - private void updateService() { + private void updateService(List sl) { + boolean isFirstUpdate = serviceList.isEmpty(); + serviceList = sl; + List options = new ArrayList<>(); + if (destinationList.size() == 0) { + destinationList.add(Destination.getUndefined()); + } + + destinationList.forEach(destination -> { + options.add(new StateOption(destination.getAddress(), destination.getAddress())); + }); + + logger.info("Added {} options to {}", destinationList.size(), destinationName.getAsString()); + logger.info("Options {}", options.toArray()); + optionProvider.setStateOptions(destinationName, options); + if (isFirstUpdate) { + updateState(destinationName, StringType.valueOf(destinationList.get(0).getAddress())); + updateState(destinationLocation, PointType.valueOf(destinationList.get(0).getCoordinates())); + } + if (!serviceList.isEmpty()) { if (serviceListIndex < 0 || serviceListIndex >= serviceList.size()) { // select first item @@ -359,25 +372,45 @@ private void updateService() { } protected void updateDestinations(List dl) { - boolean isFirstUpdate = destinationList.isEmpty(); - destinationList = dl; List options = new ArrayList<>(); - if (destinationList.size() == 0) { - destinationList.add(Destination.getUndefined()); - } else { - destinationList.forEach(destination -> { - options.add(new StateOption(destination.getAddress(), destination.getAddress())); - }); + // if list is empty add "undefined" element + if (dl.size() == 0) { + dl.add(Destination.getUndefined()); } + + // add all elements to options + destinationList = dl; + boolean isSelectedElementIn = false; + for (Destination destination : destinationList) { + options.add(new StateOption(destination.getAddress(), destination.getAddress())); + if (selectedDestination.equals(destination.getAddress())) { + isSelectedElementIn = true; + } + } + logger.info("Added {} options to {}", destinationList.size(), destinationName.getAsString()); logger.info("Options {}", options.toArray()); optionProvider.setStateOptions(destinationName, options); - if (isFirstUpdate) { + + // if current selected item isn't anymore in the list select first entry + if (!isSelectedElementIn) { updateState(destinationName, StringType.valueOf(destinationList.get(0).getAddress())); updateState(destinationLocation, PointType.valueOf(destinationList.get(0).getCoordinates())); } } + protected void selectDestination(String destinationName) { + destinationList.forEach(entry -> { + if (destinationName.equals(entry.getAddress())) { + // update selected Item + selectedDestination = destinationName; + // update coordinates according to new set location + updateState(destinationLocation, PointType.valueOf(entry.getCoordinates())); + return; + } + }); + } + protected void updateAllTrips(AllTrips allTrips) { updateState(lifeTimeCumulatedDrivenDistance, QuantityType .valueOf(Converter.round(allTrips.totalElectricDistance.userTotal), MetricPrefix.KILO(SIUnits.METRE))); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 1af6575af9f84..458093e9c8d93 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -38,7 +38,6 @@ import org.openhab.core.io.net.http.HttpUtil; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; -import org.openhab.core.library.types.PointType; import org.openhab.core.library.types.RawType; import org.openhab.core.library.types.StringType; import org.openhab.core.thing.Bridge; @@ -169,12 +168,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { } else if (CHANNEL_GROUP_DESTINATION.equals(group)) { // receive new destination location if (command instanceof StringType) { - destinationList.forEach(entry -> { - if (((StringType) command).toFullString().equals(entry.getAddress())) { - // update coordinates according to new set location - updateState(destinationLocation, PointType.valueOf(entry.getCoordinates())); - } - }); + selectDestination(((StringType) command).toFullString()); } } if (channelUID.getIdWithoutGroup().equals(VEHICLE_FINGERPRINT)) { @@ -561,7 +555,7 @@ public void onResponse(Optional content) { } updateVehicleStatus(vStatus); setCheckControlList(vStatus.checkControlMessages); - setServiceList(vStatus.cbsData); + // setServiceList(vStatus.cbsData); updatePosition(vStatus.position); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java index 3e47a3740658e..c4bfbeffdf369 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java @@ -58,8 +58,8 @@ public class VehicleTests { private static final int DOORS = 12; private static final int CHECK_EMPTY = 2; private static final int CHECK_AVAILABLE = 2; - private static final int SERVICE_AVAILABLE = 3; - private static final int SERVICE_EMPTY = 3; + private static final int SERVICE_AVAILABLE = 0;// ;3; + private static final int SERVICE_EMPTY = 0;// 3; private static final int POSITION = 2; @Nullable From 13ccfd5e4d9b48c040fb2e8f856b9e94a7c9b4b3 Mon Sep 17 00:00:00 2001 From: Bernd Date: Fri, 25 Dec 2020 13:41:37 +0100 Subject: [PATCH 079/176] switch serviceList to options Signed-off-by: Bernd --- .../BMWConnectedDriveOptionProvider.java | 5 -- .../handler/VehicleChannelHandler.java | 90 +++++++++---------- .../internal/handler/VehicleHandler.java | 7 +- .../internal/dto/StatusWrapper.java | 2 +- .../internal/handler/VehicleTests.java | 4 +- 5 files changed, 51 insertions(+), 57 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BMWConnectedDriveOptionProvider.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BMWConnectedDriveOptionProvider.java index 885f949878de9..50eed64c107b1 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BMWConnectedDriveOptionProvider.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BMWConnectedDriveOptionProvider.java @@ -18,8 +18,6 @@ import org.openhab.core.thing.type.DynamicStateDescriptionProvider; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Dynamic provider of state options while leaving other state description fields as original. @@ -29,18 +27,15 @@ @Component(service = { DynamicStateDescriptionProvider.class, BMWConnectedDriveOptionProvider.class }) @NonNullByDefault public class BMWConnectedDriveOptionProvider extends BaseDynamicStateDescriptionProvider { - protected final Logger logger = LoggerFactory.getLogger(BMWConnectedDriveOptionProvider.class); @Reference protected void setChannelTypeI18nLocalizationService( final ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) { - logger.info("LocalizationService set"); this.channelTypeI18nLocalizationService = channelTypeI18nLocalizationService; } protected void unsetChannelTypeI18nLocalizationService( final ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) { - logger.info("LocalizationService unset"); this.channelTypeI18nLocalizationService = null; } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 7c2a316660fa9..797269a0842cf 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -69,13 +69,12 @@ public class VehicleChannelHandler extends BaseThingHandler { // List Interfaces protected List serviceList = new ArrayList(); - protected String selectedService = Constants.INVALID; - private int serviceListIndex = -1; + protected String selectedService = Constants.UNKNOWN; protected List checkControlList = new ArrayList(); - protected String selectedCC = Constants.INVALID; + protected String selectedCC = Constants.UNKNOWN; private int checkControlListIndex = -1; protected List destinationList = new ArrayList(); - protected String selectedDestination = Constants.INVALID; + protected String selectedDestination = Constants.UNKNOWN; protected BMWConnectedDriveOptionProvider optionProvider; @@ -324,55 +323,49 @@ private void updateCheckControls() { } } - private void updateService(List sl) { - boolean isFirstUpdate = serviceList.isEmpty(); + protected void updateServices(List sl) { + // if list is empty add "undefined" element + if (sl.size() == 0) { + sl.add(new CBSMessage()); + } + + // add all elements to options serviceList = sl; List options = new ArrayList<>(); - if (destinationList.size() == 0) { - destinationList.add(Destination.getUndefined()); + boolean isSelectedElementIn = false; + for (CBSMessage serviceEntry : serviceList) { + options.add(new StateOption(serviceEntry.getType(), serviceEntry.getType())); + if (selectedService.equals(serviceEntry.getType())) { + isSelectedElementIn = true; + } } + optionProvider.setStateOptions(serviceName, options); - destinationList.forEach(destination -> { - options.add(new StateOption(destination.getAddress(), destination.getAddress())); - }); - - logger.info("Added {} options to {}", destinationList.size(), destinationName.getAsString()); - logger.info("Options {}", options.toArray()); - optionProvider.setStateOptions(destinationName, options); - if (isFirstUpdate) { - updateState(destinationName, StringType.valueOf(destinationList.get(0).getAddress())); - updateState(destinationLocation, PointType.valueOf(destinationList.get(0).getCoordinates())); + // if current selected item isn't anymore in the list select first entry + if (!isSelectedElementIn) { + selectService(serviceList.get(0).getType()); } + } - if (!serviceList.isEmpty()) { - if (serviceListIndex < 0 || serviceListIndex >= serviceList.size()) { - // select first item - serviceListIndex = 0; - } - CBSMessage entry = serviceList.get(serviceListIndex); - updateState(serviceName, StringType.valueOf(Converter.toTitleCase(entry.getType()))); - updateState(serviceDate, DateTimeType.valueOf(Converter.getLocalDateTime(entry.getDueDate()))); - if (imperial) { - updateState(serviceMileage, - QuantityType.valueOf(Converter.round(entry.cbsRemainingMileage), ImperialUnits.MILE)); - } else { - updateState(serviceMileage, QuantityType.valueOf(Converter.round(entry.cbsRemainingMileage), - MetricPrefix.KILO(SIUnits.METRE))); - } - } else { - // list is empty - set all fields to INVALID. If this isn't done the old values remain - updateState(serviceName, StringType.valueOf(Constants.INVALID)); - updateState(serviceDate, DateTimeType.valueOf(Converter.getLocalDateTime(Constants.NULL_DATE))); - if (imperial) { - updateState(serviceMileage, QuantityType.valueOf(-1, ImperialUnits.MILE)); - } else { - updateState(serviceMileage, QuantityType.valueOf(-1, MetricPrefix.KILO(SIUnits.METRE))); + protected void selectService(String selection) { + serviceList.forEach(entry -> { + if (selection.equals(entry.getType())) { + selectedService = selection; + updateState(serviceName, StringType.valueOf(Converter.toTitleCase(entry.getType()))); + updateState(serviceDate, DateTimeType.valueOf(Converter.getLocalDateTime(entry.getDueDate()))); + if (imperial) { + updateState(serviceMileage, + QuantityType.valueOf(Converter.round(entry.cbsRemainingMileage), ImperialUnits.MILE)); + } else { + updateState(serviceMileage, QuantityType.valueOf(Converter.round(entry.cbsRemainingMileage), + MetricPrefix.KILO(SIUnits.METRE))); + } + return; } - } + }); } protected void updateDestinations(List dl) { - List options = new ArrayList<>(); // if list is empty add "undefined" element if (dl.size() == 0) { dl.add(Destination.getUndefined()); @@ -380,6 +373,7 @@ protected void updateDestinations(List dl) { // add all elements to options destinationList = dl; + List options = new ArrayList<>(); boolean isSelectedElementIn = false; for (Destination destination : destinationList) { options.add(new StateOption(destination.getAddress(), destination.getAddress())); @@ -394,17 +388,17 @@ protected void updateDestinations(List dl) { // if current selected item isn't anymore in the list select first entry if (!isSelectedElementIn) { - updateState(destinationName, StringType.valueOf(destinationList.get(0).getAddress())); - updateState(destinationLocation, PointType.valueOf(destinationList.get(0).getCoordinates())); + selectDestination(destinationList.get(0).getAddress()); } } - protected void selectDestination(String destinationName) { + protected void selectDestination(String selection) { destinationList.forEach(entry -> { - if (destinationName.equals(entry.getAddress())) { + if (selection.equals(entry.getAddress())) { // update selected Item - selectedDestination = destinationName; + selectedDestination = selection; // update coordinates according to new set location + updateState(destinationName, StringType.valueOf(entry.getAddress())); updateState(destinationLocation, PointType.valueOf(entry.getCoordinates())); return; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 458093e9c8d93..edb38e7ba70a9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -170,6 +170,11 @@ public void handleCommand(ChannelUID channelUID, Command command) { if (command instanceof StringType) { selectDestination(((StringType) command).toFullString()); } + } else if (CHANNEL_GROUP_SERVICE.equals(group)) { + // receive new destination location + if (command instanceof StringType) { + selectService(((StringType) command).toFullString()); + } } if (channelUID.getIdWithoutGroup().equals(VEHICLE_FINGERPRINT)) { // Log Troubleshoot data @@ -555,7 +560,7 @@ public void onResponse(Optional content) { } updateVehicleStatus(vStatus); setCheckControlList(vStatus.checkControlMessages); - // setServiceList(vStatus.cbsData); + updateServices(vStatus.cbsData); updatePosition(vStatus.position); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index 09609d9df3486..fbd0d6210ebe2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -434,7 +434,7 @@ private void checkResult(ChannelUID channelUID, State state) { st = (StringType) state; switch (gUid) { case CHANNEL_GROUP_SERVICE: - wanted = StringType.valueOf(Constants.INVALID); + wanted = StringType.valueOf(Converter.toTitleCase(Constants.INVALID)); if (!vStatus.cbsData.isEmpty()) { wanted = StringType.valueOf(Converter.toTitleCase(vStatus.cbsData.get(0).getType())); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java index c4bfbeffdf369..3e47a3740658e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java @@ -58,8 +58,8 @@ public class VehicleTests { private static final int DOORS = 12; private static final int CHECK_EMPTY = 2; private static final int CHECK_AVAILABLE = 2; - private static final int SERVICE_AVAILABLE = 0;// ;3; - private static final int SERVICE_EMPTY = 0;// 3; + private static final int SERVICE_AVAILABLE = 3; + private static final int SERVICE_EMPTY = 3; private static final int POSITION = 2; @Nullable From 2e07630fb130828ef3f88ea588a55c6f4d6c28bc Mon Sep 17 00:00:00 2001 From: Bernd Date: Fri, 25 Dec 2020 14:03:03 +0100 Subject: [PATCH 080/176] switch check control list to options Signed-off-by: Bernd --- .../internal/dto/status/CCMMessage.java | 15 +++-- .../handler/VehicleChannelHandler.java | 64 +++++++++++-------- .../internal/handler/VehicleHandler.java | 8 ++- .../thing/check-control-channel-types.xml | 12 ---- .../OH-INF/thing/check-control-group.xml | 3 - 5 files changed, 50 insertions(+), 52 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CCMMessage.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CCMMessage.java index 6b3f726d8458b..67f596384ff3f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CCMMessage.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CCMMessage.java @@ -12,16 +12,19 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.dto.status; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; + /** * The {@link CCMMessage} Data Transfer Object * * @author Bernd Weymann - Initial contribution */ public class CCMMessage { - public String ccmDescriptionLong;// ": "You can continue driving. Check tyre pressure when tyres are cold and adjust - // if necessary. Perform reset after adjustment. See Owner's Handbook for further - // information.", - public String ccmDescriptionShort;// ": "Tyre pressure notification", - public int ccmId;// ": 955, - public int ccmMileage;// ": 41544 + public String ccmDescriptionLong = Constants.INVALID;// ": "You can continue driving. Check tyre pressure when tyres + // are cold and adjust + // if necessary. Perform reset after adjustment. See Owner's Handbook for further + // information.", + public String ccmDescriptionShort = Constants.INVALID;// ": "Tyre pressure notification", + public int ccmId = -1;// ": 955, + public int ccmMileage = -1;// ": 41544 } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 797269a0842cf..ce2ded5ff8949 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -72,7 +72,6 @@ public class VehicleChannelHandler extends BaseThingHandler { protected String selectedService = Constants.UNKNOWN; protected List checkControlList = new ArrayList(); protected String selectedCC = Constants.UNKNOWN; - private int checkControlListIndex = -1; protected List destinationList = new ArrayList(); protected String selectedDestination = Constants.UNKNOWN; @@ -291,36 +290,45 @@ public void handleCommand(ChannelUID channelUID, Command command) { public void initialize() { } - public synchronized void setCheckControlList(List l) { - checkControlList = l; - updateCheckControls(); - } + protected void updateCheckControls(List ccl) { + // if list is empty add "undefined" element + if (ccl.size() == 0) { + ccl.add(new CCMMessage()); + } - private void updateCheckControls() { - if (!checkControlList.isEmpty()) { - if (checkControlListIndex < 0 || checkControlListIndex >= checkControlList.size()) { - // select first item - checkControlListIndex = 0; - } - CCMMessage entry = checkControlList.get(checkControlListIndex); - updateState(checkControlName, StringType.valueOf(entry.ccmDescriptionShort)); - if (imperial) { - updateState(checkControlMileage, - QuantityType.valueOf(Converter.round(entry.ccmMileage), ImperialUnits.MILE)); - } else { - updateState(checkControlMileage, - QuantityType.valueOf(Converter.round(entry.ccmMileage), MetricPrefix.KILO(SIUnits.METRE))); - } - } else { - // list is empty - set all fields to INVALID. If this isn't done the old values remain - updateState(checkControlName, StringType.valueOf(Constants.INVALID)); - if (imperial) { - updateState(checkControlMileage, QuantityType.valueOf(Converter.round(-1), ImperialUnits.MILE)); - } else { - updateState(checkControlMileage, - QuantityType.valueOf(Converter.round(-1), MetricPrefix.KILO(SIUnits.METRE))); + // add all elements to options + checkControlList = ccl; + List options = new ArrayList<>(); + boolean isSelectedElementIn = false; + for (CCMMessage ccEntry : checkControlList) { + options.add(new StateOption(ccEntry.ccmDescriptionShort, ccEntry.ccmDescriptionShort)); + if (selectedCC.equals(ccEntry.ccmDescriptionShort)) { + isSelectedElementIn = true; } } + optionProvider.setStateOptions(checkControlName, options); + + // if current selected item isn't anymore in the list select first entry + if (!isSelectedElementIn) { + selectCC(checkControlList.get(0).ccmDescriptionShort); + } + } + + protected void selectCC(String selection) { + checkControlList.forEach(entry -> { + if (selection.equals(entry.ccmDescriptionShort)) { + selectedCC = selection; + updateState(checkControlName, StringType.valueOf(entry.ccmDescriptionShort)); + if (imperial) { + updateState(checkControlMileage, + QuantityType.valueOf(Converter.round(entry.ccmMileage), ImperialUnits.MILE)); + } else { + updateState(checkControlMileage, + QuantityType.valueOf(Converter.round(entry.ccmMileage), MetricPrefix.KILO(SIUnits.METRE))); + } + return; + } + }); } protected void updateServices(List sl) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index edb38e7ba70a9..63b293f8e865a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -166,15 +166,17 @@ public void handleCommand(ChannelUID channelUID, Command command) { } } } else if (CHANNEL_GROUP_DESTINATION.equals(group)) { - // receive new destination location if (command instanceof StringType) { selectDestination(((StringType) command).toFullString()); } } else if (CHANNEL_GROUP_SERVICE.equals(group)) { - // receive new destination location if (command instanceof StringType) { selectService(((StringType) command).toFullString()); } + } else if (CHANNEL_GROUP_CHECK_CONTROL.equals(group)) { + if (command instanceof StringType) { + selectCC(((StringType) command).toFullString()); + } } if (channelUID.getIdWithoutGroup().equals(VEHICLE_FINGERPRINT)) { // Log Troubleshoot data @@ -559,7 +561,7 @@ public void onResponse(Optional content) { return; } updateVehicleStatus(vStatus); - setCheckControlList(vStatus.checkControlMessages); + updateCheckControls(vStatus.checkControlMessages); updateServices(vStatus.cbsData); updatePosition(vStatus.position); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-channel-types.xml index 482c84ef2081e..b1a77c7583b6a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-channel-types.xml @@ -11,16 +11,4 @@ Number:Length - - Number - - - - Number - - - - Switch - - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-group.xml index 5711b14854cf1..0b554f6b98a06 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-group.xml @@ -9,9 +9,6 @@ - - - From 511b172ec150f41517d21feab05b03b58fed4a14 Mon Sep 17 00:00:00 2001 From: Bernd Date: Fri, 25 Dec 2020 15:24:49 +0100 Subject: [PATCH 081/176] rework troubleshoot fingerprint output Signed-off-by: Bernd --- .../internal/ConnectedDriveConstants.java | 4 - .../handler/ConnectedDriveBridgeHandler.java | 33 +-- .../handler/VehicleChannelHandler.java | 7 +- .../internal/handler/VehicleHandler.java | 195 ++++++++++-------- .../OH-INF/thing/bridge-connected-drive.xml | 7 - .../main/resources/OH-INF/thing/thing-bev.xml | 1 - .../resources/OH-INF/thing/thing-bev_rex.xml | 1 - .../resources/OH-INF/thing/thing-conv.xml | 1 - .../resources/OH-INF/thing/thing-phev.xml | 1 - .../thing/troubleshoot-channel-group.xml | 13 -- .../thing/troubleshoot-channel-types.xml | 10 - 11 files changed, 131 insertions(+), 142 deletions(-) delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/troubleshoot-channel-group.xml delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/troubleshoot-channel-types.xml diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 0d1d41c9ebbff..d24f093f058b4 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -175,8 +175,4 @@ public String toString() { public static final String REMOTE_SERVICE_AIR_CONDITIONING = "climate"; public static final String REMOTE_SERVICE_COMMAND = "command"; public static final String REMOTE_STATE = "state"; - - // Troubleshoot - public static final String DISCOVERY_FINGERPRINT = "discovery-fingerprint"; - public static final String VEHICLE_FINGERPRINT = "vehicle-fingerprint"; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java index 9dac337a7d95f..74eb44bad83a1 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java @@ -30,7 +30,6 @@ import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.openhab.core.io.net.http.HttpClientFactory; -import org.openhab.core.library.types.OnOffType; import org.openhab.core.thing.Bridge; import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.ThingStatus; @@ -58,31 +57,19 @@ public class ConnectedDriveBridgeHandler extends BaseBridgeHandler implements St private Optional> initializerJob = Optional.empty(); private Optional troubleshootFingerprint = Optional.empty(); - private static final String DISCOVERY_FINGERPRINT = "discovery-fingerprint"; - private ChannelUID discoveryFingerprintChannel; - public ConnectedDriveBridgeHandler(Bridge bridge, HttpClientFactory hcf, BundleContext bc) { super(bridge); httpClientFactory = hcf; - discoveryFingerprintChannel = new ChannelUID(bridge.getUID(), DISCOVERY_FINGERPRINT); } @Override public void handleCommand(ChannelUID channelUID, Command command) { - if (DISCOVERY_FINGERPRINT.equals(channelUID.getIdWithoutGroup()) && command instanceof OnOffType) { - if (command.equals(OnOffType.ON)) { - logger.warn( - "###### BMW ConnectedDrive Binding - Discovery Troubleshoot Fingerprint Data - BEGIN ######"); - logger.warn("### Discovery Result ###"); - logger.warn("{}", getDiscoveryFingerprint()); - logger.warn("###### BMW ConnectedDrive Binding - Discovery Troubleshoot Fingerprint Data - END ######"); - updateState(discoveryFingerprintChannel, OnOffType.OFF); - } - } + // no commands available } @Override public void initialize() { + troubleshootFingerprint = Optional.empty(); updateStatus(ThingStatus.UNKNOWN); configuration = Optional.of(getConfigAs(ConnectedDriveConfiguration.class)); if (configuration.isPresent()) { @@ -92,7 +79,6 @@ public void initialize() { } else { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR); } - updateState(discoveryFingerprintChannel, OnOffType.OFF); } @Override @@ -140,11 +126,19 @@ public String getDiscoveryFingerprint() { } } + private void logFingerPrint() { + logger.debug("###### BMW ConnectedDrive Binding - Discovery Troubleshoot Fingerprint Data - BEGIN ######"); + logger.debug("### Discovery Result ###"); + logger.debug("{}", getDiscoveryFingerprint()); + logger.debug("###### BMW ConnectedDrive Binding - Discovery Troubleshoot Fingerprint Data - END ######"); + } + /** * There's only the Vehicles response available */ @Override public void onResponse(Optional response) { + boolean firstResponse = troubleshootFingerprint.isEmpty(); if (response.isPresent()) { troubleshootFingerprint = response; VehiclesContainer container = Converter.getGson().fromJson(response.get(), VehiclesContainer.class); @@ -169,11 +163,18 @@ public void onResponse(Optional response) { } else { troubleshootFingerprint = Optional.of(Constants.EMPTY_VEHICLES); } + if (firstResponse) { + logFingerPrint(); + } } @Override public void onError(NetworkError error) { + boolean firstResponse = troubleshootFingerprint.isEmpty(); troubleshootFingerprint = Optional.of(error.toJson()); + if (firstResponse) { + logFingerPrint(); + } updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, error.reason); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index ce2ded5ff8949..cadde7ccac7c1 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -77,7 +77,7 @@ public class VehicleChannelHandler extends BaseThingHandler { protected BMWConnectedDriveOptionProvider optionProvider; - // Vahicle Status Channels + // Vehicle Status Channels protected ChannelUID doors; protected ChannelUID windows; protected ChannelUID lock; @@ -162,9 +162,6 @@ public class VehicleChannelHandler extends BaseThingHandler { protected ChannelUID timer3Enabled; protected ChannelUID timer3Days; - // Troubleshooting - protected ChannelUID vehicleFingerPrint; - // Image protected ChannelUID imageChannel; protected ChannelUID imageViewportChannel; @@ -278,8 +275,6 @@ public VehicleChannelHandler(Thing thing, BMWConnectedDriveOptionProvider op, St imageChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_FORMAT); imageViewportChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_VIEWPORT); imageSizeChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_SIZE); - - vehicleFingerPrint = new ChannelUID(thing.getUID(), CHANNEL_GROUP_TROUBLESHOOT, VEHICLE_FINGERPRINT); } @Override diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 63b293f8e865a..df353e02dbad9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -14,6 +14,8 @@ import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -37,7 +39,6 @@ import org.openhab.binding.bmwconnecteddrive.internal.utils.ImageProperties; import org.openhab.core.io.net.http.HttpUtil; import org.openhab.core.library.types.DecimalType; -import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.RawType; import org.openhab.core.library.types.StringType; import org.openhab.core.thing.Bridge; @@ -64,6 +65,7 @@ public class VehicleHandler extends VehicleChannelHandler { private Optional configuration = Optional.empty(); private Optional bridgeHandler = Optional.empty(); private Optional> refreshJob = Optional.empty(); + private Optional> callbackCounter = Optional.empty(); private ImageProperties imageProperties = new ImageProperties(); VehicleStatusCallback vehicleStatusCallback = new VehicleStatusCallback(); @@ -178,91 +180,11 @@ public void handleCommand(ChannelUID channelUID, Command command) { selectCC(((StringType) command).toFullString()); } } - if (channelUID.getIdWithoutGroup().equals(VEHICLE_FINGERPRINT)) { - // Log Troubleshoot data - if (command instanceof OnOffType) { - if (command.equals(OnOffType.ON)) { - logger.warn( - "###### BMW ConnectedDrive Binding - Vehicle Troubleshoot Fingerprint Data - BEGIN ######"); - logger.warn("### Discovery Result ###"); - logger.warn("{}", bridgeHandler.get().getDiscoveryFingerprint()); - if (vehicleStatusCache.isPresent()) { - logger.warn("### Vehicle Status ###"); - - // Anonymous data for VIN and Position - VehicleStatusContainer container = Converter.getGson().fromJson(vehicleStatusCache.get(), - VehicleStatusContainer.class); - VehicleStatus status = container.vehicleStatus; - if (status != null) { - status.vin = Constants.ANONYMOUS; - if (status.position != null) { - status.position.lat = -1; - status.position.lon = -1; - status.position.heading = -1; - } - } - logger.warn("{}", Converter.getGson().toJson(container)); - } else { - logger.warn("### Vehicle Status Empty ###"); - } - if (lastTripCache.isPresent()) { - logger.warn("### Last Trip ###"); - logger.warn("{}", lastTripCache.get().replaceAll(configuration.get().vin, Constants.ANONYMOUS)); - } else { - logger.warn("### Last Trip Empty ###"); - } - if (allTripsCache.isPresent()) { - logger.warn("### All Trips ###"); - logger.warn("{}", allTripsCache.get().replaceAll(configuration.get().vin, Constants.ANONYMOUS)); - } else { - logger.warn("### All Trips Empty ###"); - } - if (isElectric) { - if (chargeProfileCache.isPresent()) { - logger.warn("### Charge Profile ###"); - logger.warn("{}", - chargeProfileCache.get().replaceAll(configuration.get().vin, Constants.ANONYMOUS)); - } else { - logger.warn("### Charge Profile Empty ###"); - } - } - if (destinationCache.isPresent()) { - logger.warn("### Charge Profile ###"); - DestinationContainer container = Converter.getGson().fromJson(destinationCache.get(), - DestinationContainer.class); - if (container.destinations != null) { - container.destinations.forEach(entry -> { - entry.lat = 0; - entry.lon = 0; - entry.city = Constants.ANONYMOUS; - entry.street = Constants.ANONYMOUS; - entry.streetNumber = Constants.ANONYMOUS; - entry.country = Constants.ANONYMOUS; - }); - logger.warn("{}", Converter.getGson().toJson(container)); - } else { - logger.warn("### Destinations Empty ###"); - } - } else { - logger.warn("### Charge Profile Empty ###"); - } - if (rangeMapCache.isPresent()) { - logger.warn("### Range Map ###"); - logger.warn("{}", rangeMapCache.get().replaceAll(configuration.get().vin, Constants.ANONYMOUS)); - } else { - logger.warn("### Range Map Empty ###"); - } - logger.warn( - "###### BMW ConnectedDrive Binding - Vehicle Troubleshoot Fingerprint Data - END ######"); - } - // Switch back to off immediately - updateState(channelUID, OnOffType.OFF); - } - } } @Override public void initialize() { + callbackCounter = Optional.of(new ArrayList()); updateStatus(ThingStatus.UNKNOWN); configuration = Optional.of(getConfigAs(VehicleConfiguration.class)); if (configuration.isPresent()) { @@ -329,19 +251,25 @@ public void getData() { } else { proxy.get().requestLegacyVehcileStatus(configuration.get(), oldVehicleStatusCallback); } + addCallback(vehicleStatusCallback); if (isSupported(Constants.STATISTICS)) { proxy.get().requestLastTrip(configuration.get(), lastTripCallback); proxy.get().requestAllTrips(configuration.get(), allTripsCallback); + addCallback(lastTripCallback); + addCallback(allTripsCallback); } if (isSupported(Constants.LAST_DESTINATIONS)) { proxy.get().requestDestinations(configuration.get(), destinationCallback); + addCallback(destinationCallback); } if (isElectric) { proxy.get().requestChargingProfile(configuration.get(), chargeProfileCallback); + addCallback(chargeProfileCallback); } synchronized (imageProperties) { if (!imageCache.isPresent() && !imageProperties.failLimitReached()) { proxy.get().requestImage(configuration.get(), imageProperties, imageCallback); + addCallback(imageCallback); } } } else { @@ -349,6 +277,95 @@ public void getData() { } } + private synchronized void addCallback(ResponseCallback rc) { + if (callbackCounter.isPresent()) { + callbackCounter.get().add(rc); + } + } + + private synchronized void removeCallback(ResponseCallback rc) { + if (callbackCounter.isPresent()) { + callbackCounter.get().remove(rc); + // all necessary callbacks received => print and set to empty + if (callbackCounter.get().isEmpty()) { + logFingerPrint(); + callbackCounter = Optional.empty(); + } + } + } + + private void logFingerPrint() { + logger.debug("###### BMW ConnectedDrive Binding - Vehicle Troubleshoot Fingerprint Data - BEGIN ######"); + logger.debug("### Discovery Result ###"); + logger.debug("{}", bridgeHandler.get().getDiscoveryFingerprint()); + if (vehicleStatusCache.isPresent()) { + logger.debug("### Vehicle Status ###"); + + // Anonymous data for VIN and Position + VehicleStatusContainer container = Converter.getGson().fromJson(vehicleStatusCache.get(), + VehicleStatusContainer.class); + VehicleStatus status = container.vehicleStatus; + if (status != null) { + status.vin = Constants.ANONYMOUS; + if (status.position != null) { + status.position.lat = -1; + status.position.lon = -1; + status.position.heading = -1; + } + } + logger.debug("{}", Converter.getGson().toJson(container)); + } else { + logger.debug("### Vehicle Status Empty ###"); + } + if (lastTripCache.isPresent()) { + logger.debug("### Last Trip ###"); + logger.debug("{}", lastTripCache.get().replaceAll(configuration.get().vin, Constants.ANONYMOUS)); + } else { + logger.debug("### Last Trip Empty ###"); + } + if (allTripsCache.isPresent()) { + logger.debug("### All Trips ###"); + logger.debug("{}", allTripsCache.get().replaceAll(configuration.get().vin, Constants.ANONYMOUS)); + } else { + logger.debug("### All Trips Empty ###"); + } + if (isElectric) { + if (chargeProfileCache.isPresent()) { + logger.debug("### Charge Profile ###"); + logger.debug("{}", chargeProfileCache.get().replaceAll(configuration.get().vin, Constants.ANONYMOUS)); + } else { + logger.debug("### Charge Profile Empty ###"); + } + } + if (destinationCache.isPresent()) { + logger.debug("### Charge Profile ###"); + DestinationContainer container = Converter.getGson().fromJson(destinationCache.get(), + DestinationContainer.class); + if (container.destinations != null) { + container.destinations.forEach(entry -> { + entry.lat = 0; + entry.lon = 0; + entry.city = Constants.ANONYMOUS; + entry.street = Constants.ANONYMOUS; + entry.streetNumber = Constants.ANONYMOUS; + entry.country = Constants.ANONYMOUS; + }); + logger.debug("{}", Converter.getGson().toJson(container)); + } else { + logger.debug("### Destinations Empty ###"); + } + } else { + logger.debug("### Charge Profile Empty ###"); + } + if (rangeMapCache.isPresent()) { + logger.debug("### Range Map ###"); + logger.debug("{}", rangeMapCache.get().replaceAll(configuration.get().vin, Constants.ANONYMOUS)); + } else { + logger.debug("### Range Map Empty ###"); + } + logger.debug("###### BMW ConnectedDrive Binding - Vehicle Troubleshoot Fingerprint Data - END ######"); + } + /** * Don't stress ConnectedDrive with unnecessary requests. One call at the beginning is done to check the response. * After cache has e.g. a proper error response it will be shown in the fingerprint @@ -399,6 +416,7 @@ public void onResponse(Optional content) { updateChargeProfile(cp); } } + removeCallback(this); } /** @@ -408,6 +426,7 @@ public void onResponse(Optional content) { public void onError(NetworkError error) { logger.debug("{}", error.toString()); chargeProfileCache = Optional.of(Converter.getGson().toJson(error)); + removeCallback(this); } } @@ -416,6 +435,7 @@ public class RangeMapCallback implements StringResponseCallback { @Override public void onResponse(Optional content) { rangeMapCache = content; + removeCallback(this); } /** @@ -425,6 +445,7 @@ public void onResponse(Optional content) { public void onError(NetworkError error) { logger.debug("{}", error.toString()); rangeMapCache = Optional.of(Converter.getGson().toJson(error)); + removeCallback(this); } } @@ -441,6 +462,7 @@ public void onResponse(Optional content) { updateDestinations(dc.destinations); } } + removeCallback(this); } /** @@ -450,6 +472,7 @@ public void onResponse(Optional content) { public void onError(NetworkError error) { logger.debug("{}", error.toString()); destinationCache = Optional.of(Converter.getGson().toJson(error)); + removeCallback(this); } } @@ -466,6 +489,7 @@ public void onResponse(Optional content) { imageProperties.failed(); } } + removeCallback(this); } /** @@ -477,6 +501,7 @@ public void onError(NetworkError error) { synchronized (imageProperties) { imageProperties.failed(); } + removeCallback(this); } } @@ -492,6 +517,7 @@ public void onResponse(Optional content) { updateAllTrips(at); } } + removeCallback(this); } /** @@ -501,6 +527,7 @@ public void onResponse(Optional content) { public void onError(NetworkError error) { logger.debug("{}", error.toString()); allTripsCache = Optional.of(Converter.getGson().toJson(error)); + removeCallback(this); } } @@ -516,6 +543,7 @@ public void onResponse(Optional content) { updateLastTrip(trip); } } + removeCallback(this); } /** @@ -525,6 +553,7 @@ public void onResponse(Optional content) { public void onError(NetworkError error) { logger.debug("{}", error.toString()); lastTripCache = Optional.of(Converter.getGson().toJson(error)); + removeCallback(this); } } @@ -565,6 +594,7 @@ public void onResponse(Optional content) { updateServices(vStatus.cbsData); updatePosition(vStatus.position); } + removeCallback(this); } @Override @@ -577,6 +607,7 @@ public void onError(NetworkError error) { } vehicleStatusCache = Optional.of(Converter.getGson().toJson(error)); setThingStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, error.reason); + removeCallback(this); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/bridge-connected-drive.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/bridge-connected-drive.xml index 50d9d669fc088..ddfa1bfa44467 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/bridge-connected-drive.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/bridge-connected-drive.xml @@ -35,11 +35,4 @@ - - - Switch - - Forcing a log entry to analyze Discovery Problems - - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml index 81b931299acc6..a32ddc1fee9d3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml @@ -25,7 +25,6 @@ - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml index 05b8aba25b93a..19a6d6a0298d6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml @@ -25,7 +25,6 @@ - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml index 0777dc89b5b85..51ee215a7f819 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml @@ -22,7 +22,6 @@ - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml index 77b5cf6aedb7b..d1416e74095be 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml @@ -25,7 +25,6 @@ - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/troubleshoot-channel-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/troubleshoot-channel-group.xml deleted file mode 100644 index 594999f51ed37..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/troubleshoot-channel-group.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - Generates Debug Data - - - - - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/troubleshoot-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/troubleshoot-channel-types.xml deleted file mode 100644 index aee77d20f5c74..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/troubleshoot-channel-types.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - Switch - - - From 972380ce05315945ac5b6404381333bb88ea1b20 Mon Sep 17 00:00:00 2001 From: Bernd Date: Fri, 25 Dec 2020 15:56:21 +0100 Subject: [PATCH 082/176] update servers and constants due to changed authorization Signed-off-by: Bernd --- .../internal/handler/ConnectedDriveProxy.java | 143 +++--------------- .../handler/VehicleChannelHandler.java | 3 - .../internal/utils/BimmerConstants.java | 19 ++- 3 files changed, 31 insertions(+), 134 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index d19b53f2c3d8a..45554159a700a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -14,12 +14,6 @@ import static org.openhab.binding.bmwconnecteddrive.internal.utils.HTTPConstants.*; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.URL; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Optional; @@ -67,30 +61,14 @@ public class ConnectedDriveProxy { private final Token token = new Token(); private HttpClient httpClient; private HttpClient authHttpClient; - private String authUri; private String legacyAuthUri; private ConnectedDriveConfiguration configuration; /** * URLs taken from https://github.com/bimmerconnected/bimmer_connected/blob/master/bimmer_connected/const.py - * - * """URLs for different services and error code mapping.""" - * - * AUTH_URL = 'https://customer.bmwgroup.com/{gcdm_oauth_endpoint}/authenticate' - * AUTH_URL_LEGACY = 'https://{server}/gcdm/oauth/token' - * BASE_URL = 'https://{server}/webapi/v1' - * - * VEHICLES_URL = BASE_URL + '/user/vehicles' - * VEHICLE_VIN_URL = VEHICLES_URL + '/{vin}' - * VEHICLE_STATUS_URL = VEHICLE_VIN_URL + '/status' - * REMOTE_SERVICE_STATUS_URL = VEHICLE_VIN_URL + '/serviceExecutionStatus?serviceType={service_type}' - * REMOTE_SERVICE_URL = VEHICLE_VIN_URL + "/executeService" - * VEHICLE_IMAGE_URL = VEHICLE_VIN_URL + "/image?width={width}&height={height}&view={view}" - * VEHICLE_POI_URL = VEHICLE_VIN_URL + '/sendpoi' - * - * } */ String baseUrl; + String vehicleUrl; String legacyUrl; String vehicleStatusAPI = "/status"; String lastTripAPI = "/statistics/lastTrip"; @@ -112,23 +90,14 @@ public ConnectedDriveProxy(HttpClientFactory httpClientFactory, ConnectedDriveCo logger.warn("Auth Http Client cannot be started"); } configuration = config; - // generate URI for Authorization - // see https://customer.bmwgroup.com/one/app/oauth.js - StringBuilder uri = new StringBuilder(); - uri.append("https://customer.bmwgroup.com"); - if (BimmerConstants.SERVER_NORTH_AMERICA.equals(configuration.region)) { - uri.append("/gcdm/usa/oauth/authenticate"); - } else { - uri.append("/gcdm/oauth/authenticate"); - } - authUri = uri.toString(); StringBuilder legacyAuth = new StringBuilder(); legacyAuth.append("https://"); legacyAuth.append(BimmerConstants.AUTH_SERVER_MAP.get(configuration.region)); legacyAuth.append(BimmerConstants.OAUTH_ENDPOINT); legacyAuthUri = legacyAuth.toString(); - baseUrl = "https://" + getRegionServer() + "/webapi/v1/user/vehicles/"; + vehicleUrl = "https://" + getRegionServer() + "/webapi/v1/user/vehicles"; + baseUrl = vehicleUrl + "/"; legacyUrl = "https://" + getRegionServer() + "/api/vehicle/dynamic/v1/"; } @@ -164,6 +133,8 @@ private synchronized void call(String url, boolean post, Optional> params, ResponseCallback } public void requestVehicles(StringResponseCallback callback) { - get(baseUrl, Optional.empty(), callback); + get(vehicleUrl, Optional.empty(), callback); } public void requestVehcileStatus(VehicleConfiguration config, StringResponseCallback callback) { @@ -269,7 +240,7 @@ RemoteServiceHandler getRemoteServiceHandler(VehicleHandler vehicleHandler) { */ public Token getToken() { if (token.isExpired() || !token.isValid()) { - legacyUpdateToken(); + updateToken(); } return token; } @@ -279,20 +250,18 @@ public Token getToken() { * * @return */ - private synchronized void jettyUpdateToken() { - logger.info("updateToken - start"); - Request req = authHttpClient.POST(authUri); + private synchronized void updateToken() { + Request req = authHttpClient.POST(legacyAuthUri); req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); req.header(HttpHeader.CONNECTION, KEEP_ALIVE); req.header(HttpHeader.HOST, BimmerConstants.SERVER_MAP.get(configuration.region)); - req.header(HttpHeader.AUTHORIZATION, BimmerConstants.AUTHORIZATION_VALUE); + req.header(HttpHeader.AUTHORIZATION, BimmerConstants.AUTHORIZATION_VALUE_MAP.get(configuration.region)); req.header(CREDENTIALS, BimmerConstants.CREDENTIAL_VALUES); + req.header(HttpHeader.REFERER, BimmerConstants.REFERER_URL); MultiMap dataMap = new MultiMap(); - dataMap.add(CLIENT_ID, BimmerConstants.CLIENT_ID_VALUE); - dataMap.add(RESPONSE_TYPE, TOKEN); - dataMap.add(REDIRECT_URI, BimmerConstants.REDIRECT_URI_VALUE); + dataMap.add("grant_type", "password"); dataMap.add(SCOPE, BimmerConstants.SCOPE_VALUES); dataMap.add(USERNAME, configuration.userName); dataMap.add(PASSWORD, configuration.password); @@ -306,6 +275,12 @@ private synchronized void jettyUpdateToken() { HttpFields fields = contentResponse.getHeaders(); HttpField field = fields.getField(HttpHeader.LOCATION); tokenFromUrl(field.getValue()); + } else if (contentResponse.getStatus() == 200) { + AuthResponse authResponse = Converter.getGson().fromJson(contentResponse.getContentAsString(), + AuthResponse.class); + token.setToken(authResponse.access_token); + token.setType(authResponse.token_type); + token.setExpiration(authResponse.expires_in); } else { logger.debug("Authorization status {} reason {}", contentResponse.getStatus(), contentResponse.getReason()); @@ -317,88 +292,6 @@ private synchronized void jettyUpdateToken() { logger.info("{}", trace[i]); } } - logger.info("updateToken - finish"); - } - - private synchronized void updateToken() { - try { - URL url = new URL("https://customer.bmwgroup.com/gcdm/oauth/authenticate"); - HttpURLConnection.setFollowRedirects(false); - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("POST"); - - con.setRequestProperty(HttpHeader.CONTENT_TYPE.toString(), CONTENT_TYPE_URL_ENCODED); - con.setRequestProperty(HttpHeader.CONNECTION.toString(), KEEP_ALIVE); - con.setRequestProperty(HttpHeader.HOST.toString(), - BimmerConstants.SERVER_MAP.get(BimmerConstants.SERVER_ROW)); - con.setRequestProperty(HttpHeader.AUTHORIZATION.toString(), BimmerConstants.AUTHORIZATION_VALUE); - con.setRequestProperty(CREDENTIALS, BimmerConstants.CREDENTIAL_VALUES); - con.setDoOutput(true); - - MultiMap dataMap = new MultiMap(); - dataMap.add(CLIENT_ID, BimmerConstants.CLIENT_ID_VALUE); - dataMap.add(RESPONSE_TYPE, TOKEN); - dataMap.add(REDIRECT_URI, BimmerConstants.REDIRECT_URI_VALUE); - dataMap.add(SCOPE, BimmerConstants.SCOPE_VALUES); - dataMap.add(USERNAME, configuration.userName); - dataMap.add(PASSWORD, configuration.password); - String urlEncodedData = UrlEncoded.encode(dataMap, Charset.defaultCharset(), false); - OutputStream os = con.getOutputStream(); - byte[] input = urlEncodedData.getBytes("utf-8"); - os.write(input, 0, input.length); - BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8")); - StringBuilder response = new StringBuilder(); - String responseLine = null; - while ((responseLine = br.readLine()) != null) { - response.append(responseLine.trim()); - } - logger.info("Response Code {} Message {} ", con.getResponseCode(), con.getResponseMessage()); - tokenFromUrl(con.getHeaderField(HttpHeader.LOCATION.toString())); - } catch (IOException e) { - logger.warn("{}", e.getMessage()); - } - } - - private synchronized void legacyUpdateToken() { - try { - logger.info("Auth {}", legacyAuthUri); - URL url = new URL(legacyAuthUri); - HttpURLConnection.setFollowRedirects(false); - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("POST"); - - con.setRequestProperty(HttpHeader.CONTENT_TYPE.toString(), CONTENT_TYPE_URL_ENCODED); - con.setRequestProperty(HttpHeader.CONNECTION.toString(), KEEP_ALIVE); - con.setRequestProperty(HttpHeader.HOST.toString(), - BimmerConstants.SERVER_MAP.get(BimmerConstants.SERVER_ROW)); - con.setRequestProperty(HttpHeader.AUTHORIZATION.toString(), BimmerConstants.LEGACY_AUTHORIZATION_VALUE); - con.setRequestProperty(CREDENTIALS, BimmerConstants.LEGACY_CREDENTIAL_VALUES); - con.setDoOutput(true); - - MultiMap dataMap = new MultiMap(); - dataMap.add("grant_type", "password"); - dataMap.add(SCOPE, BimmerConstants.SCOPE_VALUES); - dataMap.add(USERNAME, configuration.userName); - dataMap.add(PASSWORD, configuration.password); - String urlEncodedData = UrlEncoded.encode(dataMap, Charset.defaultCharset(), false); - OutputStream os = con.getOutputStream(); - byte[] input = urlEncodedData.getBytes("utf-8"); - os.write(input, 0, input.length); - BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8")); - StringBuilder response = new StringBuilder(); - String responseLine = null; - while ((responseLine = br.readLine()) != null) { - response.append(responseLine.trim()); - } - logger.info("Response Code {} Message {} ", con.getResponseCode(), con.getResponseMessage()); - // logger.info("Response {}", response.toString()); - AuthResponse authResponse = Converter.getGson().fromJson(response.toString(), AuthResponse.class); - token.setToken(authResponse.access_token); - token.setType(authResponse.token_type); - token.setExpiration(authResponse.expires_in); - } catch (IOException e) { - logger.warn("{}", e.getMessage()); - } } void tokenFromUrl(String encodedUrl) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index cadde7ccac7c1..3090ffa00fdb0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -384,9 +384,6 @@ protected void updateDestinations(List dl) { isSelectedElementIn = true; } } - - logger.info("Added {} options to {}", destinationList.size(), destinationName.getAsString()); - logger.info("Options {}", options.toArray()); optionProvider.setStateOptions(destinationName, options); // if current selected item isn't anymore in the list select first entry diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java index 9a3924c4a8849..0ecd61932bd1d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java @@ -35,11 +35,12 @@ public class BimmerConstants { public static final String REGION_ROW = "ROW"; // https://github.com/bimmerconnected/bimmer_connected/blob/master/bimmer_connected/country_selector.py - public static final String AUTH_SERVER_NORTH_AMERICA = "customer.bmwgroup.com/gcdm/usa"; - public static final String AUTH_SERVER_CHINA = "customer.bmwgroup.cn/gcdm"; - public static final String AUTH_SERVER_ROW = "customer.bmwgroup.com/gcdm"; + public static final String AUTH_SERVER_NORTH_AMERICA = "b2vapi.bmwgroup.us/gcdm"; + public static final String AUTH_SERVER_CHINA = "b2vapi.bmwgroup.cn/gcdm"; + public static final String AUTH_SERVER_ROW = "b2vapi.bmwgroup.com/gcdm"; public static final Map AUTH_SERVER_MAP = Map.of(REGION_NORTH_AMERICA, AUTH_SERVER_NORTH_AMERICA, REGION_CHINA, AUTH_SERVER_CHINA, REGION_ROW, AUTH_SERVER_ROW); + public static final String OAUTH_ENDPOINT = "/oauth/token"; public static final String SERVER_NORTH_AMERICA = "b2vapi.bmwgroup.us"; @@ -48,12 +49,18 @@ public class BimmerConstants { public static final Map SERVER_MAP = Map.of(REGION_NORTH_AMERICA, SERVER_NORTH_AMERICA, REGION_CHINA, SERVER_CHINA, REGION_ROW, SERVER_ROW); - public static final String AUTHORIZATION_VALUE = "Basic blF2NkNxdHhKdVhXUDc0eGYzQ0p3VUVQOjF6REh4NnVuNGNEanliTEVOTjNreWZ1bVgya0VZaWdXUGNRcGR2RFJwSUJrN3JPSg=="; + // see https://github.com/bimmerconnected/bimmer_connected/pull/252/files + public static final Map AUTHORIZATION_VALUE_MAP = Map.of(REGION_NORTH_AMERICA, + "Basic ZDc2NmI1MzctYTY1NC00Y2JkLWEzZGMtMGNhNTY3MmQ3ZjhkOjE1ZjY5N2Y2LWE1ZDUtNGNhZC05OWQ5LTNhMTViYzdmMzk3Mw==", + REGION_CHINA, + "Basic blF2NkNxdHhKdVhXUDc0eGYzQ0p3VUVQOjF6REh4NnVuNGNEanliTEVOTjNreWZ1bVgya0VZaWdXUGNRcGR2RFJwSUJrN3JPSg==", + REGION_ROW, + "Basic ZDc2NmI1MzctYTY1NC00Y2JkLWEzZGMtMGNhNTY3MmQ3ZjhkOjE1ZjY5N2Y2LWE1ZDUtNGNhZC05OWQ5LTNhMTViYzdmMzk3Mw=="); + public static final String CREDENTIAL_VALUES = "nQv6CqtxJuXWP74xf3CJwUEP:1zDHx6un4cDjybLENN3kyfumX2kEYigWPcQpdvDRpIBk7rOJ"; - public static final String CLIENT_ID_VALUE = "dbf0a542-ebd1-4ff0-a9a7-55172fbfce35"; public static final String REDIRECT_URI_VALUE = "https://www.bmw-connecteddrive.com/app/static/external-dispatch.html"; public static final String SCOPE_VALUES = "authenticate_user vehicle_data remote_services"; - public static final String LEGACY_AUTHORIZATION_VALUE = "Basic ZDc2NmI1MzctYTY1NC00Y2JkLWEzZGMtMGNhNTY3MmQ3ZjhkOjE1ZjY5N2Y2LWE1ZDUtNGNhZC05OWQ5LTNhMTViYzdmMzk3Mw=="; public static final String LEGACY_CREDENTIAL_VALUES = "nQv6CqtxJuXWP74xf3CJwUEP:1zDHx6un4cDjybLENN3kyfumX2kEYigWPcQpdvDRpIBk7rOJ"; + public static final String REFERER_URL = "https://www.bmw-connecteddrive.de/app/index.html"; } From 1f0954567c5f8482acb6ec8966055a8c82916ab5 Mon Sep 17 00:00:00 2001 From: Bernd Date: Sat, 26 Dec 2020 14:34:12 +0100 Subject: [PATCH 083/176] correct readme.md according to code changes Signed-off-by: Bernd --- .../.gitignore | 1 + .../README.md | 485 +++++++++--------- .../doc/ServiceOptions.png | Bin 0 -> 34617 bytes 3 files changed, 231 insertions(+), 255 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/.gitignore create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/doc/ServiceOptions.png diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/.gitignore b/bundles/org.openhab.binding.bmwconnecteddrive/.gitignore new file mode 100644 index 0000000000000..fbee6f910ae62 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/.gitignore @@ -0,0 +1 @@ +/.README.md.html diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index a5edb7cfe588e..a97f147843927 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -2,32 +2,32 @@ -The Binding provides a Connection between [BMWs ConnectedDrive Portal](https://www.bmw-connecteddrive.com/country-region-select/country-region-selection.html) and openHAB. -All Vehicles connected to an Account will be detected by the Discovery with the correct type +The binding provides a connection between [BMW's ConnectedDrive Portal](https://www.bmw-connecteddrive.com/country-region-select/country-region-selection.html) and openHAB. +AllvVehicles connected to an account will be detected by the discovery with the correct type * Conventional Fuel Vehicle * Plugin-Hybrid Electrical Vehicle * Battery Electric Vehicle with Range Extender * Battery Electric Vehicle -In addition Properties are attached with Information and Services provided by this Vehicle. +In addition properties are attached with information and services provided by this vehicle. The provided data depends on -1. the [Type](#Things) and -2. the Services mentioned in [Properties](#properties) +1. the [Thing Type](#Things) and +2. the services mentioned in [Properties](#properties) -Different Channel Groups are clustering all informations. -Check for each Group if it's supported for this Vehicle. +Different channel groups are clustering all informations. +Check for each group if it's supported for this Vehicle. -Please note **this isn't a real-time Binding**. -If the Door is opened the state isn't transmitted and changed immediately. -This isn't a flaw in the Binding itself because the state in BMWs own ConnectedDrive App is also updated with some delay. +Please note **this isn't a real-time binding**. +If the aoor is opened the state isn't transmitted and changed immediately. +This isn't a flaw in the binding itself because the state in BMW's own ConnectedDrive App is also updated with some delay. ## Supported Things ### Bridge -The Bridge establishes the Connection between BMW ConnectedDrive Portal and openHAB. +The bridge establishes the connection between BMW ConnectedDrive Portal and openHAB. | Name | Bridge Type ID | Description | |----------------------------|----------------|------------------------------------------------------------| @@ -36,32 +36,32 @@ The Bridge establishes the Connection between BMW ConnectedDrive Portal and open ### Things -Four different Vehicle Types are provided. -They differ in the supported Channel Groups & Channels. +Four different vehicle types are provided. +They differ in the supported channel groups & channels. Conventional Fuel Vehicles have no _Charging Profile_, Electric Vehicles don't provide a _Fuel Range_. -For Hybrid Vehicles in addition to _Fuel and Electric Range_ the _Hybrid Range_ is shown. +For hybrid vehicles in addition to _Fuel and Electric Range_ the _Hybrid Range_ is shown. -| Name | Thing Type ID | Supported Channel Groups | -|-------------------------------------|---------------|----------------------------------------------------------------------| -| BMW Electric Vehicle | BEV | status, range, location, service, check, charge, image, troubleshoot | -| BMW Electric Vehicle with REX | BEV_REX | status, range, location, service, check, charge, image, troubleshoot | -| BMW Plug-In-Hybrid Electric Vehicle | PHEV | status, range, location, service, check, charge, image, troubleshoot | -| BMW Conventional Vehicle | CONV | status, range, location, service, check, image, troubleshoot | +| Name | Thing Type ID | Supported Channel Groups | +|-------------------------------------|---------------|--------------------------------------------------------| +| BMW Electric Vehicle | bev | status, range, location, service, check, charge, image | +| BMW Electric Vehicle with REX | bev_rex | status, range, location, service, check, charge, image | +| BMW Plug-In-Hybrid Electric Vehicle | phev | status, range, location, service, check, charge, image | +| BMW Conventional Vehicle | conv | status, range, location, service, check, image | #### Properties -For each Vehicle Properties are available. -Basically 3 Types of Information are registered as Properties +For each vehicle properties are available. +Basically 3 types of information are registered as properties -* Informations regarding your Dealer with Address and Phone Number +* Informations regarding your dealer with address and phone number * Which services are available / not available -* Vehicle Properties like Color, Model Type, Drive Train and Construction Year +* Vehicle properties like color, model type, drive train and construction year -In the right picture can see in *Services Activated* e.g. the *DoorLock* and *DoorUnlock* Services are mentioned. -This ensures [Channel Group _Remote Services_](#remote-services) is supporting Door lock and Door unlock. +In the right picture can see in *Services Activated* e.g. the *DoorLock* and *DoorUnlock* services are mentioned. +This ensures [Channel Group _Remote Services_](#remote-services) is supporting door lock and door unlock. In *Services Supported* the entry *LastDestination* is mentioned. So it's valid to connect Channel Group [Last Destinations](#destinations) in order to display the last 3 Navigation Destinations. @@ -75,20 +75,20 @@ So it's valid to connect Channel Group [Last Destinations](#destinations) in ord ## Discovery -Auto Discovery is starting after creation of the Bridge towards BMW ConnectedDrive. -A list of your registered Vehicles is queried and all found Vehicles are added in Inbox. -Unique Identifier is the *Vehicle Identification Number* (VIN). -If a Thing is already declared in a *.things configuration* Discovery won't highlight it again. -Properties will be attached to predefined Vehicles if the VIN is matching. +Auto discovery is starting after creation of the bridge towards BMW's ConnectedDrive. +A list of your registered vehicles is queried and all found items are added in Inbox. +Unique identifier is the *Vehicle Identification Number* (VIN). +If a thing is already declared in a *.things configuration* discovery won't highlight it again. +Properties will be attached to predefined vehicles if the VIN is matching. ## Configuration ### Bridge -| Parameter | Type | Description | -|-----------------|---------|-------------------------------------------------------------------------| -| userName | text | BMW Connected Drive Username | -| password | text | BMW Connected Drive Password | +| Parameter | Type | Description | +|-----------------|---------|--------------------------------------------------------------------| +| userName | text | BMW Connected Drive Username | +| password | text | BMW Connected Drive Password | | region | text | Select Region in order to connect to the appropriate BMW Server. | The region Configuration has 3 different possibilities @@ -99,7 +99,7 @@ The region Configuration has 3 different possibilities ### Thing -Same Configuration is needed for all Things +Same configuration is needed for all things | Parameter | Type | Description | |-----------------|---------|---------------------------------------| @@ -111,11 +111,11 @@ Same Configuration is needed for all Things The units can be configured in 3 ways -* _AUTODETECT_ selects Miles for US & UK, Kilometer otherwise -* _METRIC_ selects directly Kilometers -* _IMPERIAL_ selects directly Miles +* _AUTODETECT_ selects miles for US & UK, kilometer otherwise +* _METRIC_ selects directly kilometers +* _IMPERIAL_ selects directly miles -The imageVieport allows to show the Vehicle from different angels. +The _imageVieport_ allows to show the vehicle from different angels. Possible values are * FRONT @@ -126,204 +126,208 @@ Possible values are ## Channels -There are many Channels available for each Vehicle. -For better overview they are clustered in different Channel Groups. -The Channel Groups are different for the Vehicle Types, on the build-in Sensors of the Vehicle and the activated Services. +There are many channels available for each vehicle. +For better overview they are clustered in different channel groups. +The channel groups are different for the vehicle types, on the build-in sensors of the vehicle and the activated services. -### Bridge Channels - -If the Vehicle isn't found in the Discovery force a log of Fingerprint Data which helps to analyze the problem. -Please check [TroubleShooting Section](#TroubleShooting) for further advice. - -| Channel Label | Channel ID | Type | Description | -|-----------------------|-----------------------|--------|---------------------------------------------------| -| Discovery Fingerprint | discovery-fingerprint | Switch | Forcing a log entry to analyze Discovery Problems | ### Thing Channel Groups #### Vehicle Status -Reflects Status of the Vehicle. -Available for all Vehicles, Read-only. - -| Channel Label | Channel Group ID | Channel ID | Type | Description | -|---------------------------|------------------|---------------------|---------------|-----------------------------------------------------------------------------------| -| Overall Door Status | status | doors | String | **Closed** if all closed otherwise **Open**. **Unknown** if no data is delivered | -| Overall Window Status | status | windows | String | **Closed** if all closed otherwise **Open** or **Intermediate**. **Unknown** if no data is delivered | -| Doors Locked | status | lock | String | Status if Doors are locked or unlocked | -| Next Service Date | status | service-date | DateTime | Date of Upcoming Service | -| Mileage till Next Service | status | service-mileage | Number:Length | Mileage till Upcoming Service | -| Check Control | status | check-control | String | Indicator if CheckControl is **Active** or **Not Active**. **Unknown** if no data is delivered | -| Charging Status | status | charge | String | Only available for PHEV, BEV_REX and BEV | -| Last Status Timestamp | status | last-update | DateTime | Date and Time of last status update. | +Reflects status of the vehicle. +Available for all vehicles, read-only. +Channel Group ID is **status**. + +| Channel Label | Channel ID | Type | Description | +|---------------------------|---------------------|---------------|-----------------------------------------------------------------------------------| +| Overall Door Status | doors | String | **Closed** if all closed otherwise **Open**. **Unknown** if no data is delivered | +| Overall Window Status | windows | String | **Closed** if all closed otherwise **Open** or **Intermediate**. **Unknown** if no data is delivered | +| Doors Locked | lock | String | Status if Doors are locked or unlocked | +| Next Service Date | service-date | DateTime | Date of Upcoming Service | +| Mileage till Next Service | service-mileage | Number:Length | Mileage till Upcoming Service | +| Check Control | check-control | String | Indicator if CheckControl is **Active** or **Not Active**. **Unknown** if no data is delivered | +| Charging Status | charge | String | Only available for PHEV, BEV_REX and BEV | +| Last Status Timestamp | last-update | DateTime | Date and Time of last status update. | See [further details for DateTime](#last-status-update-timestamp) in case of wrong timestamp values #### Services -Group for all upcoming Services with Description, Service Date and / or Service Mileage -It's designed as [List Interface](#list-interface) so all upcoming Services can be checked. +Group for all upcoming services with description, service date and / or service mileage +Channel Group ID is **service**. -| Channel Label | Channel Group ID | Channel ID | Type | -|--------------------------------|------------------|---------------------|----------------| -| Service Name | service | name | String | -| Service Date | service | date | Number | -| Mileage till Service | service | mileage | Number:Length | -| Number of Scheduled Services | service | size | String | -| Current Selected Service Index | service | index | Number | -| Select next Service | service | next | Switch | +| Channel Label | Channel ID | Type | +|--------------------------------|---------------------|----------------| +| Service Name | name | String | +| Service Date | date | Number | +| Mileage till Service | mileage | Number:Length | + +If more than one service is scheduled in the future the String channel _name_ has all possible options attached. #### Check Control Group for all current active CheckControl Messages. -It's designed as [List Interface](#list-interface) to show all active Messages. +Channel Group ID is **check**. + +| Channel Label | Channel ID | Type | +|---------------------------------|---------------------|----------------| +| CheckControl Description | name | String | +| CheckControl Mileage Occurrence | mileage | Number:Length | -| Channel Label | Channel Group ID | Channel ID | Type | -|---------------------------------|------------------|---------------------|----------------| -| CheckControl Description | check | name | String | -| CheckControl Mileage Occurrence | check | mileage | Number:Length | -| Active CheckControl Messages | check | size | String | -| Selected CheckControl Message | check | index | Number | -| Next CheckControl Message | check | next | Switch | +If more than one check control message is active all possibilities are set as options to the String channel _name_. #### Doors Details -Detailed Status of all Doors and Windows -Available for all Vehicles, Read-only. - -| Channel Label | Channel Group ID | Channel ID | Type | -|----------------------------|------------------|-------------------------|---------------| -| Driver Door | doors | driver-front | String | -| Driver Door Rear | doors | driver-rear | String | -| Passenger Door | doors | passenger-front | String | -| Passenger Door Rear | doors | passenger-rear | String | -| Trunk | doors | trunk | String | -| Hood | doors | hood | String | -| Driver Door Window | doors | window-driver-front | String | -| Driver Door Rear Window | doors | window-driver-rear | String | -| Passenger Door Window | doors | window-passenger-front | String | -| Passenger Door Rear Window | doors | window-passenger-rear | String | -| Rear Window | doors | window-rear | String | -| Sunroof | doors | sunroof | String | +Detailed status of all doors and windows +Available for all vehicles, read-only. +Channel Group ID is **doors**. + +| Channel Label | Channel ID | Type | +|----------------------------|-------------------------|---------------| +| Driver Door | driver-front | String | +| Driver Door Rear | driver-rear | String | +| Passenger Door | passenger-front | String | +| Passenger Door Rear | passenger-rear | String | +| Trunk | trunk | String | +| Hood | hood | String | +| Driver Door Window | window-driver-front | String | +| Driver Door Rear Window | window-driver-rear | String | +| Passenger Door Window | window-passenger-front | String | +| Passenger Door Rear Window | window-passenger-rear | String | +| Rear Window | window-rear | String | +| Sunroof | sunroof | String | Following Strings will be delivered * UNKNOWN - no status data available -* INVALID - this item isn't applicable for this Vehicle -* CLOSED - the Door / Window is closed -* OPEN - the Door / Window is open -* INTERMEDIATE - Window in intermediate position, not applicable for Doors +* INVALID - this item isn't applicable for this vehicle +* CLOSED - the door / window is closed +* OPEN - the door / window is open +* INTERMEDIATE - window in intermediate position, not applicable for doors #### Range Data -Based on Vehicle Type (Thing Type ID) some Channels are presented or not. -Conventional Fuel Vehicles don't provide *Electric Range* and Battery Electric Vehicles don't show *Range Fuel*. -Hybrid Vehicles have both and in addition *Hybrid Range*. -These are Read-only values. - -| Channel Label | Channel Group ID | Channel ID | Type | CONV | PHEV | BEV_REX | BEV | -|-----------------------|------------------|-----------------------|----------------------|------|------|---------|-----| -| Mileage | range | mileage | Number:Length | X | X | X | X | -| Fuel Range | range | range-fuel | Number:Length | X | X | X | | -| Battery Range | range | range-electric | Number:Length | | X | X | X | -| Hybrid Range | range | range-hybrid | Number:Length | | X | X | | -| Battery Charge Level | range | soc | Number:Dimensionless | | X | X | X | -| Remaining Fuel | range | remaining-fuel | Number:Volume | X | X | X | | -| Fuel Range Radius | range | range-radius-fuel | Number:Length | X | X | X | | -| Electric Range Radius | range | range-radius-electric | Number:Length | | X | X | X | -| Hybrid Range Radius | range | range-radius-hybrid | Number:Length | | X | X | | +Based on vehicle type (Thing Type ID) some channels are presented or not. +Conventional fuel vehicles don't provide *Electric Range* and Battery electric Vehicles don't show *Range Fuel*. +Hybrid vehicles have both and in addition *Hybrid Range*. +These are read-only values. +Channel Group ID is **range**. + +| Channel Label | Channel ID | Type | CONV | PHEV | BEV_REX | BEV | +|-----------------------|-----------------------|----------------------|------|------|---------|-----| +| Mileage | mileage | Number:Length | X | X | X | X | +| Fuel Range | range-fuel | Number:Length | X | X | X | | +| Battery Range | range-electric | Number:Length | | X | X | X | +| Hybrid Range | range-hybrid | Number:Length | | X | X | | +| Battery Charge Level | soc | Number:Dimensionless | | X | X | X | +| Remaining Fuel | remaining-fuel | Number:Volume | X | X | X | | +| Fuel Range Radius | range-radius-fuel | Number:Length | X | X | X | | +| Electric Range Radius | range-radius-electric | Number:Length | | X | X | X | +| Hybrid Range Radius | range-radius-hybrid | Number:Length | | X | X | | See Description [Range vs Range Radius](#range-vs-range-radius) to get more information #### Charge Profile -Valid for Electric and Hybrid Vehicles -These are Read-only values. - -| Channel Label | Channel Group ID | Channel ID | Type | -|------------------------------------|------------------|---------------------|--------| -| Air Conditioning at Departure Time | charge | profile-climate | Switch | -| Charging Mode for Profile | charge | profile-mode | String | -| Charging Window Start Time | charge | window-start | String | -| Charging Window End Time | charge | window-end | String | -| Timer 1: Departure Time | charge | timer1-departure | String | -| Timer 1: Scheduled Days | charge | timer1-days | String | -| Timer 1: Enabled | charge | timer1-enabled | Switch | -| Timer 2: Departure Time | charge | timer2-departure | String | -| Timer 2: Scheduled Days | charge | timer2-days | String | -| Timer 2: Enabled | charge | timer2-enabled | Switch | -| Timer 3: Departure Time | charge | timer3-departure | String | -| Timer 3: Scheduled Days | charge | timer3-days | String | -| Timer 3: Enabled | charge | timer3-enabled | Switch | +Valid for electric and hybrid vehicles +These are read-only values. +Channel Group ID is **charge**. + +| Channel Label | Channel ID | Type | +|------------------------------------|---------------------|--------| +| Air Conditioning at Departure Time | profile-climate | Switch | +| Charging Mode for Profile | profile-mode | String | +| Charging Window Start Time | window-start | String | +| Charging Window End Time | window-end | String | +| Timer 1: Departure Time | timer1-departure | String | +| Timer 1: Scheduled Days | timer1-days | String | +| Timer 1: Enabled | timer1-enabled | Switch | +| Timer 2: Departure Time | timer2-departure | String | +| Timer 2: Scheduled Days | timer2-days | String | +| Timer 2: Enabled | timer2-enabled | Switch | +| Timer 3: Departure Time | timer3-departure | String | +| Timer 3: Scheduled Days | timer3-days | String | +| Timer 3: Enabled | timer3-enabled | Switch | #### Location -Available for all Vehicles. -These are Read-only values. +Available for all vehicles. +These are read-only values. +Channel Group ID is **location**. -| Channel Label | Channel Group ID | Channel ID | Type | -|----------------|------------------|---------------------|--------------| -| Latitude | location | latitude | Number | -| Longitude | location | longitude | Number | -| Heading | location | heading | Number:Angle | +| Channel Label | Channel ID | Type | +|-----------------|---------------------|--------------| +| GPS Coordinates | gps | Location | +| Heading | heading | Number:Angle | #### Last Trip Check [Vehicle Properties](#Properties) if *Statistics* is present in *Services Supported* -These are Read-only values. +These are read-only values. +Channel Group ID is **last-trip**. -| Channel Label | Channel Group ID | Channel ID | Type | -|-----------------------------------------|------------------|------------------------------|---------------| -| Last Trip Date | last-trip | date | DateTime | -| Last Trip Duration | last-trip | duration | Number:Time | -| Average Power Consumption per 100 km | last-trip | average-consumption | Number:Power | -| Average Combined Consumption per 100 km | last-trip | average-combined-consumption | Number:Volume | -| Average Power Recuperation per 100 km | last-trip | average-recuperation | Number:Power | -| Last Trip Distance | last-trip | distance | Number:Length | -| Distance since Last Charge | last-trip | distance-since-charging | Number:Length | +| Channel Label | Channel ID | Type | +|-----------------------------------------|------------------------------|---------------| +| Last Trip Date | date | DateTime | +| Last Trip Duration | duration | Number:Time | +| Average Power Consumption per 100 km | average-consumption | Number:Power | +| Average Combined Consumption per 100 km | average-combined-consumption | Number:Volume | +| Average Power Recuperation per 100 km | average-recuperation | Number:Power | +| Last Trip Distance | distance | Number:Length | +| Distance since Last Charge | distance-since-charging | Number:Length | #### Lifetime Statistics Check [Vehicle Properties](#Properties) if *Statistics* is present in *Services Supported* -These are Read-only values. +These are read-only values. +Channel Group ID is **lifetime**. -| Channel Label | Channel Group ID | Channel ID | Type | -|-----------------------------------------|------------------|------------------------------|---------------| -| Average Power Consumption per 100 km | lifetime | average-consumption | Number:Power | -| Average Power Recuperation per 100 km | lifetime | average-recuperation | Number:Power | -| Cumulated Electric Driven Distance | lifetime | cumulated-driven-distance | Number:Length | -| Average Combined Consumption per 100 km | lifetime | average-combined-consumption | Number:Volume | -| Longest Distance with one Charge | lifetime | single-longest-distance | Number:Length | +| Channel Label | Channel ID | Type | +|-----------------------------------------|------------------------------|---------------| +| Average Power Consumption per 100 km | average-consumption | Number:Power | +| Average Power Recuperation per 100 km | average-recuperation | Number:Power | +| Cumulated Electric Driven Distance | cumulated-driven-distance | Number:Length | +| Average Combined Consumption per 100 km | average-combined-consumption | Number:Volume | +| Longest Distance with one Charge | single-longest-distance | Number:Length | #### Remote Services -Check [Vehicle Properties](#Properties) *Services Activated* which Remote Services are available -Only one Remote Service can be executed each Time. +Check [Vehicle Properties](#Properties) *Services Activated* which remote services are available +Only one remote service can be executed each Time. Parallel execution isn't supported. -The *Service Execution State* Channel is reporting the state. -State *Executed* is the final State when Execution is finished. +The *Service Execution State* channel is reporting the state. +State *Executed* is the final state when execution is finished. +Channel Group ID is **remote**. + +| Channel Label | Channel ID | Type | +|-------------------------|---------------------|---------| +| Remote Service Command | command | String | +| Service Execution State | state | String | -| Channel Label | Channel Group ID | Channel ID | Type | -|-------------------------|------------------|---------------------|---------| -| Remote Service Command | remote | command | String | -| Service Execution State | remote | state | String | +The channel _command_ has the following value options: + +* _Flash Lights_ +* _Vehicle Finder_ +* _Door Lock_ +* _Door Unlock_ +* _Horn Blow_ +* _Climate Control_ #### Destinations Check [Vehicle Properties](#Properties) if *LastDestinations* is present in *Services Supported* -It's designed as [List Interface](#list-interface) in order to have access to all stored Destinations. +Channel Group ID is **destination**. + +| Channel Label | Channel ID | Type | +|----------------------------------|---------------------|-----------| +| Destination Name | name | String | +| Destination GPS Coordinates | gps | Location | -| Channel Label | Channel Group ID | Channel ID | Type | -|----------------------------------|------------------|---------------------|---------| -| Destination Name | destination | name | String | -| Destination Latitude | destination | latitude | Number | -| Destination Longitude | destination | longitude | Number | -| Number of Available Destinations | destination | size | String | -| Index of Selected Destination | destination | index | Number | -| Skip to Next Destination | destination | next | Switch | +If more than one service is scheduled in the future the String channel _name_ has all possible options attached. #### Image @@ -331,64 +335,31 @@ It's designed as [List Interface](#list-interface) in order to have access to al Available for all Vehicles. Picture can be modified regarding *Viewport* and *Size*. See [Things Section](#thing) for Viewport possibilities and [Status Image](#status-image) for possible Use Cases. +Channel Group ID is **image**. -| Channel Label | Channel Group ID | Channel ID | Type | -|-------------------------------|------------------|---------------------|--------| -| Rendered Image of the Vehicle | image | png | Image | -| Image Viewport | image | view | String | -| Image Picture Size | image | size | Number | +| Channel Label | Channel ID | Type | +|-------------------------------|---------------------|--------| +| Rendered Image of the Vehicle | png | Image | +| Image Viewport | view | String | +| Image Picture Size | size | Number | -#### Troubleshooting - -Available for all Vehicles! -Switch will log a *Vehicle Data Fingerprint* into the openHAB log. -Please check [TroubleShooting Section](#TroubleShooting) for further advice. - -| Channel Label | Channel Group ID | Channel ID | Type | Description | -|-------------------------------------|------------------|---------------------|--------|---------------------------------------------------| -| Log Vehicle Fingerprint | troubleshoot | vehicle-fingerprint | Switch | Forces log entries in openHAB logger in order to raise issues | - ## Further Descriptions ### List Interface -Currently there are 3 occurrences of dynamic data delivered as Lists - -* Upcoming Services -* Check Control Messages -* Last Destinations - -In order to provide all data the lists are organized the following way based on the Service Group example - -* **size** is the total length of the list. Read-only. -* **index** is the current selected index starting with 0 => list with size 10, valid index is between 0 - 9. If the index is set to _out of bounds_ it's set to first element. Read-write. -* **next** declares a switch for scrolling forward through the list in an endless way. Reaching end of list will start again from 0. Read-write. -* **name**, **mileage** and **date** declares the list item. It will change when setting new index or perform next. Read-only. - -### Range vs Range Radius + - +Currently there are 3 occurrences of dynamic data delivered as Lists -You will observe differences in the Vehicle Range and Range Radius values. -While range is indicating the possible distance to be driven on roads the range radius indicates the reachable range on the Map. +* Upcoming Services delivered in group [Services](#services) +* Check Control Messages delivered in group [Check Control](#check_control) +* Last Destinations delivered in group [Destinations](#destinations) -The right picture shows the distance between Kassel and Frankfurt in Germany. -While the Air-line Distance is ~145 Kilometer the Route Distance is ~192 Kilometer. -So Range value is the normal remaining range. -See the Section [OpenStreetMap](#openstreetMap-widget) how the Range Radius is used to indicate the reachable Range on Map. -Please note this is just an indicator and the effective range, especially for Electric Vehicles, -depends on many factors like driving style and electric consumers. - -### Last Status Update Timestamp - -A timestamp is showing the last Vehicle Status update. If this isn't shown correctly please check the date settings. -In case of Raspberry Pi execute *raspi-config*, select *Localization Options*, the *Change Time Zone* -Select your *Geographical Area* and afterwards the correct City. -One restart of openHAB service with *systemctl restart openhab2* is necessary in order to see the corrected Time Settings. - -Correct TimeZone is crucial for handling all Time information in openHAB and it's discussed many times in the Forum. -See [similar discussion in the openHAB Forum](https://community.openhab.org/t/solved-wrong-local-time-how-to-change/90938) which deals with the same problem. +The channel **name** shows the first element. +All other elements are attached as options. +The picture on the right shows the _Service Name_ item and all plus the 4 available options. +With this you're able to select each service and the corresponding _Service Date & Milage_ will be shown. ### TroubleShooting @@ -400,19 +371,16 @@ Please perform the following Steps: * Is the Vehicle listed in your Account? _There's a one-to-one dependency from User to Vehicle_ If the access to the Portal and listing of the Vehicle is checked some debug data is needed in order to identify the issue. -The [Example Sitemap](#Sitemap) contains the necessary items to generate Debug Data. - -#### My Vehicle isn't found automatically! - -The Vehicle isn't recognized or a predefined Vehicle doesn't show the right properties? -For this the [Discovery Fingerprint](#bridge-channels) is needed. -Short press on the Switch will force some logging entries which can be [normally found in the logs here](http://openhab:9001/) -#### My Vehicle shows wrong data or data is missing! - -Now the [Vehicle Fingerprint](#troubleshooting) is needed. -Proceed like before, shortly press the Switch and the log contains the data. +#### Generate Debug Fingerprint +If you checked the above pre-conditions you need to get the debug fingerprint from the debug logs. +First [enable debug logging](https://www.openhab.org/docs/administration/logging.html#defining-what-to-log) for the binding. +``` +log:set DEBUG org.openhab.binding.bmwconnecteddrive +``` +The debug fingerprint is generated when the Vehicle Thing is initialized the first time, e.g. after openHAB startup. +To force a new fingerprint disable the thing shortly and enable it again. Personal Data is eliminated from the log entries so it should be possible to share them in public. Data like @@ -425,24 +393,31 @@ are anonymized. After the corresponding Fingerprint is generated please [follow the instructions to raise an Issue](https://community.openhab.org/t/how-to-file-an-issue/68464) and attach the Fingerprint data! Your feedback is highly appreciated! -Here an example of Debug Fingerprint Data from a BEV_REX Vehicle -``` -2020-09-07 17:27:21.101 [WARN ] [rive.internal.handler.VehicleHandler] - ###### BMW ConnectedDrive Binding - Vehicle Troubleshoot Fingerprint Data - BEGIN ###### -2020-09-07 17:27:21.105 [WARN ] [rive.internal.handler.VehicleHandler] - ### Discovery Result ### -2020-09-07 17:27:21.116 [WARN ] [rive.internal.handler.VehicleHandler] - {"vehicles":[{"vin":"ANONYMOUS","model":"i3 94 (+ REX)","driveTrain":"BEV_REX","brand":"BMW_I","yearOfConstruction":2017,"bodytype":"I01","color":"CAPPARISWEISS MIT AKZENT BMW I BLAU","statisticsCommunityEnabled":false,"statisticsAvailable":true,"hasAlarmSystem":true,"dealer":{"name":"ANONYMOUS","street":"ANONYMOUS","postalCode":"ANONYMOUS","city":"ANONYMOUS","country":"ANONYMOUS","phone":"ANONYMOUS"},"breakdownNumber":"ANONYMOUS","supportedChargingModes":["AC_LOW","DC"],"chargingControl":"WEEKLY_PLANNER","vehicleFinder":"ACTIVATED","hornBlow":"ACTIVATED","lightFlash":"ACTIVATED","doorLock":"ACTIVATED","doorUnlock":"ACTIVATED","climateNow":"ACTIVATED","sendPoi":"ACTIVATED","remote360":"NOT_SUPPORTED","climateControl":"NOT_SUPPORTED","chargeNow":"NOT_SUPPORTED","lastDestinations":"SUPPORTED","carCloud":"NOT_SUPPORTED","remoteSoftwareUpgrade":"NOT_SUPPORTED","climateNowRES":"NOT_SUPPORTED","climateControlRES":"NOT_SUPPORTED","smartSolution":"NOT_SUPPORTED","ipa":"NOT_SUPPORTED"}]} -2020-09-07 17:27:21.121 [WARN ] [rive.internal.handler.VehicleHandler] - ### Vehicle Status ### -2020-09-07 17:27:21.125 [WARN ] [rive.internal.handler.VehicleHandler] - {"vehicleStatus":{"mileage":17708,"remainingFuel":4.0,"remainingRangeElectric":146.0,"remainingRangeElectricMls":90.0,"remainingRangeFuel":65.0,"remainingRangeFuelMls":40.0,"maxRangeElectric":203.0,"maxRangeElectricMls":126.0,"maxFuel":8.5,"chargingLevelHv":74.0,"vin":"ANONYMOUS","updateReason":"VEHICLE_SECURED","updateTime":"2020-09-07T12:47:08+0000","doorDriverFront":"CLOSED","doorDriverRear":"CLOSED","doorPassengerFront":"CLOSED","doorPassengerRear":"CLOSED","windowDriverFront":"CLOSED","windowDriverRear":"CLOSED","windowPassengerFront":"CLOSED","windowPassengerRear":"CLOSED","sunroof":"CLOSED","trunk":"CLOSED","rearWindow":"INVALID","hood":"OPEN","doorLockState":"SECURED","parkingLight":"OFF","positionLight":"ON","connectionStatus":"DISCONNECTED","chargingStatus":"INVALID","lastChargingEndReason":"END_REQUESTED_BY_DRIVER","lastChargingEndResult":"SUCCESS","position":{"lat":-1.0,"lon":-1.0,"heading":-1,"status":"OK"},"internalDataTimeUTC":"2020-09-07T12:47:08","singleImmediateCharging":false,"chargingConnectionType":"CONDUCTIVE","chargingInductivePositioning":"NOT_POSITIONED","vehicleCountry":"DE","DCS_CCH_Activation":"NA","DCS_CCH_Ongoing":false,"checkControlMessages":[],"cbsData":[{"cbsType":"BRAKE_FLUID","cbsState":"OK","cbsDueDate":"2021-11","cbsDescription":"Next change due at the latest by the stated date.","cbsRemainingMileage":0},{"cbsType":"VEHICLE_CHECK","cbsState":"OK","cbsDueDate":"2021-11","cbsDescription":"Next visual inspection due when the stated distance has been covered or by the stated date.","cbsRemainingMileage":0},{"cbsType":"OIL","cbsState":"OK","cbsDueDate":"2021-11","cbsDescription":"Next change due when the stated distance has been covered or by the specified date.","cbsRemainingMileage":0},{"cbsType":"VEHICLE_TUV","cbsState":"OK","cbsDueDate":"2021-11","cbsDescription":"Next statutory vehicle inspection due by the stated date.","cbsRemainingMileage":0}]}} -2020-09-07 17:27:21.130 [WARN ] [rive.internal.handler.VehicleHandler] - ### Last Trip ### -2020-09-07 17:27:21.133 [WARN ] [rive.internal.handler.VehicleHandler] - {"lastTrip":{"efficiencyValue":0.8,"totalDistance":14,"electricDistance":14,"avgElectricConsumption":13.7,"avgRecuperation":3,"drivingModeValue":1,"accelerationValue":0.27,"anticipationValue":0.87,"totalConsumptionValue":0.98,"auxiliaryConsumptionValue":0.89,"avgCombinedConsumption":0,"electricDistanceRatio":100,"savedFuel":0,"date":"2020-09-07T14:35:00+0000","duration":13}} -2020-09-07 17:27:21.135 [WARN ] [rive.internal.handler.VehicleHandler] - ### All Trips ### -2020-09-07 17:27:21.138 [WARN ] [rive.internal.handler.VehicleHandler] - {"allTrips":{"avgElectricConsumption":{"communityLow":11,"communityAverage":16.28,"communityHigh":22,"userAverage":16.46},"avgRecuperation":{"communityLow":0.47,"communityAverage":3.37,"communityHigh":11.51,"userAverage":4.53},"chargecycleRange":{"communityAverage":194.57,"communityHigh":270,"userAverage":57.28,"userHigh":185.48,"userCurrentChargeCycle":33},"totalElectricDistance":{"communityLow":58,"communityAverage":41269.29,"communityHigh":193882,"userTotal":17060.4},"avgCombinedConsumption":{"communityLow":0,"communityAverage":0.92,"communityHigh":4.44,"userAverage":0.64},"savedCO2":473.033,"savedCO2greenEnergy":2782.551,"totalSavedFuel":0,"resetDate":"2020-09-07T12:00:04+0000","batterySizeMax":33200}} -2020-09-07 17:27:21.140 [WARN ] [rive.internal.handler.VehicleHandler] - ### Charge Profile ### -2020-09-07 17:27:21.142 [WARN ] [rive.internal.handler.VehicleHandler] - {"weeklyPlanner":{"climatizationEnabled":false,"chargingMode":"DELAYED_CHARGING","chargingPreferences":"CHARGING_WINDOW","timer1":{"departureTime":"05:00","timerEnabled":true,"weekdays":["MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY"]},"timer2":{"departureTime":"12:00","timerEnabled":false,"weekdays":["SATURDAY"]},"timer3":{"departureTime":"00:00","timerEnabled":false,"weekdays":[]},"overrideTimer":{"departureTime":"05:00","timerEnabled":false,"weekdays":["TUESDAY"]},"preferredChargingWindow":{"startTime":"11:00","endTime":"17:00"}}} -2020-09-07 17:27:21.144 [WARN ] [rive.internal.handler.VehicleHandler] - ### Charge Profile ### -2020-09-07 17:27:21.151 [WARN ] [rive.internal.handler.VehicleHandler] - {"destinations":[{"lat":0.0,"lon":0.0,"country":"ANONYMOUS","city":"ANONYMOUS","street":"ANONYMOUS","streetNumber":"ANONYMOUS","type":"DESTINATION","createdAt":"2020-08-16T12:52:58+0000"},{"lat":0.0,"lon":0.0,"country":"ANONYMOUS","city":"ANONYMOUS","street":"ANONYMOUS","streetNumber":"ANONYMOUS","type":"DESTINATION","createdAt":"2020-08-12T17:03:35+0000"},{"lat":0.0,"lon":0.0,"country":"ANONYMOUS","city":"ANONYMOUS","street":"ANONYMOUS","streetNumber":"ANONYMOUS","type":"DESTINATION","createdAt":"2020-08-03T08:15:20+0000"},{"lat":0.0,"lon":0.0,"country":"ANONYMOUS","city":"ANONYMOUS","street":"ANONYMOUS","streetNumber":"ANONYMOUS","type":"DESTINATION","createdAt":"2020-07-31T13:09:15+0000"},{"lat":0.0,"lon":0.0,"country":"ANONYMOUS","city":"ANONYMOUS","street":"ANONYMOUS","streetNumber":"ANONYMOUS","type":"DESTINATION","createdAt":"2020-07-25T11:20:18+0000"},{"lat":0.0,"lon":0.0,"country":"ANONYMOUS","city":"ANONYMOUS","street":"ANONYMOUS","streetNumber":"ANONYMOUS","type":"DESTINATION","createdAt":"2020-07-18T11:22:37+0000"},{"lat":0.0,"lon":0.0,"country":"ANONYMOUS","city":"ANONYMOUS","street":"ANONYMOUS","streetNumber":"ANONYMOUS","type":"DESTINATION","createdAt":"2020-02-08T11:06:52+0000"},{"lat":0.0,"lon":0.0,"country":"ANONYMOUS","city":"ANONYMOUS","street":"ANONYMOUS","streetNumber":"ANONYMOUS","type":"DESTINATION","createdAt":"2020-02-02T14:07:54+0000"},{"lat":0.0,"lon":0.0,"country":"ANONYMOUS","city":"ANONYMOUS","street":"ANONYMOUS","streetNumber":"ANONYMOUS","type":"DESTINATION","createdAt":"2020-02-02T13:24:36+0000"}]} -2020-09-07 17:27:21.158 [WARN ] [rive.internal.handler.VehicleHandler] - ###### BMW ConnectedDrive Binding - Vehicle Troubleshoot Fingerprint Data - END ###### -``` +### Range vs Range Radius + + + +You will observe differences in the Vehicle Range and Range Radius values. +While range is indicating the possible distance to be driven on roads the range radius indicates the reachable range on the Map. + +The right picture shows the distance between Kassel and Frankfurt in Germany. +While the Air-line Distance is ~145 Kilometer the Route Distance is ~192 Kilometer. +So Range value is the normal remaining range. +See the Section [OpenStreetMap](#openstreetMap-widget) how the Range Radius is used to indicate the reachable Range on Map. +Please note this is just an indicator and the effective range, especially for Electric Vehicles, +depends on many factors like driving style and electric consumers. + +### Last Status Update Timestamp + +A timestamp is showing the last Vehicle Status update. If this isn't shown correctly please check the date settings. +In case of Raspberry Pi execute *raspi-config*, select *Localization Options*, the *Change Time Zone* +Select your *Geographical Area* and afterwards the correct City. +One restart of openHAB service with *systemctl restart openhab2* is necessary in order to see the corrected Time Settings. + +Correct TimeZone is crucial for handling all Time information in openHAB and it's discussed many times in the Forum. +See [similar discussion in the openHAB Forum](https://community.openhab.org/t/solved-wrong-local-time-how-to-change/90938) which deals with the same problem. + ## Full Example diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/doc/ServiceOptions.png b/bundles/org.openhab.binding.bmwconnecteddrive/doc/ServiceOptions.png new file mode 100644 index 0000000000000000000000000000000000000000..5458f866b0e2e9f70ba0865b8c9154e9ce7e41ac GIT binary patch literal 34617 zcmeFZ2T;>rv@RMcq6qRA6hWF&r6Wa}6b0!;N_{t_=TE0De*mG2n0f^ zs35Befe<``K=2c;;el^H`f-hcw=2$?^3Nbe{j{s#1A)a;)u#|hNyLpaV?yxxx`TqA zGX!$875DE-r~Ow`2qdsyQTC~}J8Tm}$W&>L)po_H{3%<#SkpWCGmix>XWpvW znF{r&Iv4MIH1f2HTJ-m(h}V=X=O+kc%m_6~HN?^It2u+e;>i{qB9`^ZYHkz2;V=Q>nRqCxg#o1@?A4zc^x~&l8>+jUsY`KiN0b zyNjWMeS0>1(AH0y;(Jmt)`vRv=Z()=pyQ-QtXKa^w9wA48~ns6V_}%NZtgXyZ!mBn zxh-Red~Z~nTeLYggR1ub)ZG!ph3?rKkFT>+B5l9c{K z_mP_4JrM}beS#cbk~Hrqjn_p)c!{=?eXb=3yq#4Ix#kSYqY2*UZ1_uBrcy2vmqu?+ zUlkjKx63%kd73@f85ut*1A%0}lHSX7zw<*{CBR7n(?>p1ChPRM7e*R_NYHs!H{7qK*aMHk;xpeAJIj(QHGZ=kDB3E$HfoLGq##J$tgUaN3_ z7vs#VtMK%uZC|=0ETc1wRIW*pbt6zFFPA9)i(L2yi_o}jpOXqN_wx7PD;_h+Uh-v2 z-(QCxWYJ2lzuV}Mn&oC(Wp3eHG$`$Fr{#^$Dez#ewP~Ve|+6!G|IYa`04&5T&YcBH#IPh8V9mvQE7%CFnJSX-~~5+wZetOunJ| zC54L(o8;s*D{q@~_j*efFetVG%*=5c@4~vFOF?G&cl$V|^$5KKqEk4^V6DC`;=X+j zk&OBAZ4Ajhy<2Yh=_$FwuEI{6X@#xt4Jhusa)7-ZRPxYb8@)5LE4SYsl))=yE<_*u zl2PM9iSzq4H}fvCM-3NCzmf)+4{bD5A%0gJQVAexn!7)?+EV+%Q=;F_rSvH{()I+q zDj|%{1g}5HtI#)UQIQZf3?HngV4|){}O^ zibc?wsrppOVq*pcL4T0SVMzYt`+1UlZ1kwx(NDg~bbH=64d=#AL~u5&LbuaJyj3jU zZdGeK6mxR2qr##q+JzejG1k)NtM0-)6O~?(ze6Ir=p(rmwQVEMhL4YUwb>xj_wJ)0 zP3+e`xEu#*Gj@qvJl33IGMXH6zVQxao|kRc%wD!AJ#J|YM_wQK*=P4P$~}YVU2abm zbMN;!Ds*?!+LX*?0hjZXtdRAFJ9qLD?CySlZg9h{v zUAr~28;J01<9n~QLd1~`a0eM_UM18y+E^e)7gx0Y6pOkktEqRm#L#uQFLmeaz-=+c zcT&p2aHm{EvW-ugP^ z)r<9|zPt99f&1v{onb3D7GYNSU2HqUSNBi#rMfvcazNkNbu8=pv>kI!c~Xg7`i?5MnjZRn7A`f@A<;iS!8IBK7yOAjSk;= zQ@+n}fn|g_-_66~)l}J|%1ya~7j5gTQ;xj;pY_3tYfTOKj1tPJH9&Q35jk#w(wbrS zAkII-q-CPNPDD;sLEj~$O0m{$DAj*fco!ykb4g7H88?N}AXhZ!?yvbB=tH)Jp>kNT zZPv3`pZjQ&WGW>QeJ8nE#A%$n{v^o^g^#l6k^ezr0I!XEc2M`Oshki-GzUvFk5|*( zzH#`Zv}Ge-iX7%t5@pD2NOOGey9c|l;eeCd_p=vHMdx1^DUSQQ)JHMMjk-VSF;O9Q z`;qjn_TV7X5OsH^)p)EkrX|^cy z2zBb#ycc}jke+zeY>`ry$2(25`TWJv_DqqzN!K7xjBCjk{8A7NfhIKkMuU zs|>&C-&=Yq#b=zT!g8&B+DEOAM%!yRAB{;8>Wr(WO3Yy}`czZoS@FXV-SsYd)?}>dfl&{4(LmH!YL{BLeycW*mI>Sv>8?&?BVs z@;Gj>Ii(bV7vp?duZ0H*WyTq+M-BBgo&LV+3kv_8VQnq4U~loMjI#n8d)kk*q{^&O z?|t;cFT`KfOG@aG3MDSQo%<*XuhYilieGCG^>Bz2R(4zH=2GNB>Q7zt9l)Kptvdqy zyU=9ZVp8Qs0lKOiFIR33$1xohBp2)zIcD^brXl|(sT3Xz&i($Y0akGEB|7R;Q?DD=6w=k#57hZOZop31p9Y?Q78 z3Z^T8cT>_%n|ZVCq-|nVA1@K*tfTS8Gn2-sW=eEgQW4d!u$X$yjf}8CT?X|4b!^b& zAZyRn>DA@wVyw%cjspEoszf4B9;v5)jH8g{gY-{AF5hnAs zK@A0NNJok25o=|L(c%Mul);MhQ{zt9xTTSuCJFTUn_9^?pA4UvCJ zbP+7T5=mge{fIb(C97+$V9k-Mb}ka7qR{_{xUshM}0|w$dIF_cl zS3{WH3zvWWJ%ZAanFGM-Mr}UPE$`LA!x=B$hD}xMydYYWusyeyCh2+Bw2);pb%-XL zm6P33x$tkp?S{A9?e+Ce5rQlXZCecv{axJGbZYRQ;Q_X{$NY8wbWf-wbcAUOq323; zx<%mjj|SgE523oFmY=b*IvB3%epRhbyX%n9Cpi04M9b8QU+!Dye>rU`|NQU;Y_%e% z>p=mQ$Vc(6e|NS2PK?t>cJ}9`pVk};OgEnjL%JOI;x(}?+}G)Yrk7#eV)dodJ zYjEK+jcJLvFFCaA4vsa#I@RdW}EunJ%zPxwh9`p)-wXY}$|uE*EwIm}k-JbUD2 zz8hIU)nvF*!6$`%4i4A5ab^*2r7bsTY#T39u|bzcOH%;NhSrC2zg*)Lo2i#6Nm{B@ ztb7#G89ZtIrR0A0#BVnfhswXcttOq0>4C7E}6! z`j|f?jts)0Z~iQ0G=H9j7+y^0w{(fyv@ZzJdpTdPJ9BVNLVSiUmr?XvR>{g^ci!4U zy#su|Tc2>qs2<*v@)m1JFziC+aH_C@S#znVZOzW%=IdcaKh4RE_UC~iLyfDxmzhGh zoJH}Pe}0TwY&L-BBaEz;@6xoJA@vtUYGS~}qlk}uqo>GuAJ238bx;aVMejJmJ z-e{i0Ki&rsTUxhWnFPI!9VWa+OuA}N={RAn}~uY%wemxrhIFoS{f zFNo?ZXtMTIn_<#nTJdSRbz}->GkbO8Wz(wMt;zZ`72z5Nj62u%Rs3)h7I@Ki1@*2| z8XG=@=^lvD)KY1SX~wr)C7s?*?ormTqrE3F`X<$690_^yyO|N0w}pzObXtwE%er5_ z31_z1*(woIVHtTk9m%ryLNI!mRkPnGu>=|BsZ)jQXqD zY5yqN0iNagUhrL6KmDKSHt%>dl+0dS^*GlA^-PW2yebyom`n6To%Frv1G_*MXaD(* zx~(!wImdRzdXl$wLx2s7Y z83ee&AZhjFcrHI{EKaA5S=y@5Qq6uUSTopS(bOAvlC`6=jf_q=-|x(mn1yBBA*uCm zu0%|)jpY@?$sb8Xv*bG=uiGc1e?0GRlw8T4)HK<_SS0hlUJdvC*ja~f9p&9_Xle)# zaciSZek`@JMn*%}Ub+*ENn*a26_~N_)n3)Wo>Jdao|#w^qRR`uujedYbPk{-J?PH= zqqjoivGq9-IEiU@PeoQWEGDRLm%USB3F$f*R?Tqq3`ALVD>Vv~-3=$LTXd0T?=w;k z2RquPZFR6=!F|ZmjeN<)t-Y;eYFG^iHdZ_knNrY-NRfRVv3Qjuo5Y7)Wtx-yblfpC zeW)vId(Y<|{=SC8jOK)p#hwNCDxD<3Ryw(Pi~)C*wB)n?Q^^G$G6++mhlgb>2Oi|A z`R&_i;~K=9%+Dg$<4e25yiW$av%eIHr)-u~r7F`;vHT5koZQ#w3%B;@pUt~e5U~x6 zGKp?ApN|UZgdwvhX)CG-b5<-Q3=l%G!r?%z#_uiw- z(TBA`7uT;pBdWLCs_)6}!@_g1#C?Y5!aoUE2f%-dh~91ei4jiSl`J?tYkSdF`%QKJ zQxevbq;V=rS)>|qsB{en2V1) z`Z>AlROjopnyQ&PhOb;^bh(b(%5W~W={w2%on7c*{0G-jTLbGURF<*PJzU2wxeO&E z4k9l!*i*vlo*h5^5CRV-cckE5I z(p2qhJ9htU!~{LmsF=2UvN2uP!&knw;3V1=-tfn0KOjh(O!Tc?!Dhp1taw{X2@-B% zuwTI@mew$kg!sh#8Vy5YV_LU<)Gc`z8?Gr1a68~Diu9BewiSg*NELi|v`rgDb912j zr}ai0)U8RP`gVwCTG#olwsdr&cS^)12_Rv-#OMO z5-q_cb$dHej9p*#03<@{4t>z{zrFTzg6XVT^w5kocHK#@g0PeFG-h^Q!|Nd75(BNB zk;pf{Iu&Wc!d(4)=Ax`h1QKd=Vz7tN8o?!#W^aJp(tR!J=L@|hcM_*(QVP-y(B3&N zhWwDGZ-7`p_@ThfKU3y`r)>-dVYJ5%*SB+tA@}S5Ef@7@3)jqlVW#Te8vcJwa_!eH z-~Gx6fv`P~Sd4$Z5cfEA&Bv_T zR7{3X6sm$~FF&_`b?rBd0%9bH%e<+{eSY&vPqLj>7|lgzzZj-b$kt0zy(qpwa*uY%@}o#5?gKGGqbJ_0{Dz6OidZ5y6=c?OeqsaF;IPS`C+( zmv>m!YhJy<^66{#9OE2wiM2_(RXxF-5dsL6BgpajT_NnwAz0xd?SrLLH%wEsS1wG> zsM&Z6c*OVAfMgx6m6Kb^4SeNB&y89Hq3UGlH4I2>u)uA#T_H^$r9pm>mPy1}!+qzu z`6>ZaT}sE>74Wa%Jkq?IkS+&6XZ*FrT2 z)4m1adqsWxJSxP#_m#(H?#zhWudeJs^EBIV_LA_QA|*T{#E>p&&=S>VO9*e5&p>A{ zk{CMh(A?4E?Hn;Tb(Iy_S5}C0HjahOjOJa|f6!lTz?aU(B@P~v zQ%MP(o~XySo8?J9qxLX)CqOxIFap;v15IQ;!Zkq&)&+2k@AUWXTyCs?ad>-3UYk2@ zm!}0%EH2MkulQ*^5Lrpy;Jkb`>^jTs!YTqz#)zS8xGZUZ~RUjv3omuw%|66(L5 zZ!esnPZ>&`P4D9NFe$D_vX4F~mGLxaK=~l!&r3732_dt>xF%}O*_|q zmw>hZ#T^nQc=QGj=;#rS6Eb~>GQ2IheGl6FPuJG`XcHvzCNOWlXQqYUk@=NsA2)c$ zE%Wdof5-sckbBpZnE-q&lu(9MTos;@2Z4A!!}aifol6YI96`xCq{$78u*)4>Fg%}6TU;dC;UeHm~%Gvz@ob5L&M$tX2)d1JEhJzj@aD!-% zWA64hnk!B6xYmsPciH`~4{Hb}B3HgH}gB0i+R3$bGHVzqSBv zW=Ey4*J|V1`-p3gLu8MuZ#HdbxRY%EoO$mN7S)n+;WRf!oK9Gsq}4{1lDGly0CoOzM_ zE(T--cwb&TtV+@zdD7^5eoVI0XAkVg=w+QpIUlIw`LOtq1vHR2b0DI zVyt~?m3fi=xz->AA$c(E@$vD}(vnGMc+5j&TwL6+>b)Dp#GgKW>IkK#APy+78RAIx0bEHqiC7zL-UUMN(*2n3V8m~9v;U(?9*AQv(nSkzkh!@ zGVHej8%G1v6xjm?8)@8|?wA*SHGS|ce}Z<58_zg#(6IH{xuQaT3JHXX9#}7b=p*w2 zjx7I|T%&uHje*9Q1K%RGqIATmA#zV}=19fVs1P&c=eogkiv^WA(iMq{{r5i>zld?@ z_=dV-Bm(>#=->EpUbN4KT^iM3Exl!=t04+xQp(6|qfIFztUwv2Sz_V<}7?yzhBikumCP zem*KU&my~g0uAAt|Ci_bf9A*vIy*aqVJAMxWsHoBPegwW`M$31 zNid6qe9T8#MvY-^E%o@!akZ;{QDMN=MWA2}H&4IHb~;W>PGYxb3=IvX`0Y9fAtEw= zTi9?*(}-tvG2rFp9q8#=_4VbYKIXS(1Kx@W*J_D=k~X`u0)LbWBRX^Y{9XOaq3KlEn3CB%=wUC;8IhO> zGiYR~m{7?93;yo7;F-c#!j)fAqLH1KdX?V|w1o4mpryn$ZFYgBm6f=dn1g%9w0&q^F@VVkizjUkT)p&i$=c1YnjJ%~^p8$%h_Jo_q`JRVqXZIEkAHU&dRZfY1Dp!d*e=O!zO%YAt zWn+w7Q#hetC~h-^;tC2e{HO&HFvt8**W&s81@bPKLJCcXzZoI^~h`YGE@&I?wTdV?`z|gSKVjwj!@gADy{Rfo$ z6WAnof(j@{jE|3tii+mVr|pktLHP21yY=zDcn$_OC^L7aep$A>{@vmF1MjrPtuP%j z_#RJZDVMTS$Zza*W?&c#oe|i}7Vb&A^J3q{KywJ+nFtO#mBLd28Pth!nHLE+jd&|K zF**t_Pr98sVSoR6P^+1l*(x7W7S8HV0P(^>GfC{PlWY#N`vzk-Zror~OQs?Y&_)&W zds^U0%i(P7sxtj_T)}i9htES^UIuZvjRZ3HyVBTrl0htSn>-872dc(DPRGR zSq8AQp|qg#$wIcJ{U7;^(pU(YGvSycng>aj1sZ7tuxTV)lC+jFAeG5M<+s5&u7M*o zG&n+&coZua4XLv zu0h|7!lVP=T8>-5D72mJn&+-?;=)%kT6y?2;Y&h4K_CF|yT$48R(&PSr;sBfb%S{P z0eGwe8`w@%X!6>}a7kxCGT)R^nCjw4X5YV(1taEC8mr{+QNWy`4Bj=Vr!sHWlW;dm z;ch%GU<%r(Tn43wJjulG77EwE#7~3S=i~TADg@Uua5%wJ9fJ;kToC~wq-(lW3b=C! zhre<+(9EM>BtUWF;KfU!u-72lyJ8}xzBN;{28gU2=&VMYoweH5v`uWd@NUP~?5Kx& zWx9C5BQG+*1^c)Q2HS&OSt{$z78et;D71&W$Y;(xS12wy8MH>OKrAD`T4!iD%{VlIskmUtdjEk`5z@+;5;4}#!6%)^=Ix;L%>gnb+Y#nSs z1EquTF@ml_@QI_=gj2 z>mMwjJ?sFo{RzJ+9)Sc!aHlqiV%u<``u`c4vdqc8`(!17VfInDtw{eX>R0W^>RYWs zh+k9)&UI7!e_{s(Y3C{CGMBU5nY{mNto!;iAtd7lm>-9{eT8s6!G0=%(Jo&8UE+fc zFD7KZ+4Fs)mt+J&GH&AI;V2c6;CRZ-(%OlXex2IQub2r_VFuuX+@~HuLd}7#ftSzj zfh5>LU?>t`DB$%!qGS0F*#VHqxPgmc$pe;oZ}h)d)@J`u4>780z_uv&0txj8+%ShDK9eouD#UKqh6Qv+@n=3x2`v*PzBvf6c0< z$ozK={WWUBb~!Z|sCJF~t^(zv$00pawl@Mc1Mk&VDE2`hp)NQOW70C}-srl+AgJ8g zqtRf(wwYZ6`@@t(-;tE#oQb=Q_YrXDRvt++Dj}kZeL3r`#Ou`h3Q#a{KcwHu{i; zKYRfF|0U8Q4`6!5_waJtrJNOBur~pLDB$ElRD*aAKn)yv6>^{Z5#Z5spPSlNqk5#? zE-s40`5O+iep~x$3j{XNS(Pph0UP#IYp}a2*y%X`DF4C;Sb2TXl^gw%;!ZoNo_xu; zO%`kzsQda(V)aWhdBMJtdpAKgzs8uAYi5ZCf9Xc4<+p6jYLBY(ksBq!S z@L<{qJYSiN5dTKHWubH4Y zt?V3qVp~=9RSlqHbG_dcBZ5->q{UwtF0LqTqgb^_7h}5Ve7)F22|m%Sf$C-6_ruGp zdgGp0M_+8%dwjX4jsU|%+v1vjU;?nO$q~fbHECk5rwd!BHgzdwf%JdY7toKj_F@F(CG%o~sp0 z?(Hw*l^U9M!eh_VeECjxO}6mmCiDd-`9Z~wIwPN{+PAh!LFw&uwSVrO=_CN3-<%Q3 zJ<*3uDS)ML@B?^#{@bAk^Uy7G4@x&vQKs34!Z?E z_Ma!lM7Mg5tiA-bbHUDVH!jYGrLg`^AG?u_GMbyp<_;9^Y!jAH2Sy45{p#9MzKq9|cxtUtfv zXtgeZ1#fJO$YB33Yu^peL+o@QS~*?KYi~VQnmk@a!fR_uj#<7`2`8W_zR-9)eSR(I zkh!waHk8^roc*Bxk{N5eM+wp@_#NNzn?9NekGMYhvjEKBMQjoSNN4*3V_bt27T@ri zO5!+X$>0m&isD-2vt1)7Nch%uME{ytDP#)DG+Mk%$g$!X#!hZREk>)J1C>w@r z6U$x1!$LrfCTyOcUBtEzWR~kXe5g&7-VHCW1NBy$iFInYt^4!7-|9dKBWLH2QfU*e zL;iB?9Wg{k&+E^))J&MM5!6VrLhgIx{MUz&`g5GoTTmPHqQAdBD~9+&l`=JXay>3=M2;=^k>+LC;Ldzt*3&WgED&lpOi)> z`sj+0C|*#Dg)0k>Or*{JJobcrxy^iwlwM)#7E}Au?rQR3Y+I_2lbX{E94orR$jQd% z=;=lSaKmAS8$!js_!UzxG+My2h55>?z>L~C;FU8xMF|V9WH%D4#4pDXEr{$CS_7i- z{!^jYe=GD>-#8Vxe}jgFeb)63T2&bq^7thb!zCyMno&$%x@7qm|5 zw{=WM`o2^v3r&JK5(P#MGik&_nVT9OUJ+iSji3mD*Z;X6VSB}Izu5zT8h4#VmD`hD zsjd62orC!Pv&qhy79^n?uZtaMw`?msFSi`tU{)ATA{Tt}b791uKE@8Cgm>W(i=cV!jm3)m&^9jh>^p< zvyg42ni-Q4=SAFth+vHu1$yYktv-CxK5QmsoE<3tZ&&n57@{Tg3uLxldQ~t(n(UL= z0DEJ<# z_#&cb9lv&9J(k8JTU9jHS)W%Z3E28bRP<-FZ*-P~)86xPsqM5AUxS&O6HLixkaXKw zAF6r(j+$!9)PpfW?la-+R8TWRp0-os_crTXvjjAK9Z4GsG>Z$CQNOBM72EcWy10s6 zim7h|rnn0}DrfufUH?vmQZrWyRr2GRzXgyVc564K<`e*07vF+J-olYkynumvF6{CE zaOqkHCT4|o9m#w$#A;8>N9g|Cqd-)OZDJxQ*dKg{X1uW-sM*f`y9_1U0x}EYF|^nF^rT6b$KMj(q#&8$F3-_^7o@t;OdGJ<=fjJ2)ZY>BAGtJ$woaD!uVi z+btaf2N{r|W*c2Ss9L+3xWJkiV6rq!*v(3q!yUOPyc=TLH%G|Hc=z?)#4_0%ACQR0 zJ^JpPL;&vq=L(euiO=3o>@{}319Rn_deb#UdE(+8bgqB-Cf@cWLB+;b{A7q}`nyAf zt9zO`6*>LB^b4}UzM<>LE7~Mo+|f|WlDBWhI)0uP2gWOYD0rd6XwRLJGMfFHMm?|d z?jhfg31+VGK6y|VU=r7D2|T@jj4u1Bv$WV_QKElOOWhU(2wOhAXK#-0lbd8lU~es! zDP%_7gez-#O(r&M--P_ZMe%a?Ys(CjSr?CBWCYB&6hxwemqo&3T*O|XPAi`q`fxSu z#H9MSnb1w3K>eT0qI!izWe=0J_`+u;uqele(-}HOfo2B5%V($XC}Fu#5EBSA9Fq!V z1U(%Ex;(bLQPG{R^ym>8Jv%XE!MsmwY+I2k(D8a>I~rm^BxzqIL|sj|%RZI5CI2n! zJ;vc-!&X3%g|GVkD}FAm&Qmxc_EGTvnrau=72x$BYiz6kl4O7c-Y;ES{xOvW8&_bF z7vEs6DU6q(cB<0GoQXl5g*D%eh;wB^)fGK~ues@Y@f5^zPRB%9?Oo_N8>aJrRfc2o zJ+MeVwp%DOU}t|-9p8JBZa}D-|FtOPxA4em7f)*?kh0(#jn&2|t7X)g(a08=N^;b% zijoC4w^|L;wL0l>W=x6x<*DI(5)756_k^d~zBcwFVNRd0G6y-Ls$%98pQ)IS&o$gG zvGgMWa(1JArz&;beYO*hPfLHJ4?L7se;K-SPVZ!aoM>A_0JWSukX zxzmOzVD3=SSd8`xskowcp>vJcLGn8=J^tvj0vSYoPZNkTS>bjYTcGcE{!TIK$@l!t zoS6-;6PQFX-{qk_fkj%O`M#;%=-^eTWGrSdPYDA!lmwe0S-@sx23Q-uZUChaHl`A9 z+m(ezhxw8p8!UON+AkGzGM>j=fn<>2f-&UOmER>iP*FlP`Fs;S^Knz?wxmb85{P2_ zKuq^{$vhZNG}qn~7A)!h_6X3~^eOfnditz145MuktGYYNl@A1jo@Ee729D41X-}tk zl<{5~0gWS?vwU&>=p-(^Sc+v6$lCBIEEavY)D&;SRw#ymU`wxps7{DzB{gZP{y8q{ z!F!Sh;tsfz-C21QYG#l9Ap~e9L6zNaf8L-rraptvo@$(82Wra(+)Kd$xuP_uv2N2dw^=+6KDr zWGx?BLe}YMGYRUjnjn2Cmz$q|dVy`cOqx0C;0sLWK?dn#X4=z85*SSykd4CT*+2XoUN%8Pb317`V>`R82W4^HFIF zfEBc~w7gD$mu-1-7ZGV)1(_w8D6<%#P=B&BaCtU>okrNp%LiG31AY>~gU*)gRoaXr zW*pn^==LTGak8;>CLNsZ4M^>FF_paR%?~%1z-k(TvL*DqKYqN-!Vo@gMo36_7v?_4 zS4Rh#{SFY$VWKxlc)Q!JZrgkNG^z18Y1?Z>-1j)nca;SNhU0yDxCt8=ELef9S+D)f z&6}a7xEW;MaJ*c*RkNNR!oyGELx$&fc~nIO>HloR=RWPRV&L2-q!})k0fj=*rb9`f zuYXm>WiAG3k4ysH8Y8o_vt=3QD!{owoI0ZadqF_~sJpV8T39%*zl1c*yI`^Fq*D2~cZXZ{?{KBvC5o1px9vcC#yHhKBkir=CRo*XZte2-cgwraNu7-XgD8b5 z#CHAemD58-ZpkhgvaA6b`??2+mpZ#m_+)j*%Si_Z2LS;ANDeK17KF`ook#K!o?kQR zQbI5;P!_Phyg27=I7+`A%WDV&st2J%<(t?v@5AxSi|xzU*0;GzzrJzxB(ZchJDHwU z6nk&RHJ)X)Av-$ciVgUK%YCu6GckYe&vjbUe#(%KkOZ4zng+L6^;^;``AFG)dqCYv zALUk|a-*}Bh@_61{qc$FQkf#W;NuB1$Ng?T2ljaftytb-WE)EPY4_0&1 z)XrZ(AUU`UdjGZSRG`?aE^+X4Z6qJO;<)sjHY>&gTaATkrR*Ee4}mFv;pogOEcD(* zvt^T{WE9F!ZeR8R}0Kbw1u*N;}`MC~my)OyIn3yg5-p{-Lh_eWcOeFOvul|HTd(`_~m#&;e;i z=E*7F%X6gja(@aZ&0em$x7E&kJ6MklXY_LfcFP+yC^s$9c9T}*&kq?gG|xR@yJRoT z<2taRzjz%I-k_Xv8CKoJmsl?-W45>{ad8C_h*RlU#L`aLZ$3V{RmV)6;B&UXkj8KJ z2{BS=+?y&^)&m?bct9MyZR>=M+RAAI zRC8)MIav1v{k;UhY2oc%zcvv>`;Q^OOZ*h&+^=8b1uclPEOW$ z_@MQlobL}0NL|)N>lVIZNyyx;Fm-ixoo-#$EqXo98R@>rXV9VvU{+bV=Nb(Zd9tA# z%atJMT{HG8WMlIVrw%A9&I;l%$Wp+5x{h#{+tccmRK)(Ee3sWv``sCbR?_pEcDY4G zv9ruk8KtF8pJ_4|fslxjQt1n*%s9k&0r9=|B7D!4n?X}nEgKGU%VnW1lWm}OI1@@k}+m_c-j4r+J z*$%_`Z+SO>$PAZ9@w_L}`CNV#A|i_0E(^?% z*AC5uKpmnvU16=;m?62lxA(sJbKd>~%P%!GCwGDG1yHoqcv{RP5rPXZ@WhsM=a^g?_gk{j|^RNgLj4?{YbN}mYAZ03kdI|9p z2=j#lF;OVBKnLR08=yhKs$jpA*`5Lzx)}34AJaAT9zneB_?fFUAhyn>co*l&j(sn; zFY6bP%5|yu34)fI9v;=V!IG7`u8%HEcf-$)cB(M&$++;9mK(gZ9_l2~knwF9sw)tS zo4_suM`kl5PgtJL?{qRm$YtQ*g@?;3EaTSVk^A|{0g{CoG3B{l$iFFcCYGSmZCsv50$k-;{kFF~z|DfSFG2K3*TXOt zrx&S7Nt^*|YilkIAC(Wk+-=oFRPY|hPydR4Kz#N6bkliYU|_SoA**wJ6dS~EH~^qR z>z9&}lI(0bVkB`m;#EdYQ4!DfwU^HV?oxS1z2ANysp-Ako4|1TtJ4(U)WqlVbjE(X zG|QeVfzSAz@Pz4Pr7b?))~OnQa8=aq(^s!v)pfu$#l3!WaB!G%oN68RN~al2saz~V=2z?Fg%roN|y0fvG>CQJI%<9xrSTMUM)gieLdOfjeoQN&@dX` zQ`Gdb&)%mDP#4&G^x}eq{|>-~nF{N;v3R?8&7XxuavB{>~q{ zv(Sl1^9J~ezeGLG##_IS1QG-_oJs=hobOXVe*9^?JZ+rz-zd;4qvVBc^xaF}*w}dY z4v*aiEE;wTBN5S<#U(!wA#wQYhkD)bng*BEAu{jZGBB>=C0^fZ=M^=f;-tEc&&dcBSp)DE6aNltNdB&984yN6z`YPh9M)o?xe(>ya_ow+d)&HWx{y+jsBw^hdP- zK_JVw15d`xy7mU|Q+oGV|DWn0%~2B%OtymK@WJK9MCE1*0}+HIv%2~?Mi&ECN> zfN4h9#M6c&oS!QyDq2{q0P1A+RJ1fs##t|-4xyzre7HGj=ySYu3b<3iUD(TSM*du1 zW2xW$gdw#bw-FMJi|#%$W9#bZkyqHnX*0()$RzfE;P%I`s<0x%_|eeNP}zWF?Mh)e zb9n*aPyl>TZ0f1P_CV)RY;f2MfGn%NvQnq=uupjA34lStZW^@uo;qMstz=SMqVhiW zTQiM@m3d?HKxTlp|0iSeek(f~u-H6J`AMg1oJ1$=Ko`*<_7b# zX@ybOwr}~=!Z(2=&MESIRNo%`2%D{%1h&lL%pbrgynr}L9KJ#IhV|C2zA>P>a}F;b zYo2t8nY99?=0YD(Cl2YAM$&rph1~T$f9`qnyzO8P5d4fRg79CH1G_B*jIy zB%89{yrLqtP0DeFU@P*kMF7wMDK{jKw%Pn45FF{vxXrT7DJ8B~_(9R$UfGwu=W!RA z#$j0%6j#Ci^u?4Mq>B6m6vC5$4G;199`~dj_gZv!cWbX-N8&Hh*nOYFVGqs>Demzb zl)Pz=YuIP8jH`xKQ7|^r@NBV~i54_&H=Hj1!6dOTM=DGl2l*Za0e@Q$Vu`~G5tdCS%%X8|X~}z$iQ)KcMas8dbR`oWvXS0+KG|45|A}*v$sMB>UG-{w z5@}T@7>`0R8E_1Tb|l9^w@A@V5l6S>uN)87?& z<7=8#Y1{L2Z8@eMUi|mZuw2_V{isqe$XK^K%cj`o$R8Ye^nf|+T5)0`?pc0pF^Z-f z8g0r#_FK(q$kHrbl0=F};;Mt}!SwSbp5?k`|~^+^K; zqNt8G-Nl8SHLmMfaWFBH4iX@*0k6*1f8A#MfTLSMpAc5s>gwt;h&p8geed`0zpPzo zab9zwBMkh$##vma35AYKPfMEj#=m&D==x8r+2(lJO8Z?yuepG`rlkJTpY!wAs~XQY zfwux~9W+uWd5Yck-Rl$1noJb3wz9GUuDGC6A7@#9q428%sPgjiIzZ(BjsgKS@HOhp zY255z6uJx2qNJ5og)y$0r~w`H&j9C+rjj$txuVBtL%iW zFOoPoxp;Z8-Jlr=KPG{0fhQ`Xrp6O6H!#W#;IYmQC++j8F&VNGxKzf|=R+UI9s+NI z5*ua&6gf)!zlRS%YBycd?IR0SllAt1K^{G!B4vNLnK4Ip@Z zi9$oFeOEzyk?4MH*44E&D_h&Xo*oqKJSiavHY5h@6>7Tr`(vMZdwZ`raj}CCA=9om zCVjo8zzU6IiGz7s0?l=!H*R32=>p=ZnT3U_$Y5sD61VMXgIahlHAZHnGmM5Upf5>y z?B`E+Z!2r-Dx2|n*FUrpp4#Ledw26<&CuGhLaM{oI8==s?EhKs$08v3`0?o27&zK7 zJKOvoDF}#=l9EzpNqSPzI?&{Db8`>nUIyuSJ0SWBX^AJkvz`?1h*DzRv(^5B# z><*YMT=HzbJtWHjDQ9W9dPn#517n%KEg+;XGirVZ62uAeqfE{-d#PBi*WV+haTXRz zasqN8&_@yqhwf)Poh*ogR}~zzH}iFH)57#Kfll2COm|UkZd6PBBNIG-zp;N=!aV^L zt*Db}Pb@bsm&ZyT3?@lg`QhzE5l6<1Utl`?2Ac+~tH6{o_#7FtM@L61;DH<{s+0f; z>>Sbjj&Pdp18&wrZE{u`^x5R+%=Ey{0;x}sXVS`6(F5cGOwM&sxdLa%qToOS zfV+VsIUKzGzpGVc&Umb(02wuSwf-%MfkJNPjProRfB5dd?oWOFXVCV4;Hm#M2rBl+ zqaAP|aiPur!SD1HE|zHily{K^lqGCSFNgO~u&R9vs=#q>Dw4ow4{*XqJ>U=doLpEo zq_#tf3&(1Zb~mXNm}j}Tl(@JRKaj`^nc<a&vQ&j*bp@PSOhy%`W%G>7NJibHxip!f`fp#^K~SLC(XYU z(;lo^%9uFx41WIicZZzXU6IaSQ~EWdPq8f&xR{;b@7%2lT{Rz{2q8iZY?NtxL!$il z&k@>b$Byd%3eQ-h=SISM|$Ka*-UP& zt!aYehUW86aK{wv8^|{k6i-N**=0oa$*+r~C15VEg&nMq&A82Y=M8NZU#u0gs;3rk zy!QmTGXTOx^@kGzF8GG6d;o@VM+HgR_Q1&*CfkCrLMf+SMI>j=Ri}6Ouolzb6PaGE zg5?tOM0H}Emg^>E8|e;G>Rh>ng<+iwfAe|3pFs0n|@Ji6w z1N~8n{t5cN9Br^agUT0@DA*y}eLRrrw(Ja6n5tDxmrxqJdDF;2m>Zr`IDV3Kr#2Rm zFMlfVOycZ6m}Le0fHlvPRPOg_JkLK7FSUq zx^#u{8xf$t>%q?(j~D8I(7u0R)YrE-)fsUiXSSP09zzTt*D=V zZGOW(-}N4`n4Rcb%ESH;G42_w&Ilms@(q16v+JC-$My8}FLyAyJp`h~EQ%OOrCrpo zC5q&^c|}h5V!}@vQr-)6PyU9fb9;BHT>W+z{Gi?iKZx4>$**`V>|<#ugz0;keV;+D z3s{Wf__VQTze*&xrj0rsw6_e%^&s4dqHpDVDFf#474>Zu0S3}pE}g3h;wq_iQG(Zw zliaU7>H$Dl-DY{w_y_^uq+bvpl|INoRv&I(=9^6c_9IFe_km`rsG}^B zOWt?#>r*opk5oM+?o+3!)RcZ7Lf`Q%=4)`CW%L74wTm&#Iz5WT#dA+@KLUsttis6$ zOuJeN%%#d5-~kF6Alu(G(Rsy_vcF62&@c!%&d?ZbmqnR}6yb-Kr&pf9M*allRA=bJ zb>{3BczJ=h*H3<4HSfj=N)KK)tCjX-FFY&ZKBtw`t`WFdnttkL((^_OC{RlCQD&kZ zMTWHa=hCCWxTzHjCdW|E@#or=J(Ev)m|PWPO2w==Y%gk5-(<-A{Q3S6-RKFR3{broK1cjpwlQdqE5$Y;3NwwaX_% z4IH0;G!$Zs6#X9iHPMWTf2)qe+1>|FX8E;~=G_ zF*LTewSnm9ug&Flhk(pmQ~kzx6KTSjyGv;Na;FhV%<1l(NA^_~#)e9XlHQ^*;w4!; zztX~r*IL8mFZG(os(=h*ZEXz%Kn}ne>v)7)i(R5=MO1jXtIGFLdO643PwlQF57;e9H_ro}W&- zHuHRx;T#YHGAJsJ@S8+dbVfMiIq>uV^^2WoTF#ZX7u!2ynT#S1p-aaM3w#B3Wr1dxt<+L7G;vV%+l>~07 z9X(;>3N$jH9+nx-aYi(P<{%b+F;|0%Y9UPPS?>!)y(^rn@-$Q*fXk^0i%#rCPFExi zu#yD#d+*Ea84MUX#$c6XB~kvPl}C+x3>e4-p95c}SE;;$YGsM-s02KpX!RQ=?~FN- zG+A_YfN0|lzAY?$pj1622Zr-YaG_^-t7w&52b09->KB06GSbk4l9mu!?%Mx6O)) zSV9Z*D~%!uDh1iLKlzicCV!$N|B;jJzl68HlL@z0;+Gjl=uuJC5U+ZH?W~NBZL-9# ziszY2$qDTJMiEjXMdFP)#PSV79PPRK!o zx8wWh+=)OhH3@qYzp?G!>a8iS`JAK%dcNxLJ#S}!SRA2C`$Bqtkc;|N{^6eYIkz6f zdmjX63#_OKe?j*iEH*d2{uNpqlT2oWH?B3B)Wa{0LdNI(e~sN&Z%Q3N$fG5Pe~25m zy}fHWUw{}5Y}KjN~4Ir(iTK_!1kV<-M|xnCupBQ_4m|UtNi?j6 z%vC$N-6z}eo25!YL1t>mSV6`L&NzPk02evIE#3K-A}Mx~UNS|7WQ8l2B)N;}zhT#Y z*?8vnIr0XyW$akiFu~Xg==qa|dTz~aC=d6;lV<8HmpuDAA1y6+T|62ZXl*^obN<#n zd8r4RKc%iS9FF@;U88LtRN0k+#WJA*zvvjKH`cYCS`-Us=;(c{K7dKgaAeV9u%aU^ z4dUpqOa>Ja!(y)^US#KZj6V4(tvW5jU1lb0*Clv!LM-5iW{GIu7pMJF&AVbJc@rM6 z<9FNO0NHQ`BWHrg8I?2M#%O0*O4o5bR%#~|J^zWbyiDf1jeUh#OfFpZad`_}t&_cD z$o??V%BS$4q3Y@6@%c?c>rs&C!YZhp*>dYu0O=!(v}~jT&bJwzNmF zLQXP_Bz5V%)B~%K70~+KD5#JaG56*ZD5?*-xjAUD8&FCu=ocZeB4{Jiv+Q1^EDQg3 za~y;&$&$7zF;nA}4mQPSM9ZZdmg`ifO%pcrh25_Cdz*c_cq^7VEE=uHIygFGGW0dE z5zJB#AgB(7_V_u_Y7;79Op4>t3le-aIpf&(J2V*@ zG*MTD86cl&_!KH!GgtiaSjv;6!;87Pn0?tu_%Z;T$BJyjs_Chp-0@6-_DHB(%sxvO;t8UMada&}k@mNQ{JL`Al|-o>}q} znSA|F@erzxCGJO_$~-(H4IZ&PiNI z2w0)LH8b2NO1%iKYW6G7JSI4S+i|xv z>E2>s!!pM|rRRGm;oJ=-v3zOM9C7quQ?~R{(M=09wo3p#6wi)Pye0CM1;dR?^4@+_ zJ;q-tc#ZpEJfu2S2lg$DW*j2Le`ixmvoq;tGi#`A7C<>D)yl1F$^EitW3|ToY)SZ% z_ODyF_DO7hun-M4oTYmE6O!(AU-I&Ea`h93i)kK`8)T2jwTJuE?$6d#q6j)J0k+V< zwi8R)BPxEi>0A9j@+3U%dC$nNG`*bRc0n}40@V}|$LAfuJlp~5{JLUJ!ZvkV!aK1V zyRY^5j;URVzGsn{^2Kt!z4BaEJ$f|~#7+Ux-Rq*ItyhoZN7)HxL%u$939Ktg=hYq% z1D?*VnwIbUToxsBrz;ZGB{x{#P9(W8T3Ci96UKUm5>YV)VR<-^Ec zgmc`EqHiIj))k+O47PimxmaQqn1k|J)~K5L`9PJhl5R}$Kf^LdD zNJeSCiuDRpxBP}}Ie!eEGP2(qe}^>o$oPgx!MOC5E%N+}ZnhRE3@lMx0i-3$V?m6$ zy%ac-l=+Xrh`1|YE#xx+V;vAlEtr4vYUz{OAUojUwI@Ls)i!nOcZ`+tiSTAqSE~9- zHx&I+=3Xe5Pob>L&-EG;U*Gc|1gczW4qaqYA25p+jv}v2w&OO7X#+y&uNG&WyeK zFB>#~E5OnUO6|H1l%u2wkjIcTR*Y#$uf&_g&c+zl0jS`2&;8EXzF(>#RE!#& zXyveC%DMzPqa9Gf&O(m{Pkk>358=ORLH_&p{*40P!{1=%#+Rl$ZHMiVH$>zhRu+p@-$;Cr=NIY+pn+rv#awg=@CnZTaFI>(kfy;T%_iMy*%tLDRR%{r4J*g%ruvXISuh>YLJeLEmRE>a5hqylzY|fXz zmRcz>VkTqlUwBZ(n~^eE6JFVrGQY_`G%(_Pvjs2A?cd!eSGr#|M(;xaXt>TcOQeqfU#}?#)5KZW}iM-jrv+gnS<)E@ikstjc_SC@)VJir( z#^F#Z_+&uCO6+GTzaM{i#>orVg3F{kwL=k?5ihv5wPLO6NDh17sT0b&d~$W|Bhx<9 z?X?oz=8a&}oG0e1?T-XegJ^$sb(d9|SFD+p)?)v5_;~-o?jH{#11hDkq6nMbn!}8? z21*#V=`WnWFi+E=K8$^I=vny}5f+qdkm1_`^}_sUj2uSzhF3blm9O?azwF z+!I5O&Bc572JcOY2tijs=UvK6+puM*nST&D^6tIOvFzUWyK8sw5fq#i$2E^xtLoTopB$=}yZ; z_s}lGJww{x9?kS_^_k3)xR<(H$zP(SE&6r31Q9v%GCZqTaoP3s2Jekp#9&R*R0P(q zKkzZ4+@&epsBrS~BsxpaCQm1Thf~l4kYi@%(l~1q#kr(h)YxQoJXn((DqSzG4Jy@+yH1Sm`WA%+Y{oB)R?VMk zD!^4Tv;K$`b-$Z-pixd*yCa1GE&m4ScJkOp3aJ%7QK$Sdy`D_!DDgkoSK~XP6Y@E) zM^IAktPV8O?_KTur*Sq!R`yC*IJkrTAGMEq`sj}+)t89=C=DUUsw8F0lFpp4+qOW- zER}uNQ4+Y|Proa1-6+aL$9XsU^0Q@7n;?_S1o>$UqPTXv(s~0dXJegAr`xBzY+var zv@tqxr?JGIUK=L#1 zOg-|?2nRN^xV2L)0nc`SaCdqm*Y29QRhW%VsR`+6w?NYJgC0fhUL_xn$Btnqdm@ig zO?I9*7Q&?YIy}53io4!*>YIDFOfE3D0z8{81r$dM#cAtDPa_9Q5{J1OA~1)ei$1sofdv?5wc=-G#aj39JWktZo37exm+co%ZJzp4|2r!f9 zy`J*SYO!rUK}DVtECNt{AZvb%ffkola#ucou0mOoK!sY+gmSJe%0t^JKZPDcwHmnc&rfjnnuwiusW zR#8!@qio8z&w*WKw>OI`^9WiFMcgIWvsj{yturdsmjEx%JQG2y&8%cDH(=ry`#aJMES+6U*5Owq@F zvfhgaRf7|(Oqbd_IzDTc&NiJbG>Le@a{C&cfPa`GJGAv0G*b5GwUG|-+RG_HrF zEAop6MD()tS#`nKgswfj(YvRpsYE-4sLWlF?B8Hb3&g;_6nxv;Y5(#1B;;F1Bp>Yj ztshHT!awR=bruTZI8Dx04j}bG$n4c2r?l;^v}2q2T%qEIw1RFC-c<^wP-5*kq;q<# zPI{PpjGAji43=IE;7GD?7P#JO@jN8|RK-4CJ>??vagb}Qh=DNqzp1Q0?}4k+}uL~(aNuy4 zUtI*g3o?UO%#1I?!^1&^Prq`9IaU`?0JQr$J31iR{5qGr7OUS?_sYw||HHm)eOAE~;JApdgz@-Q3U%CR@1zL-nvf7_BgC5kO#JtRkTo0DK$6|H8NbGe*JJg#j)ESE0sUM@RADy4D7LkMiM)d+!P=%=uF#hs2?&q8a-k zmcBUjx`eG?=Kic=3&>2oL1jJ|0=&~y@|;g?9+FM=s;CV+F#zzS*XRuMX$HvcJo{Ni zW0n=IjZ=JJ1lR(%d)7C|eZ2t87gbW<&E6`Ovmfn#Id?1};eEA(*KFtphyc5wG+$d{6X-_;pp0 zZj6ImO2XAV@QoBVE2c;NGC$^&kNO%DgAcdoX-Ip~X`jn@Vkp1$q5QVkS#_w)RdL7} z|+pG2fg-fo-($Lp|DzM;i#8PPF_5FZ(3+mV6BelE`?SL=!xn>5r@ zFgx z@<75ZTMkMh+U)NMI08a51YObXyB`f5ST4vf2T+@Qnb^pW*%VWoI)vfpd1~B*tW$Y& z`Rq*BGBLj@tEXDFMqJ@)M5r0d~K|vY};`Bc$!_lTe`y>DhL;}_x*l8s%a~c7h;ux3D&oh+V-%~W{ zXQUkQK0w37?a1Iak{V@{AIFGwyDtARIPljU{9a1`i^s(O8CUq{L;tL7yTf}@G zb?>jU4frSy+r{%{e9p@sL`WxZ#(DlS?b-xL(|r89(}uihijVSqR$A$o%x_5^RC~x}?B|*ELBlo! zK@sljIAQ{&0o*Eq@n(wK%({n6aN$ZnV|m*Vcetu7XV@vrQqncrrFvDF&IIqzADXn# zb8lIv`aC>@VHaN>O!!J1Odrw2!Mo+)ddZpmPF+M>>RmS`*n^l|m%}h0m*{AFr1jFf zvs;x5%4B|E&E~$>eXRS-?_4HR-PSP#p)<`2iy9`l*}8-!oizwrJI%TiAOBQ0m01g| zATIKbg>Cg*(+QvL52Rf}*k1JJw)@>fk2_lx2;6kO;I|-mm#gKcLgd1P9~xTZ$QGsi z5q&->$E5I+2Q2h&7X+(@v=FQ9+%XcTwqd92obIkVY!qW>O}pV^`Eo|F8Ldj-_u}tx zCy87?1wC)G8gyV^q6lWNeM6BmP#1L!3a)KbGpf_Ja3~FV%1Suv+$&VL370;w^v}a; zV7tN1j`evAei!-2qi7hM&5Dygr#Qc9iC728I)X2S)>3=XHK)8eB?PrO>=b|vW5B8D zE`Fw5Y4O{N^P_j2oQ^+3H&V5|RPXNFE857gFQJw{D3p3jA80y7$P(O8;-jn=sD=F} zK+rJhF(oB+Lkq;l@h_TVbZpJT*^*5Ai2VrZzGl|hs+Q+8G8G4)fX9*+mSYBn8F(F* z^ND%(q9$LjRWq`STnj!mpy65$vQR6RV{nDY@%hx_gXww&2aKwbhae-eB@cLF=38lN|YPB*adci zDKX0ky*~!Y9G-APLDe3)WT8Bb%;f#ZIt13#(5)UM5Sx`H>V1yB-jJr$8Rb#s?pLQj>N;2Pndf8BuaqC(-P1-Crr3 zp*)P}xxe;{akm!0c(95*MxZQXD*v*YZIxaQ?#mG-ihGdOL3z;eJgDf@OX~tE#5zyo zWQ*g>X!6bpZVSjE1>RM-(oc!$m_fL=N}*~1_d@$uTF=UWGyf#ZffIOM|2HCpl^Nii zfyw|#aw0AMu!*+#z1?TMadIvcI1*SYi0ChR? zsMYbmg`Nst%flca*9F2;271#Wblw4A(d{bh`WhG*_yeW7Av47VHae8T1*zW|C<4TL zKsX5vcOGrC(qC&mVg7>m&<3dO!7C2HD=^j^Q*R&r%EF{_HzPU_U^kya&t9T0GAT!v zl;{sUEo=EJj^zZY7#ZY3<<78yBY@gq#rNyy{Jd_eY&k%6cyubL8VjzheGxcfe5$w#%?cFmgUV#qlib4tNLx*9L^C#hqPLKpupq>leS2Kdi* z;LI1P3`k0O14B^_@7>WkM)g&RuffiOR|(KhURsH(Qphvo6go_SU4_7r#ix`&{Wm>E z=z#Bycq0NF42%adXxtU!M83(yZi zdY4^b^0X}1@s6frd?J#%@p^%FD+avfVl`@SC&7FgD7m_OdH}aFct+ac7!^ZJT*O%x zQ;%N22Q;8#7L;vEtWR=7UX2kq@Qhtwv z^RaXrS-Z{?c{Gdr@8p*kF_&~z;;RTjAMYth} zZ{p^54rRP9gaD?}bzNBZFjI=m8ey6N%)1bfG7yKEBH7%q7fh7vj3O=pS6JXx5iD4s z4N6lzo)4u>tBZ!J-@?xUb5<`0M_RM|J(w zq6`y0m=sods67N zjw0f*>}4q&!e@*q$_WfG!(zQAD_aKlH}#t`CeR1v%dZt|>P~pkuk9=;+LIMN3Y!)J zD>JIB3m})dEFHO-pY8y!&)DxkjJaRQh;{%p7d1a{EoEsS5na#nT4csn&F3XN_3*M& zM61?p%M+#J!V?|LcN`HTZ>7vUN3E-!OE-toG1qUY);PV`Bm`lS-y6Jq8?rmDCun3k zxtX|ly8e(jYjH}ojC(BGX59P5=1aeFX`@I$xi|tsfio8KjHp6Gm}mC+T}t3blyErz?%=UvG+gh8SKI$>M~N%2D|fzJ?I5|RFwT;;80D~H@C7D zE{wv#9cMfr!LrhRV*BYPOHdv!Q?hlHJ03qK=ZM~@mBX_iE?o~KlgqgGZ)@_^uz=NP zp{o{HlNh+QCI}e=w=hgoI#-{AW7%ncwGNT{!qoOI{R)Sb*z82dIKgsSTYKi2aynvP zj!vIV=aYFZ*-!GM=YEVo&54-nH5&OTNK^kLL&O6=60h@!k4f8u$|#-$c%Uh))?k;+ z?P!~xshwPqTCNPM)2F8yA6rAi9YZtrC%L3BtUXLtwm47)W7>Q{fhLZQ zeT7wK;Z`+{)X|bayX*WriSYrCX2EXg@)=<{RVbYs;f;WaH=oYn+S=H6zv@LB=Q$@R zBTX4I%NNAPTH4iVX>44Sy|FRYwtfNEou4RQQ&wp#_-<+9UMgA9FAv2Ssn*m~hy;#sT4C^>``Z6- zs(=JJgBg@WiwtyaKDXR99aBd#CB)c{(Y^DZ_9FMbZupQacP?~_FCigwU-5Y_gI(_@ zLm6$DkHyMRr_4W`$1k$NDsS`a${4%rsmHs9sM>Fw*g`xq8*PeT(x1&}ZF8e*SwUiw zcg8p$sIi@(DFZKuWd!~Tvh0q`dV-V;2;H1qDMu2J_tYwF(>!`WNKCZ>xRep+#B3eS z4|8@?qU#UdZn8+(O`svW4fWO3BNKk{o2fy1O3K&245LE^4|mxKF?3}u+?azNf=l_N zcjal~Y%P5`%*Au%;@;wENAkXj-|RhvM|=H5_Pv_2XLrfPJo;OEx#NhS#UA4N1vt7F z4Na7M{)-G+V*rxvE3L8a<$m0QE{C*N84F0fl0{LR*Pbx0LW3+fd`9X zeqNp)GkEolhbcKH)M8;`pNP;Ek9$Rtr~_f)ZxZOpAPNSQcW#vJFs7Y{xUoBNShqKE zf|lu${oHH8!gpe}k-*a+xUbl@s=(IQU-yOhhH{8jp6 zA;9gB%IcZ&Tl%+4$;nS@+b8vFIv&A}l)Zv$NcQ*uaA4Iug?$u6@m$-WM`O8mVxG zEd^xjLf|%9k$@aBQ{blYB=9 z^Y7*4y-93N6J#;doaok1I2Cu-!5MS8)Yk=dE-U0Mcv-JD#n)o2zsB1-NyGT0nGBRr zZXrrS;xv9j{NRa8SFG)SCB){HdG9tj#vnc7o_WNbUuo%g|J4s`9Wx_fMqpu;`Pt+6 zvC4~(OYf(k=<+s$*5=j{{pk4I!R0Peh3ZMnb$7I}{&}1b+^@Dfj}|Q)W2_H=hW0rh z!59V6_$Lk_@;C>GeD+0rj7m|xloW|5PcO=xH$LqgHUzq1M~!ZKSwEUllysgYPXRQn zTQt6F^(1E4U9U2!XrBEX|-A@IsIghN6pa3%EKTFwHg5LfJ$Do%%Lv)70#cfns;Pd`(Y2WcDx-|Wjp#)AltQ#1?ED1Wm_g=SG_sN# zjV$vE*EFtf6DrCbB9?oPCYh8Djo`0jp>4z8S~v8o#^n{<$+OwGzlO&B5Fmlj@j3hevzC-L7>^n_aqR z(m+Cjr0`*5V=%>}eyDW5FxnV1P0%WO|2F#~v?xR?JEY7zpq6ypeglh+ zN=oK^BMJ^Po)X5FgS%}uxZ_PQ3s)n(jrZoJv~H5LA!#<}`$kk-!VBS%FHg=W(==ww z78>^@a@dniY6)7X5&Sag3BOV%xV>a zmt%a;jMLdAJ Date: Sat, 26 Dec 2020 15:15:19 +0100 Subject: [PATCH 084/176] solve checkstyle warnings Signed-off-by: Bernd --- .../README.md | 2 + .../ConnectedDriveHandlerFactory.java | 4 +- .../internal/dto/auth/AuthResponse.java | 11 +- .../dto/compat/VehicleAttributes.java | 120 ++++++++++++------ .../compat/VehicleAttributesContainer.java | 34 ++--- .../internal/handler/ConnectedDriveProxy.java | 6 +- 6 files changed, 112 insertions(+), 65 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index a97f147843927..89ddeab3fd876 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -376,9 +376,11 @@ If the access to the Portal and listing of the Vehicle is checked some debug dat If you checked the above pre-conditions you need to get the debug fingerprint from the debug logs. First [enable debug logging](https://www.openhab.org/docs/administration/logging.html#defining-what-to-log) for the binding. + ``` log:set DEBUG org.openhab.binding.bmwconnecteddrive ``` + The debug fingerprint is generated when the Vehicle Thing is initialized the first time, e.g. after openHAB startup. To force a new fingerprint disable the thing shortly and enable it again. Personal Data is eliminated from the log entries so it should be possible to share them in public. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java index c844b6db11780..599593086a7a2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java @@ -77,9 +77,7 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { @Override protected void removeHandler(ThingHandler thingHandler) { - if (thingHandler instanceof ConnectedDriveBridgeHandler) { - // nothing to cleanup - } else { + if (thingHandler instanceof VehicleHandler) { VEHICLE_HANDLER_REGISTRY.remove(thingHandler); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/auth/AuthResponse.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/auth/AuthResponse.java index 5b44051c3dde1..ef3cbcf49d0fc 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/auth/AuthResponse.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/auth/AuthResponse.java @@ -12,13 +12,18 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.dto.auth; +import com.google.gson.annotations.SerializedName; + /** * The {@link Timer} Data Transfer Object * * @author Bernd Weymann - Initial contribution */ public class AuthResponse { - public String access_token; - public String token_type; - public int expires_in; + @SerializedName("access_token") + public String accessToken; + @SerializedName("token_type") + public String tokenType; + @SerializedName("expires_in") + public int expiresIn; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributes.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributes.java index c4387b21b37b6..75c4af8530afc 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributes.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributes.java @@ -12,6 +12,8 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.dto.compat; +import com.google.gson.annotations.SerializedName; + /** * The {@link VehicleAttributes} Data Transfer Object * @@ -19,18 +21,30 @@ */ public class VehicleAttributes { // Windows & Doors - public String door_driver_front;// "CLOSED", - public String door_driver_rear;// "CLOSED", - public String door_passenger_front;// "CLOSED", - public String door_passenger_rear;// "CLOSED", - public String hood_state;// "CLOSED", - public String trunk_state;// "CLOSED", - public String window_driver_front;// "CLOSED", - public String window_driver_rear;// "CLOSED", - public String window_passenger_front;// "CLOSED", - public String window_passenger_rear;// "CLOSED", - public String sunroof_state;// "CLOSED", - public String door_lock_state;// "SECURED", + @SerializedName("door_driver_front") + public String doorDriverFront;// "CLOSED", + @SerializedName("door_driver_rear") + public String doorDriverRear;// "CLOSED", + @SerializedName("door_passenger_front") + public String doorPassengerFront;// "CLOSED", + @SerializedName("door_passenger_rear") + public String doorPassengerRear;// "CLOSED", + @SerializedName("hood_state") + public String hoodState;// "CLOSED", + @SerializedName("trunk_state") + public String trunkState;// "CLOSED", + @SerializedName("window_driver_front") + public String winDriverFront;// "CLOSED", + @SerializedName("window_driver_rear") + public String winDriverRear;// "CLOSED", + @SerializedName("window_passenger_front") + public String winPassengerFront;// "CLOSED", + @SerializedName("window_passenger_rear") + public String winPassengerRear;// "CLOSED", + @SerializedName("sunroof_state") + public String sunroofState;// "CLOSED", + @SerializedName("door_lock_state") + public String doorLockState;// "SECURED", public String shdStatusUnified;// "CLOSED", // Charge Status @@ -39,7 +53,8 @@ public class VehicleAttributes { public String connectorStatus;// "DISCONNECTED", public String chargingLogicCurrentlyActive;// "NOT_CHARGING", public String chargeNowAllowed;// "NOT_ALLOWED", - public String charging_status;// "NOCHARGING", + @SerializedName("charging_status") + public String chargingStatus;// "NOCHARGING", public String lastChargingEndResult;// "SUCCESS", public String chargingSystemStatus;// "NOCHARGING", public String lastUpdateReason;// "VEHCSHUTDOWN_SECURED" @@ -55,46 +70,73 @@ public class VehicleAttributes { public double beRemainingRangeFuelKm;// "67.0", public double beRemainingRangeFuelMile;// "41.0", public double beRemainingRangeFuel;// "67.0", - public double kombi_current_remaining_range_fuel;// "67.0", + @SerializedName("kombi_current_remaining_range_fuel") + public double kombiRemainingRangeFuel;// "67.0", public double chargingLevelHv;// "89.0", - public double soc_hv_percent;// "82.6", - public double remaining_fuel;// "4", + @SerializedName("soc_hv_percent") + public double socHvPercent;// "82.6", + @SerializedName("remaining_fuel") + public double remainingFuel;// "4", public double fuelPercent;// "47", // Last Status update public String updateTime;// "22.08.2020 12:55:46 UTC", - public String updateTime_converted;// "22.08.2020 13:55", - public String updateTime_converted_date;// "22.08.2020", - public String updateTime_converted_time;// "13:55", + @SerializedName("updateTime_converted") + public String updateTimeConverted;// "22.08.2020 13:55", + @SerializedName("updateTime_converted_date") + public String updateTimeConvertedDate;// "22.08.2020", + @SerializedName("updateTime_converted_time") + public String updateTimeConvertedTime;// "13:55", + @SerializedName("updateTime_converted_timestamp") + public String updateTimeConvertedTimestamp;// "1598104546000", + // Last Trip Update - public String Segment_LastTrip_time_segment_end_formatted_date;// "22.08.2020", - public String Segment_LastTrip_time_segment_end_formatted;// "22.08.2020 14:52", - public String Segment_LastTrip_time_segment_end_formatted_time;// "14:52", - public String Segment_LastTrip_time_segment_end;// "22.08.2020 14:52:00 UTC", + @SerializedName("Segment_LastTrip_time_segment_end") + public String lastTripEnd;// "22.08.2020 14:52:00 UTC", + @SerializedName("Segment_LastTrip_time_segment_end_formatted") + public String lastTripEndFormatted;// "22.08.2020 14:52", + @SerializedName("Segment_LastTrip_time_segment_end_formatted_date") + public String lastTripEndFormattedDate;// "22.08.2020", + @SerializedName("Segment_LastTrip_time_segment_end_formatted_time") + public String lastTripEndFormattedTime;// "14:52", // Location - public float gps_lat;// "43.21", - public float gps_lng;// "8.765", + @SerializedName("gps_lat") + public float gpsLat;// "43.21", + @SerializedName("gps_lng") + public float gpsLon;// "8.765", public int heading;// "41", public String unitOfLength;// "km", public String unitOfEnergy;// "kWh", - public String vehicle_tracking;// "1", - public String head_unit_pu_software;// "07/16", - public String check_control_messages;// "", - public String sunroof_position;// "0", - public String single_immediate_charging;// "isUnused", + @SerializedName("vehicle_tracking") + public String vehicleTracking;// "1", + @SerializedName("head_unit_pu_software") + public String headunitSoftware;// "07/16", + @SerializedName("check_control_messages") + public String checkControlMessages;// "", + @SerializedName("sunroof_position") + public String sunroofPosition;// "0", + @SerializedName("single_immediate_charging") + public String singleImmediateCharging;// "isUnused", public String unitOfCombustionConsumption;// "l/100km", - public String Segment_LastTrip_ratio_electric_driven_distance;// "100", - public String condition_based_services;// "00003,OK,2021-11,;00017,OK,2021-11,;00001,OK,2021-11,;00032,OK,2021-11,", - public String updateTime_converted_timestamp;// "1598104546000", - public String charging_inductive_positioning;// "not_positioned", - public String lsc_trigger;// "VEHCSHUTDOWN_SECURED", - public String lights_parking;// "OFF", + @SerializedName("Segment_LastTrip_ratio_electric_driven_distance") + public String lastTripElectricRation;// "100", + @SerializedName("condition_based_services") + public String conditionBasedServices;// "00003,OK,2021-11,;00017,OK,2021-11,;00001,OK,2021-11,;00032,OK,2021-11,", + @SerializedName("charging_inductive_positioning") + public String chargingInductivePositioning;// "not_positioned", + @SerializedName("lsc_trigger") + public String lscTrigger;// "VEHCSHUTDOWN_SECURED", + @SerializedName("lights_parking") + public String lightsParking;// "OFF", public String prognosisWhileChargingStatus;// "NOT_NEEDED", - public String head_unit;// "EntryNav", - public String battery_size_max;// "33200", - public String charging_connection_type;// "CONDUCTIVE", + @SerializedName("head_unit") + public String headunit;// "EntryNav", + @SerializedName("battery_size_max") + public String batterySizeMax;// "33200", + @SerializedName("charging_connection_type") + public String chargingConnectionType;// "CONDUCTIVE", public String unitOfElectricConsumption;// "kWh/100km", } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java index 0557c04dfc4c3..54e22a528bc8e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java @@ -38,37 +38,37 @@ public String transform() { vsc.vehicleStatus = vs; vs.mileage = attributesMap.mileage; - vs.doorLockState = attributesMap.door_lock_state; + vs.doorLockState = attributesMap.doorLockState; - vs.doorDriverFront = attributesMap.door_driver_front; - vs.doorDriverRear = attributesMap.door_driver_rear; - vs.doorPassengerFront = attributesMap.door_passenger_front; - vs.doorPassengerRear = attributesMap.door_passenger_rear; - vs.hood = attributesMap.hood_state; - vs.trunk = attributesMap.trunk_state; + vs.doorDriverFront = attributesMap.doorDriverFront; + vs.doorDriverRear = attributesMap.doorDriverRear; + vs.doorPassengerFront = attributesMap.doorPassengerFront; + vs.doorPassengerRear = attributesMap.doorPassengerRear; + vs.hood = attributesMap.hoodState; + vs.trunk = attributesMap.trunkState; - vs.windowDriverFront = attributesMap.window_driver_front; - vs.windowDriverRear = attributesMap.window_driver_rear; - vs.windowPassengerFront = attributesMap.window_passenger_front; - vs.windowPassengerRear = attributesMap.window_passenger_rear; - vs.sunroof = attributesMap.sunroof_state; + vs.windowDriverFront = attributesMap.winDriverFront; + vs.windowDriverRear = attributesMap.winDriverRear; + vs.windowPassengerFront = attributesMap.winPassengerFront; + vs.windowPassengerRear = attributesMap.winPassengerRear; + vs.sunroof = attributesMap.sunroofState; - vs.remainingFuel = attributesMap.remaining_fuel; + vs.remainingFuel = attributesMap.remainingFuel; vs.remainingRangeElectric = attributesMap.beRemainingRangeElectricKm; vs.remainingRangeElectricMls = attributesMap.beRemainingRangeElectricMile; vs.remainingRangeFuel = attributesMap.beRemainingRangeFuelKm; vs.remainingRangeFuelMls = attributesMap.beRemainingRangeFuelMile; - vs.remainingFuel = attributesMap.remaining_fuel; + vs.remainingFuel = attributesMap.remainingFuel; vs.chargingLevelHv = attributesMap.chargingLevelHv; vs.chargingStatus = attributesMap.chargingHVStatus; vs.lastChargingEndReason = attributesMap.lastChargingEndReason; - vs.updateTime = attributesMap.updateTime_converted; + vs.updateTime = attributesMap.updateTimeConverted; // vs.internalDataTimeUTC = attributesMap.updateTime; Position p = new Position(); - p.lat = attributesMap.gps_lat; - p.lon = attributesMap.gps_lng; + p.lat = attributesMap.gpsLat; + p.lon = attributesMap.gpsLon; p.heading = attributesMap.heading; vs.position = p; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index 45554159a700a..219d7f43915b7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -278,9 +278,9 @@ private synchronized void updateToken() { } else if (contentResponse.getStatus() == 200) { AuthResponse authResponse = Converter.getGson().fromJson(contentResponse.getContentAsString(), AuthResponse.class); - token.setToken(authResponse.access_token); - token.setType(authResponse.token_type); - token.setExpiration(authResponse.expires_in); + token.setToken(authResponse.accessToken); + token.setType(authResponse.tokenType); + token.setExpiration(authResponse.expiresIn); } else { logger.debug("Authorization status {} reason {}", contentResponse.getStatus(), contentResponse.getReason()); From b80c64046a765bfad892e5d2d6e7533a3660b89e Mon Sep 17 00:00:00 2001 From: Bernd Date: Sat, 26 Dec 2020 16:10:44 +0100 Subject: [PATCH 085/176] shorten some channel ids Signed-off-by: Bernd --- .../README.md | 22 +++++++++---------- .../internal/ConnectedDriveConstants.java | 17 +++++++------- .../OH-INF/thing/doors-status-group.xml | 10 ++++----- .../OH-INF/thing/ev-last-trip-group.xml | 4 ++-- .../OH-INF/thing/ev-lifetime-group.xml | 4 ++-- .../OH-INF/thing/hybrid-last-trip-group.xml | 6 ++--- .../OH-INF/thing/hybrid-lifetime-group.xml | 6 ++--- 7 files changed, 34 insertions(+), 35 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 89ddeab3fd876..831d2ac994710 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -191,11 +191,11 @@ Channel Group ID is **doors**. | Passenger Door Rear | passenger-rear | String | | Trunk | trunk | String | | Hood | hood | String | -| Driver Door Window | window-driver-front | String | -| Driver Door Rear Window | window-driver-rear | String | -| Passenger Door Window | window-passenger-front | String | -| Passenger Door Rear Window | window-passenger-rear | String | -| Rear Window | window-rear | String | +| Driver Door Window | win-driver-front | String | +| Driver Door Rear Window | win-driver-rear | String | +| Passenger Door Window | win-passenger-front | String | +| Passenger Door Rear Window | win-passenger-rear | String | +| Rear Window | win-rear | String | | Sunroof | sunroof | String | Following Strings will be delivered @@ -272,9 +272,9 @@ Channel Group ID is **last-trip**. |-----------------------------------------|------------------------------|---------------| | Last Trip Date | date | DateTime | | Last Trip Duration | duration | Number:Time | -| Average Power Consumption per 100 km | average-consumption | Number:Power | -| Average Combined Consumption per 100 km | average-combined-consumption | Number:Volume | -| Average Power Recuperation per 100 km | average-recuperation | Number:Power | +| Average Power Consumption per 100 km | avg-consumption | Number:Power | +| Average Combined Consumption per 100 km | avg-combined-consumption | Number:Volume | +| Average Power Recuperation per 100 km | avg-recuperation | Number:Power | | Last Trip Distance | distance | Number:Length | | Distance since Last Charge | distance-since-charging | Number:Length | @@ -287,10 +287,10 @@ Channel Group ID is **lifetime**. | Channel Label | Channel ID | Type | |-----------------------------------------|------------------------------|---------------| -| Average Power Consumption per 100 km | average-consumption | Number:Power | -| Average Power Recuperation per 100 km | average-recuperation | Number:Power | +| Average Power Consumption per 100 km | avg-consumption | Number:Power | +| Average Power Recuperation per 100 km | avg-recuperation | Number:Power | | Cumulated Electric Driven Distance | cumulated-driven-distance | Number:Length | -| Average Combined Consumption per 100 km | average-combined-consumption | Number:Volume | +| Average Combined Consumption per 100 km | avg-combined-consumption | Number:Volume | | Longest Distance with one Charge | single-longest-distance | Number:Length | diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index d24f093f058b4..b8fc5d90e6fe5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -91,7 +91,6 @@ public String toString() { public static final String CHANNEL_GROUP_CHARGE = "charge"; public static final String CHANNEL_GROUP_VEHICLE_IMAGE = "image"; public static final String CHANNEL_GROUP_DESTINATION = "destination"; - public static final String CHANNEL_GROUP_TROUBLESHOOT = "troubleshoot"; // Generic Constants for several groups public static final String NAME = "name"; @@ -117,11 +116,11 @@ public String toString() { public static final String DOOR_PASSENGER_REAR = "passenger-rear"; public static final String HOOD = "hood"; public static final String TRUNK = "trunk"; - public static final String WINDOW_DOOR_DRIVER_FORNT = "window-driver-front"; - public static final String WINDOW_DOOR_DRIVER_REAR = "window-driver-rear"; - public static final String WINDOW_DOOR_PASSENGER_FRONT = "window-passenger-front"; - public static final String WINDOW_DOOR_PASSENGER_REAR = "window-passenger-rear"; - public static final String WINDOW_REAR = "window-rear"; + public static final String WINDOW_DOOR_DRIVER_FORNT = "win-driver-front"; + public static final String WINDOW_DOOR_DRIVER_REAR = "win-driver-rear"; + public static final String WINDOW_DOOR_PASSENGER_FRONT = "win-passenger-front"; + public static final String WINDOW_DOOR_PASSENGER_REAR = "win-passenger-rear"; + public static final String WINDOW_REAR = "win-rear"; public static final String SUNROOF = "sunroof"; // Charge Profile @@ -153,9 +152,9 @@ public String toString() { public static final String DURATION = "duration"; public static final String DISTANCE = "distance"; public static final String DISTANCE_SINCE_CHARGING = "distance-since-charging"; - public static final String AVG_CONSUMPTION = "average-consumption"; - public static final String AVG_COMBINED_CONSUMPTION = "average-combined-consumption"; - public static final String AVG_RECUPERATION = "average-recuperation"; + public static final String AVG_CONSUMPTION = "avg-consumption"; + public static final String AVG_COMBINED_CONSUMPTION = "avg-combined-consumption"; + public static final String AVG_RECUPERATION = "avg-recuperation"; // Lifetime + Average Consumptions public static final String CUMULATED_DRIVEN_DISTANCE = "cumulated-driven-distance"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/doors-status-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/doors-status-group.xml index 2658539819f57..4a05e8cdb9453 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/doors-status-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/doors-status-group.xml @@ -13,11 +13,11 @@ - - - - - + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/ev-last-trip-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/ev-last-trip-group.xml index 30597ad3fb670..5e0d0084dbd55 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/ev-last-trip-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/ev-last-trip-group.xml @@ -11,8 +11,8 @@ - - + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/ev-lifetime-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/ev-lifetime-group.xml index f4ac0bf14f729..b570bb09a7be3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/ev-lifetime-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/ev-lifetime-group.xml @@ -7,8 +7,8 @@ Consumption Values and Distances over Lifetime - - + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/hybrid-last-trip-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/hybrid-last-trip-group.xml index d40039d4c99b7..ceac5b1f5c7b6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/hybrid-last-trip-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/hybrid-last-trip-group.xml @@ -11,9 +11,9 @@ - - - + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/hybrid-lifetime-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/hybrid-lifetime-group.xml index 8e86a89ab0470..e8046bd9b4792 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/hybrid-lifetime-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/hybrid-lifetime-group.xml @@ -7,9 +7,9 @@ Consumption Values and Distances over Lifetime - - - + + + From de0db3706bb16a0db924ee3ca0f42b4b7230ed44 Mon Sep 17 00:00:00 2001 From: Bernd Date: Sat, 26 Dec 2020 16:21:28 +0100 Subject: [PATCH 086/176] remove fingerprint channel leftovers Signed-off-by: Bernd --- .../bmwconnecteddrive/internal/handler/VehicleHandler.java | 2 +- .../resources/OH-INF/i18n/bmwconnecteddrive_de.properties | 3 --- .../main/resources/OH-INF/thing/bridge-connected-drive.xml | 4 ---- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index df353e02dbad9..7c8f93f37fd1f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -99,7 +99,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { vehicleStatusCallback.onResponse(vehicleStatusCache); } else if (CHANNEL_GROUP_CHARGE.equals(group)) { vehicleStatusCallback.onResponse(chargeProfileCache); - } else if (CHANNEL_GROUP_TROUBLESHOOT.equals(group)) { + } else if (CHANNEL_GROUP_VEHICLE_IMAGE.equals(group)) { imageCallback.onResponse(imageCache); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties index c3b85c1a2e0f1..1c8f509d1180d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties @@ -225,6 +225,3 @@ channel-type.bmwconnecteddrive.remote-state-channel.label = Ausf channel-type.bmwconnecteddrive.png-channel.label = Fahrzeug Bild channel-type.bmwconnecteddrive.image-view-channel.label = Fahrzeug Ansicht channel-type.bmwconnecteddrive.image-size-channel.label = Fahrzeug Bildgröße - -channel-type.bmwconnecteddrive.vehicle-fingerprint-channel.label = Fahrzeug Fingerabdruck -channel-type.bmwconnecteddrive.discovery-fingerprint-channel.label = Portal Fingerabdruck diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/bridge-connected-drive.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/bridge-connected-drive.xml index ddfa1bfa44467..956431e8a0688 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/bridge-connected-drive.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/bridge-connected-drive.xml @@ -9,10 +9,6 @@ Access to BMW ConnectedDrive Portal for a specific user - - - - From e67a72b9afcbf40a5bfba059296ec3df06f9c914 Mon Sep 17 00:00:00 2001 From: Bernd Date: Sat, 26 Dec 2020 17:48:18 +0100 Subject: [PATCH 087/176] label bugfixes Signed-off-by: Bernd --- .../internal/handler/VehicleChannelHandler.java | 13 ++++++++++--- .../bmwconnecteddrive/internal/utils/Constants.java | 2 +- .../internal/dto/StatusWrapper.java | 4 ++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 3090ffa00fdb0..17abb0eca3ec4 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -286,9 +286,14 @@ public void initialize() { } protected void updateCheckControls(List ccl) { - // if list is empty add "undefined" element if (ccl.size() == 0) { - ccl.add(new CCMMessage()); + // No Check Control available - show not active + CCMMessage ccm = new CCMMessage(); + ccm.ccmDescriptionLong = Constants.NOT_ACTIVE; + ccm.ccmDescriptionShort = Constants.NOT_ACTIVE; + ccm.ccmId = -1; + ccm.ccmMileage = -1; + ccl.add(ccm); } // add all elements to options @@ -329,7 +334,9 @@ protected void selectCC(String selection) { protected void updateServices(List sl) { // if list is empty add "undefined" element if (sl.size() == 0) { - sl.add(new CBSMessage()); + CBSMessage cbsm = new CBSMessage(); + cbsm.cbsType = Constants.NO_SERVICES; + sl.add(cbsm); } // add all elements to options diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java index 6740edc2e5867..8d4931c96a5c9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -28,12 +28,12 @@ public class Constants { public static final String OK = "Ok"; public static final String ACTIVE = "ACTIVE"; public static final String NOT_ACTIVE = "NOT ACTIVE"; + public static final String NO_SERVICES = "NO SERVICES PLANNED"; public static final String OPEN = "OPEN"; public static final String INVALID = "INVALID"; public static final String CLOSED = "CLOSED"; public static final String INTERMEDIATE = "INTERMEDIATE"; public static final String UNKNOWN = "UNKNOWN"; - public static final String NO_SERVICE_REQUEST = "No Service Requests"; public static final String UTC_APPENDIX = "-01T12:00:00"; public static final String NULL_DATE = "1900-01-01T00:00:00"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index fbd0d6210ebe2..3aeb504eb1a29 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -434,14 +434,14 @@ private void checkResult(ChannelUID channelUID, State state) { st = (StringType) state; switch (gUid) { case CHANNEL_GROUP_SERVICE: - wanted = StringType.valueOf(Converter.toTitleCase(Constants.INVALID)); + wanted = StringType.valueOf(Converter.toTitleCase(Constants.NO_SERVICES)); if (!vStatus.cbsData.isEmpty()) { wanted = StringType.valueOf(Converter.toTitleCase(vStatus.cbsData.get(0).getType())); } assertEquals(wanted.toString(), st.toString(), "Service Name"); break; case CHANNEL_GROUP_CHECK_CONTROL: - wanted = StringType.valueOf(Constants.INVALID); + wanted = StringType.valueOf(Constants.NOT_ACTIVE); if (!vStatus.checkControlMessages.isEmpty()) { wanted = StringType.valueOf(vStatus.checkControlMessages.get(0).ccmDescriptionShort); } From 0bc45b2921f6bba6c3640f6fd0e9afc899abfcc1 Mon Sep 17 00:00:00 2001 From: Bernd Date: Sun, 27 Dec 2020 01:20:11 +0100 Subject: [PATCH 088/176] title case adaptions plus minor bugfixes Signed-off-by: Bernd --- .../README.md | 551 ++++++------------ .../internal/dto/Destination.java | 10 +- .../internal/dto/charge/Timer.java | 3 +- .../handler/VehicleChannelHandler.java | 46 +- .../internal/utils/Constants.java | 18 +- .../i18n/bmwconnecteddrive_de.properties | 14 +- .../OH-INF/thing/image-channel-types.xml | 9 + .../thing/remote-services-channel-types.xml | 2 +- .../internal/dto/StatusWrapper.java | 28 +- 9 files changed, 250 insertions(+), 431 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 831d2ac994710..657a116bbbe0e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -3,7 +3,7 @@ The binding provides a connection between [BMW's ConnectedDrive Portal](https://www.bmw-connecteddrive.com/country-region-select/country-region-selection.html) and openHAB. -AllvVehicles connected to an account will be detected by the discovery with the correct type +All vehicles connected to an account will be detected by the discovery with the correct type * Conventional Fuel Vehicle * Plugin-Hybrid Electrical Vehicle @@ -13,21 +13,21 @@ AllvVehicles connected to an account will be detected by the discovery with the In addition properties are attached with information and services provided by this vehicle. The provided data depends on -1. the [Thing Type](#Things) and -2. the services mentioned in [Properties](#properties) +1. the [Thing Type](#thing) and +2. the [Properties](#properties) mentioned in Services Different channel groups are clustering all informations. Check for each group if it's supported for this Vehicle. Please note **this isn't a real-time binding**. -If the aoor is opened the state isn't transmitted and changed immediately. +If a door is opened the state isn't transmitted and changed immediately. This isn't a flaw in the binding itself because the state in BMW's own ConnectedDrive App is also updated with some delay. ## Supported Things ### Bridge -The bridge establishes the connection between BMW ConnectedDrive Portal and openHAB. +The bridge establishes the connection between BMW's ConnectedDrive Portal and openHAB. | Name | Bridge Type ID | Description | |----------------------------|----------------|------------------------------------------------------------| @@ -61,43 +61,43 @@ Basically 3 types of information are registered as properties * Vehicle properties like color, model type, drive train and construction year In the right picture can see in *Services Activated* e.g. the *DoorLock* and *DoorUnlock* services are mentioned. -This ensures [Channel Group _Remote Services_](#remote-services) is supporting door lock and door unlock. +This ensures channel group [_Remote Services_](#remote-services) is supporting door lock and unlock remote control. In *Services Supported* the entry *LastDestination* is mentioned. -So it's valid to connect Channel Group [Last Destinations](#destinations) in order to display the last 3 Navigation Destinations. +So it's valid to connect channel group [Last Destinations](#destinations) in order to display and select the last navigation destinations. | Property Key | Property Value | Supported Channel Groups | |--------------------|---------------------|------------------------------| | Services Supported | Statistics | last-trip, lifetime | | Services Supported | LastDestinations | destinations | -| Services Activated | list of services | remote | +| Services Activated | _list of services_ | remote | ## Discovery -Auto discovery is starting after creation of the bridge towards BMW's ConnectedDrive. -A list of your registered vehicles is queried and all found items are added in Inbox. +Auto discovery is starting after the bridge towards BMW's ConnectedDrive is created. +A list of your registered vehicles is queried and all found things are added in the inbox. Unique identifier is the *Vehicle Identification Number* (VIN). -If a thing is already declared in a *.things configuration* discovery won't highlight it again. +If a thing is already declared in a _.things_ configuration, discovery won't highlight it again. Properties will be attached to predefined vehicles if the VIN is matching. ## Configuration -### Bridge +### Bridge Configuration | Parameter | Type | Description | |-----------------|---------|--------------------------------------------------------------------| -| userName | text | BMW Connected Drive Username | -| password | text | BMW Connected Drive Password | -| region | text | Select Region in order to connect to the appropriate BMW Server. | +| userName | text | BMW ConnectedDrive Username | +| password | text | BMW ConnectedDrive Password | +| region | text | Select region in order to connect to the appropriate BMW server. | -The region Configuration has 3 different possibilities +The region Configuration has 3 different options * _NORTH_AMERICA_ * _CHINA_ -* _ROW_ for Rest of World +* _ROW_ (Rest of World) -### Thing +### Thing Configuration Same configuration is needed for all things @@ -109,26 +109,26 @@ Same configuration is needed for all things | imageSize | integer | Image Size | | imageViewport | text | Image Viewport | -The units can be configured in 3 ways +The unit configuration has 3 options * _AUTODETECT_ selects miles for US & UK, kilometer otherwise * _METRIC_ selects directly kilometers * _IMPERIAL_ selects directly miles The _imageVieport_ allows to show the vehicle from different angels. -Possible values are +Possible options are -* FRONT -* REAR -* SIDE -* DASHBOARD -* DRIVERDOOR +* _FRONT_ +* _REAR_ +* _SIDE_ +* _DASHBOARD_ +* _DRIVERDOOR_ ## Channels There are many channels available for each vehicle. For better overview they are clustered in different channel groups. -The channel groups are different for the vehicle types, on the build-in sensors of the vehicle and the activated services. +They differ for each vehicle type, build-in sensors and activated services. ### Thing Channel Groups @@ -143,19 +143,20 @@ Channel Group ID is **status**. |---------------------------|---------------------|---------------|-----------------------------------------------------------------------------------| | Overall Door Status | doors | String | **Closed** if all closed otherwise **Open**. **Unknown** if no data is delivered | | Overall Window Status | windows | String | **Closed** if all closed otherwise **Open** or **Intermediate**. **Unknown** if no data is delivered | -| Doors Locked | lock | String | Status if Doors are locked or unlocked | -| Next Service Date | service-date | DateTime | Date of Upcoming Service | -| Mileage till Next Service | service-mileage | Number:Length | Mileage till Upcoming Service | +| Doors Locked | lock | String | Status if doors are locked or unlocked | +| Next Service Date | service-date | DateTime | Date of upcoming service | +| Mileage till Next Service | service-mileage | Number:Length | Mileage till upcoming service | | Check Control | check-control | String | Indicator if CheckControl is **Active** or **Not Active**. **Unknown** if no data is delivered | -| Charging Status | charge | String | Only available for PHEV, BEV_REX and BEV | -| Last Status Timestamp | last-update | DateTime | Date and Time of last status update. | +| Charging Status | charge | String | Only available for phev, bev_rex and bev | +| Last Status Timestamp | last-update | DateTime | Date and time of last status update | See [further details for DateTime](#last-status-update-timestamp) in case of wrong timestamp values #### Services -Group for all upcoming services with description, service date and / or service mileage +Group for all upcoming services with description, service date and/or service mileage. Channel Group ID is **service**. +If more than one service is scheduled in the future the String channel _name_ contains all future services as options. | Channel Label | Channel ID | Type | |--------------------------------|---------------------|----------------| @@ -163,23 +164,20 @@ Channel Group ID is **service**. | Service Date | date | Number | | Mileage till Service | mileage | Number:Length | -If more than one service is scheduled in the future the String channel _name_ has all possible options attached. - #### Check Control Group for all current active CheckControl Messages. Channel Group ID is **check**. +If more than one check control message is active the String channel _name_ contains all active messages as options. | Channel Label | Channel ID | Type | |---------------------------------|---------------------|----------------| | CheckControl Description | name | String | | CheckControl Mileage Occurrence | mileage | Number:Length | -If more than one check control message is active all possibilities are set as options to the String channel _name_. - #### Doors Details -Detailed status of all doors and windows +Detailed status of all doors and windows. Available for all vehicles, read-only. Channel Group ID is **doors**. @@ -198,21 +196,22 @@ Channel Group ID is **doors**. | Rear Window | win-rear | String | | Sunroof | sunroof | String | -Following Strings will be delivered +Following String states are possible -* UNKNOWN - no status data available -* INVALID - this item isn't applicable for this vehicle -* CLOSED - the door / window is closed -* OPEN - the door / window is open -* INTERMEDIATE - window in intermediate position, not applicable for doors +* _Unknown_ - no status data available +* _Invalid_ - this item isn't applicable for this vehicle +* _Closed_ - the door / window is closed +* _Open_ - the door / window is open +* _Intermediate_ - window in intermediate position, not applicable for doors #### Range Data -Based on vehicle type (Thing Type ID) some channels are presented or not. -Conventional fuel vehicles don't provide *Electric Range* and Battery electric Vehicles don't show *Range Fuel*. +Based on vehicle type some channels are presented or not. +Conventional fuel vehicles don't provide *Electric Range* and Battery electric Vehicles don't show *Fuel Range*. Hybrid vehicles have both and in addition *Hybrid Range*. These are read-only values. Channel Group ID is **range**. +See description [Range vs Range Radius](#range-vs-range-radius) to get more information. | Channel Label | Channel ID | Type | CONV | PHEV | BEV_REX | BEV | |-----------------------|-----------------------|----------------------|------|------|---------|-----| @@ -226,7 +225,6 @@ Channel Group ID is **range**. | Electric Range Radius | range-radius-electric | Number:Length | | X | X | X | | Hybrid Range Radius | range-radius-hybrid | Number:Length | | X | X | | -See Description [Range vs Range Radius](#range-vs-range-radius) to get more information #### Charge Profile @@ -264,7 +262,7 @@ Channel Group ID is **location**. #### Last Trip -Check [Vehicle Properties](#Properties) if *Statistics* is present in *Services Supported* +Check [Vehicle Properties](#properties) if *Statistics* is present in *Services Supported*. These are read-only values. Channel Group ID is **last-trip**. @@ -281,7 +279,7 @@ Channel Group ID is **last-trip**. #### Lifetime Statistics -Check [Vehicle Properties](#Properties) if *Statistics* is present in *Services Supported* +Check [Vehicle Properties](#properties) if *Statistics* is present in *Services Supported*. These are read-only values. Channel Group ID is **lifetime**. @@ -296,7 +294,7 @@ Channel Group ID is **lifetime**. #### Remote Services -Check [Vehicle Properties](#Properties) *Services Activated* which remote services are available +Check [Vehicle Properties](#properties) *Services Activated* which remote services are available. Only one remote service can be executed each Time. Parallel execution isn't supported. The *Service Execution State* channel is reporting the state. @@ -308,7 +306,7 @@ Channel Group ID is **remote**. | Remote Service Command | command | String | | Service Execution State | state | String | -The channel _command_ has the following value options: +The channel _command_ provides these options * _Flash Lights_ * _Vehicle Finder_ @@ -317,17 +315,24 @@ The channel _command_ has the following value options: * _Horn Blow_ * _Climate Control_ +The channel _state_ shows the progress of the command execution in the following order + +* _Initiated_ +* _Pending_ +* _Delivered_ +* _Executed_ + #### Destinations -Check [Vehicle Properties](#Properties) if *LastDestinations* is present in *Services Supported* +Check [Vehicle Properties](#properties) if *LastDestinations* is present in *Services Supported* Channel Group ID is **destination**. +If more than one last destination is avialble in the navigation system the String channel _name_ contains all destinations as options. | Channel Label | Channel ID | Type | |----------------------------------|---------------------|-----------| | Destination Name | name | String | | Destination GPS Coordinates | gps | Location | -If more than one service is scheduled in the future the String channel _name_ has all possible options attached. #### Image @@ -343,34 +348,35 @@ Channel Group ID is **image**. | Image Viewport | view | String | | Image Picture Size | size | Number | +The possible values are the same mentioned in [Thing Configuration](#thing-configuration). ## Further Descriptions -### List Interface +### Dynamic Data -Currently there are 3 occurrences of dynamic data delivered as Lists +There are 3 occurrences of dynamic data delivered * Upcoming Services delivered in group [Services](#services) -* Check Control Messages delivered in group [Check Control](#check_control) +* Check Control Messages delivered in group [Check Control](#check-control) * Last Destinations delivered in group [Destinations](#destinations) -The channel **name** shows the first element. +The channel **name** shows the first element as default. All other elements are attached as options. The picture on the right shows the _Service Name_ item and all plus the 4 available options. With this you're able to select each service and the corresponding _Service Date & Milage_ will be shown. ### TroubleShooting -BMW has a high range of Vehicles supported by BMWs ConnectedDrive. +BMW has a high range of Vehicles supported by ConnectedDrive. In case of any issues with this Binding please help to resolve it! Please perform the following Steps: * Can you login [into ConnectedDrive](https://www.bmw-connecteddrive.com/country-region-select/country-region-selection.html) with your Credentials? _Please note this isn't the BMW Customer Portal - it's the ConnectedDrive Portal_ * Is the Vehicle listed in your Account? _There's a one-to-one dependency from User to Vehicle_ -If the access to the Portal and listing of the Vehicle is checked some debug data is needed in order to identify the issue. +If the access to the portal is working and the vehicle is listed some debug data is needed in order to identify the issue. #### Generate Debug Fingerprint @@ -381,9 +387,9 @@ First [enable debug logging](https://www.openhab.org/docs/administration/logging log:set DEBUG org.openhab.binding.bmwconnecteddrive ``` -The debug fingerprint is generated when the Vehicle Thing is initialized the first time, e.g. after openHAB startup. +The debug fingerprint is generated immediately after the vehicle thing is initialized the first time, e.g. after openHAB startup. To force a new fingerprint disable the thing shortly and enable it again. -Personal Data is eliminated from the log entries so it should be possible to share them in public. +Personal data is eliminated from the log entries so it should be possible to share them in public. Data like * Dealer Properties @@ -391,8 +397,13 @@ Data like * Location Latitude / Longitude are anonymized. +You'll find the fingerprint in the logs with the command -After the corresponding Fingerprint is generated please [follow the instructions to raise an Issue](https://community.openhab.org/t/how-to-file-an-issue/68464) and attach the Fingerprint data! +``` +less openhab.log | grep "BMW ConnectedDrive Binding" +``` + +After the corresponding fingerprint is generated please [follow the instructions to raise an Issue](https://community.openhab.org/t/how-to-file-an-issue/68464) and attach the fingerprint data! Your feedback is highly appreciated! @@ -400,24 +411,25 @@ Your feedback is highly appreciated! -You will observe differences in the Vehicle Range and Range Radius values. -While range is indicating the possible distance to be driven on roads the range radius indicates the reachable range on the Map. +You will observe differences in the vehicle range and range radius values. +While range is indicating the possible distance to be driven on roads the range radius indicates the reachable range on the map. The right picture shows the distance between Kassel and Frankfurt in Germany. -While the Air-line Distance is ~145 Kilometer the Route Distance is ~192 Kilometer. -So Range value is the normal remaining range. -See the Section [OpenStreetMap](#openstreetMap-widget) how the Range Radius is used to indicate the reachable Range on Map. -Please note this is just an indicator and the effective range, especially for Electric Vehicles, +While the air-line distance is ~145 kilometer the route distance is ~192 kilometer. +So range value is the normal remaining range. +See the Section [OpenStreetMap](#openstreetmap-widget) how the range radius is used to indicate the reachable range on map. +Please note this is just an indicator and the effective range, especially for electric vehicles, depends on many factors like driving style and electric consumers. ### Last Status Update Timestamp -A timestamp is showing the last Vehicle Status update. If this isn't shown correctly please check the date settings. +A timestamp is showing the last vehicle status update. +If this isn't shown correctly please check the date settings. In case of Raspberry Pi execute *raspi-config*, select *Localization Options*, the *Change Time Zone* -Select your *Geographical Area* and afterwards the correct City. -One restart of openHAB service with *systemctl restart openhab2* is necessary in order to see the corrected Time Settings. +Select your *Geographical Area* and afterwards the correct city. +One restart of openHAB service with *systemctl restart openhab2* is necessary in order to see the corrected time settings. -Correct TimeZone is crucial for handling all Time information in openHAB and it's discussed many times in the Forum. +Correct TimeZone is crucial for handling all time information in openHAB and it's discussed many times in the forum. See [similar discussion in the openHAB Forum](https://community.openhab.org/t/solved-wrong-local-time-how-to-change/90938) which deals with the same problem. @@ -430,7 +442,7 @@ Exchange the 3 configuration parameters in the Things section * YOUR_PASSWORD - with your ConnectedDrive Password Credentials * VEHICLE_VIN - the Vehicle Identification Number -In addition search for all occurrences of *i3* and replace it with your Vehicle Identification like *x3* or *535d* and 're ready to go! +In addition search for all occurrences of *i3* and replace it with your Vehicle Identification like *x3* or *535d* and you're ready to go! ### Things @@ -443,103 +455,84 @@ Bridge bmwconnecteddrive:account:user "BMW ConnectedDrive Account" [userName=" ### Items ``` -Number:Length i3Mileage "Odometer [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#mileage" } -Number:Length i3Range "Range [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#hybrid"} -Number:Length i3RangeElectric "Electric Range [%d %unit%]" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#electric"} -Number:Length i3RangeFuel "Fuel Range [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#fuel"} -Number:Dimensionless i3BatterySoc "Battery Charge [%.1f %%]" (i3,long) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#soc"} -Number:Volume i3Fuel "Fuel [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#remaining-fuel"} -Number:Length i3RadiusElectric "Electric Radius [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#radius-electric" } -Number:Length i3RadiusHybrid "Hybrid Radius [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:range#radius-hybrid" } - -String i3DoorStatus "Door Status [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#doors" } -String i3WindowStatus "Window Status [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#windows" } -String i3LockStatus "Lock Status [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#lock" } -DateTime i3NextServiceDate "Next Service Date [%1$tb %1$tY]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#service-date" } -String i3NextServiceMileage "Next Service Mileage [%d %unit%]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#service-mileage" } -String i3CheckControl "Check Control [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#check-control" } -String i3ChargingStatus "Charging [%s]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#charge" } -DateTime i3LastUpdate "Update [%1$tA, %1$td.%1$tm. %1$tH:%1$tM]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:status#last-update"} - -DateTime i3TripDateTime "Trip Date [%1$tA, %1$td.%1$tm. %1$tH:%1$tM]" (i3) {channel="bmwconnecteddrive:BEV_REX:user:i3:last-trip#date"} -Number:Time i3TripDuration "Trip Duration [%d %unit%]" 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 EFIvn;tN;K2 literal 52952 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 QcsohwCFI1jMXz}N9~31)#{d8T diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 3556a57bfd9d1..a1900f2e4144d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -18,6 +18,9 @@ import java.util.List; import java.util.Optional; +import javax.measure.Unit; +import javax.measure.quantity.Length; + import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; import org.openhab.binding.bmwconnecteddrive.internal.dto.Destination; @@ -421,31 +424,59 @@ private void setOptions(ChannelUID cuid, List options) { } protected void updateAllTrips(AllTrips allTrips) { - updateState(lifeTimeCumulatedDrivenDistance, QuantityType - .valueOf(Converter.round(allTrips.totalElectricDistance.userTotal), MetricPrefix.KILO(SIUnits.METRE))); - updateState(lifeTimeSingleLongestDistance, QuantityType - .valueOf(Converter.round(allTrips.chargecycleRange.userHigh), MetricPrefix.KILO(SIUnits.METRE))); - updateState(lifeTimeAverageConsumption, QuantityType - .valueOf(Converter.round(allTrips.avgElectricConsumption.userAverage), Units.KILOWATT_HOUR)); + Unit lengthUnit = MetricPrefix.KILO(SIUnits.METRE); + double totalElectricDistance = allTrips.totalElectricDistance.userTotal; + double longestElectricTrip = allTrips.chargecycleRange.userHigh; + double distanceSinceCharging = allTrips.chargecycleRange.userCurrentChargeCycle; + double avgConsumotion = allTrips.avgElectricConsumption.userAverage; + double avgCombinedConsumption = allTrips.avgCombinedConsumption.userAverage; + double avgRecuperation = allTrips.avgRecuperation.userAverage; + if (imperial) { + lengthUnit = ImperialUnits.MILE; + totalElectricDistance /= Constants.MILES_TO_KM_RATIO; + longestElectricTrip /= Constants.MILES_TO_KM_RATIO; + distanceSinceCharging /= Constants.MILES_TO_KM_RATIO; + avgConsumotion *= Constants.MILES_TO_KM_RATIO; + avgCombinedConsumption *= Constants.MILES_TO_KM_RATIO; + avgRecuperation *= Constants.MILES_TO_KM_RATIO; + } + updateState(lifeTimeCumulatedDrivenDistance, + QuantityType.valueOf(Converter.round(totalElectricDistance), lengthUnit)); + updateState(lifeTimeSingleLongestDistance, + QuantityType.valueOf(Converter.round(longestElectricTrip), lengthUnit)); + updateState(tripDistanceSinceCharging, + QuantityType.valueOf(Converter.round(distanceSinceCharging), lengthUnit)); + updateState(lifeTimeAverageConsumption, + QuantityType.valueOf(Converter.round(avgConsumotion), Units.KILOWATT_HOUR)); updateState(lifetimeAvgCombinedConsumption, - QuantityType.valueOf(allTrips.avgCombinedConsumption.userAverage, Units.LITRE)); + QuantityType.valueOf(Converter.round(avgCombinedConsumption), Units.LITRE)); updateState(lifeTimeAverageRecuperation, - QuantityType.valueOf(Converter.round(allTrips.avgRecuperation.userAverage), Units.KILOWATT_HOUR)); - updateState(tripDistanceSinceCharging, QuantityType.valueOf( - Converter.round(allTrips.chargecycleRange.userCurrentChargeCycle), MetricPrefix.KILO(SIUnits.METRE))); + QuantityType.valueOf(Converter.round(avgRecuperation), Units.KILOWATT_HOUR)); } protected void updateLastTrip(LastTrip trip) { // Whyever the Last Trip DateTime is delivered without offest - so LocalTime updateState(tripDateTime, DateTimeType.valueOf(Converter.getLocalDateTimeWithoutOffest(trip.date))); updateState(tripDuration, QuantityType.valueOf(trip.duration, Units.MINUTE)); - updateState(tripDistance, - QuantityType.valueOf(Converter.round(trip.totalDistance), MetricPrefix.KILO(SIUnits.METRE))); - updateState(tripAvgConsumption, - QuantityType.valueOf(Converter.round(trip.avgElectricConsumption), Units.KILOWATT_HOUR)); - updateState(tripAvgCombinedConsumption, QuantityType.valueOf(trip.avgCombinedConsumption, Units.LITRE)); - updateState(tripAvgRecuperation, - QuantityType.valueOf(Converter.round(trip.avgRecuperation), Units.KILOWATT_HOUR)); + + double distance = trip.totalDistance; + double avgConsumtption = trip.avgElectricConsumption; + double avgCombinedConsumption = trip.avgCombinedConsumption; + double avgRecuperation = trip.avgRecuperation; + Unit lengthUnit = MetricPrefix.KILO(SIUnits.METRE); + + if (imperial) { + distance /= Constants.MILES_TO_KM_RATIO; + avgConsumtption *= Constants.MILES_TO_KM_RATIO; + avgCombinedConsumption *= Constants.MILES_TO_KM_RATIO; + avgRecuperation *= Constants.MILES_TO_KM_RATIO; + lengthUnit = ImperialUnits.MILE; + } + updateState(tripDistance, QuantityType.valueOf(Converter.round(distance), lengthUnit)); + updateState(tripAvgConsumption, QuantityType.valueOf(Converter.round(avgConsumtption), Units.KILOWATT_HOUR)); + updateState(tripAvgCombinedConsumption, + QuantityType.valueOf(Converter.round(avgCombinedConsumption), Units.LITRE)); + updateState(tripAvgRecuperation, QuantityType.valueOf(Converter.round(avgRecuperation), Units.KILOWATT_HOUR)); } protected void updateChargeProfile(ChargeProfile cp) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java index 82681df3db477..ffd486f1e4afd 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -60,6 +60,7 @@ public class Constants { public static final String ANONYMOUS = "Anonymous"; public static final int MILES_TO_FEET_FACTOR = 5280; + public static final double MILES_TO_KM_RATIO = 1.60934; public static final String EMPTY_VEHICLES = "{}"; @SuppressWarnings("serial") diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties index 31062adc85ddb..861a6ae6afd0c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties @@ -208,9 +208,12 @@ channel-type.bmwconnecteddrive.trip-date-time-channel.label = Datum channel-type.bmwconnecteddrive.trip-duration-channel.label = Dauer channel-type.bmwconnecteddrive.distance-channel.label = Distanz channel-type.bmwconnecteddrive.distance-since-charging-channel.label = Distanz seit letzter Ladung -channel-type.bmwconnecteddrive.average-consumption-channel.label = kw/h Verbrauch über 100 km -channel-type.bmwconnecteddrive.average-combined-consumption-channel.label = Liter Verbrauch kombiniert über 100 km -channel-type.bmwconnecteddrive.average-recuperation-channel.label = kw/h Rekuperation über 100 km +channel-type.bmwconnecteddrive.average-consumption-channel.label = Elektrischer Verbrauch +channel-type.bmwconnecteddrive.average-consumption-channel.description = Elektrischer Durchnittsverbaruch über 100 km/mi +channel-type.bmwconnecteddrive.average-combined-consumption-channel.label = Kombinierter Verbrauch +channel-type.bmwconnecteddrive.average-combined-consumption-channel.description = Kombinierter Durchnittsverbaruch in Liter über 100 km/mi +channel-type.bmwconnecteddrive.average-recuperation-channel.label = Rekuperation Durchschnitt +channel-type.bmwconnecteddrive.average-recuperation-channel.label = Durchschnittliche Rekuperation über 100 km/mi channel-type.bmwconnecteddrive.cumulated-driven-distance-channel.label = Elektrisch gefahrene Distanz channel-type.bmwconnecteddrive.single-longest-distance-channel.label = Längste Fahrt mit einer Ladung diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/last-trip-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/last-trip-channel-types.xml index 50b08f40e9930..28d2830057b78 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/last-trip-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/last-trip-channel-types.xml @@ -9,7 +9,7 @@ Number:Time - + Number:Length @@ -17,18 +17,22 @@ Number:Length - + + Total distance driven since last charging Number:Energy - + + Average electric power consumption per 100 km/mi Number:Volume - + + Average combined consumption in liter per 100 km/mi Number:Energy - + + Average electric recuperation per 100 km/mi diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/lifetime-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/lifetime-channel-types.xml index f26d0a3a5e8a9..007698fdc972b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/lifetime-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/lifetime-channel-types.xml @@ -5,11 +5,13 @@ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> Number:Energy - + + Average electric power consumption per 100 km/mi Number:Energy - + + Average electric recuperation per 100 km/mi Number:Length @@ -17,7 +19,8 @@ Number:Volume - + + Average combined consumption in liter per 100 km/mi Number:Length diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java index bf6e7cffa9010..7efe5e1f8eeb4 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java @@ -27,7 +27,9 @@ import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTrips; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTripsContainer; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.core.library.types.QuantityType; +import org.openhab.core.library.unit.ImperialUnits; import org.openhab.core.library.unit.MetricPrefix; import org.openhab.core.library.unit.SIUnits; import org.openhab.core.library.unit.Units; @@ -45,9 +47,11 @@ @SuppressWarnings("null") public class LifetimeWrapper { private static final Gson GSON = new Gson(); + private static final Unit MILES = ImperialUnits.MILE; private static final Unit KILOMETRE = MetricPrefix.KILO(SIUnits.METRE); private AllTrips allTrips; + private boolean imperial; private boolean isElectric; private boolean hasFuel; private boolean isHybrid; @@ -55,6 +59,7 @@ public class LifetimeWrapper { private Map specialHandlingMap = new HashMap(); public LifetimeWrapper(String type, boolean imperial, String statusJson) { + this.imperial = imperial; hasFuel = type.equals(VehicleType.CONVENTIONAL.toString()) || type.equals(VehicleType.PLUGIN_HYBRID.toString()) || type.equals(VehicleType.ELECTRIC_REX.toString()); isElectric = type.equals(VehicleType.PLUGIN_HYBRID.toString()) @@ -102,43 +107,76 @@ private void checkResult(ChannelUID channelUID, State state) { case DISTANCE_SINCE_CHARGING: assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); - assertEquals(KILOMETRE, qt.getUnit(), "KM"); - assertEquals(allTrips.chargecycleRange.userCurrentChargeCycle, qt.floatValue(), 0.1, - "Distance since charging"); + if (imperial) { + assertEquals(MILES, qt.getUnit(), "Miles"); + assertEquals(allTrips.chargecycleRange.userCurrentChargeCycle / Constants.MILES_TO_KM_RATIO, + qt.floatValue(), 0.1, "Distance since charging"); + } else { + assertEquals(KILOMETRE, qt.getUnit(), "KM"); + assertEquals(allTrips.chargecycleRange.userCurrentChargeCycle, qt.floatValue(), 0.1, + "Distance since charging"); + } break; case SINGLE_LONGEST_DISTANCE: assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); - assertEquals(KILOMETRE, qt.getUnit(), "KM"); - assertEquals(allTrips.chargecycleRange.userHigh, qt.floatValue(), 0.1, "Longest Distance"); + if (imperial) { + assertEquals(MILES, qt.getUnit(), "Miles"); + assertEquals(allTrips.chargecycleRange.userHigh / Constants.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, + "Longest Distance"); + } else { + assertEquals(KILOMETRE, qt.getUnit(), "KM"); + assertEquals(allTrips.chargecycleRange.userHigh, qt.floatValue(), 0.1, "Longest Distance"); + } break; case CUMULATED_DRIVEN_DISTANCE: assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); - assertEquals(KILOMETRE, qt.getUnit(), "KM"); - assertEquals(allTrips.totalElectricDistance.userTotal, qt.floatValue(), 0.1, "Cumulated Distance"); + if (imperial) { + assertEquals(MILES, qt.getUnit(), "Miles"); + assertEquals(allTrips.totalElectricDistance.userTotal / Constants.MILES_TO_KM_RATIO, + qt.floatValue(), 0.1, "Cumulated Distance"); + } else { + assertEquals(KILOMETRE, qt.getUnit(), "KM"); + assertEquals(allTrips.totalElectricDistance.userTotal, qt.floatValue(), 0.1, "Cumulated Distance"); + } break; case AVG_CONSUMPTION: assertTrue(isElectric, "Is Electric"); assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); - assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw"); - assertEquals(allTrips.avgElectricConsumption.userAverage, qt.floatValue(), 0.1, "Avg Consumption"); + assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw/h"); + if (imperial) { + assertEquals(allTrips.avgElectricConsumption.userAverage * Constants.MILES_TO_KM_RATIO, + qt.floatValue(), 0.1, "Avg Consumption"); + } else { + assertEquals(allTrips.avgElectricConsumption.userAverage, qt.floatValue(), 0.1, "Avg Consumption"); + } break; case AVG_RECUPERATION: assertTrue(isElectric, "Is Electric"); assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); - assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw"); - assertEquals(allTrips.avgRecuperation.userAverage, qt.floatValue(), 0.1, "Avg Recuperation"); + assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw/h"); + if (imperial) { + assertEquals(allTrips.avgRecuperation.userAverage * Constants.MILES_TO_KM_RATIO, qt.floatValue(), + 0.1, "Avg Recuperation"); + } else { + assertEquals(allTrips.avgRecuperation.userAverage, qt.floatValue(), 0.1, "Avg Recuperation"); + } break; case AVG_COMBINED_CONSUMPTION: assertTrue(isHybrid, "Is Hybrid"); assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); assertEquals(Units.LITRE, qt.getUnit(), "Liter"); - assertEquals(allTrips.avgCombinedConsumption.userAverage, qt.floatValue(), 0.01, - "Avg Combined Consumption"); + if (imperial) { + assertEquals(allTrips.avgCombinedConsumption.userAverage * Constants.MILES_TO_KM_RATIO, + qt.floatValue(), 0.1, "Avg Combined Consumption"); + } else { + assertEquals(allTrips.avgCombinedConsumption.userAverage, qt.floatValue(), 0.1, + "Avg Combined Consumption"); + } break; default: // fail in case of unknown update diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java index d73f63820bbe7..8b1dbd8650a40 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java @@ -27,9 +27,11 @@ import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTrip; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTripContainer; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.QuantityType; +import org.openhab.core.library.unit.ImperialUnits; import org.openhab.core.library.unit.MetricPrefix; import org.openhab.core.library.unit.SIUnits; import org.openhab.core.library.unit.Units; @@ -47,9 +49,11 @@ @SuppressWarnings("null") public class TripWrapper { private static final Gson GSON = new Gson(); + private static final Unit MILES = ImperialUnits.MILE; private static final Unit KILOMETRE = MetricPrefix.KILO(SIUnits.METRE); private LastTrip lastTrip; + private boolean imperial; private boolean isElectric; private boolean hasFuel; private boolean isHybrid; @@ -57,6 +61,7 @@ public class TripWrapper { private Map specialHandlingMap = new HashMap(); public TripWrapper(String type, boolean imperial, String statusJson) { + this.imperial = imperial; hasFuel = type.equals(VehicleType.CONVENTIONAL.toString()) || type.equals(VehicleType.PLUGIN_HYBRID.toString()) || type.equals(VehicleType.ELECTRIC_REX.toString()); isElectric = type.equals(VehicleType.PLUGIN_HYBRID.toString()) @@ -117,27 +122,49 @@ private void checkResult(ChannelUID channelUID, State state) { case DISTANCE: assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); - assertEquals(KILOMETRE, qt.getUnit(), "KM"); - assertEquals(lastTrip.totalDistance, qt.floatValue(), 0.1, "Distance"); + if (imperial) { + assertEquals(MILES, qt.getUnit(), "Miles"); + assertEquals(lastTrip.totalDistance / Constants.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, + "Distance"); + + } else { + assertEquals(KILOMETRE, qt.getUnit(), "KM"); + assertEquals(lastTrip.totalDistance, qt.floatValue(), 0.1, "Distance"); + } break; case AVG_CONSUMPTION: assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); - assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw"); - assertEquals(lastTrip.avgElectricConsumption, qt.floatValue(), 0.1, "Avg Consumption"); + assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw/h"); + if (imperial) { + assertEquals(lastTrip.avgElectricConsumption * Constants.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, + "Avg Consumption"); + } else { + assertEquals(lastTrip.avgElectricConsumption, qt.floatValue(), 0.1, "Avg Consumption"); + } break; case AVG_COMBINED_CONSUMPTION: assertTrue(isHybrid, "Is Hybrid"); assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); assertEquals(Units.LITRE, qt.getUnit(), "Liter"); - assertEquals(Converter.round(lastTrip.avgCombinedConsumption), qt.floatValue(), 0.01, "Percent"); + if (imperial) { + assertEquals(Converter.round(lastTrip.avgCombinedConsumption * Constants.MILES_TO_KM_RATIO), + qt.floatValue(), 0.01, "Percent"); + } else { + assertEquals(Converter.round(lastTrip.avgCombinedConsumption), qt.floatValue(), 0.01, "Percent"); + } break; case AVG_RECUPERATION: assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); - assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw"); - assertEquals(lastTrip.avgRecuperation, qt.floatValue(), 0.1, "Avg Recuperation"); + assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw/h"); + if (imperial) { + assertEquals(lastTrip.avgRecuperation * Constants.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, + "Avg Recuperation"); + } else { + assertEquals(lastTrip.avgRecuperation, qt.floatValue(), 0.1, "Avg Recuperation"); + } break; default: // fail in case of unknown update diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AllTripTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AllTripTests.java index 1e171bc39e9ac..bd226cba06349 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AllTripTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AllTripTests.java @@ -117,4 +117,20 @@ public void test530E() { String content = FileReader.readFileInString("src/test/resources/responses/530E/all-trips.json"); assertTrue(testTrip(content, HYBRID_CALL_TIMES, Optional.empty())); } + + @Test + public void testi3RexImperial() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(VehicleType.ELECTRIC_REX.toString(), true); + String content = FileReader.readFileInString("src/test/resources/responses/I01_REX/all-trips.json"); + assertTrue(testTrip(content, HYBRID_CALL_TIMES, Optional.empty())); + } + + @Test + public void test530EImperial() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(VehicleType.PLUGIN_HYBRID.toString(), true); + String content = FileReader.readFileInString("src/test/resources/responses/530E/all-trips.json"); + assertTrue(testTrip(content, HYBRID_CALL_TIMES, Optional.empty())); + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/LastTripTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/LastTripTests.java index e082989870fb2..cb12b7c975e92 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/LastTripTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/LastTripTests.java @@ -117,4 +117,20 @@ public void test530E() { String content = FileReader.readFileInString("src/test/resources/responses/530E/last-trip.json"); assertTrue(testTrip(content, HYBRID_CALL_TIMES, Optional.empty())); } + + @Test + public void testi3RexImperial() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(VehicleType.ELECTRIC_REX.toString(), true); + String content = FileReader.readFileInString("src/test/resources/responses/I01_REX/last-trip.json"); + assertTrue(testTrip(content, HYBRID_CALL_TIMES, Optional.empty())); + } + + @Test + public void test530EImperial() { + logger.info("{}", Thread.currentThread().getStackTrace()[1].getMethodName()); + setup(VehicleType.PLUGIN_HYBRID.toString(), true); + String content = FileReader.readFileInString("src/test/resources/responses/530E/last-trip.json"); + assertTrue(testTrip(content, HYBRID_CALL_TIMES, Optional.empty())); + } } From 85e828b8eec6d9f3341dd2de51bb1b7cd43a91b3 Mon Sep 17 00:00:00 2001 From: Bernd Date: Sat, 2 Jan 2021 14:47:00 +0100 Subject: [PATCH 094/176] ensure channel label & id <= 25 chars Signed-off-by: Bernd --- .../README.md | 56 +++++++++---------- .../internal/ConnectedDriveConstants.java | 2 +- .../handler/VehicleChannelHandler.java | 7 +-- .../i18n/bmwconnecteddrive_de.properties | 15 +---- .../OH-INF/thing/charge-channel-types.xml | 8 +-- .../thing/destination-channel-types.xml | 4 +- .../thing/door-status-channel-types.xml | 8 +-- .../OH-INF/thing/ev-lifetime-group.xml | 2 +- .../OH-INF/thing/hybrid-lifetime-group.xml | 2 +- .../OH-INF/thing/image-channel-types.xml | 2 +- .../OH-INF/thing/last-trip-channel-types.xml | 6 +- .../OH-INF/thing/lifetime-channel-types.xml | 24 ++++---- .../internal/dto/LifetimeWrapper.java | 7 ++- 13 files changed, 67 insertions(+), 76 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index ea867edfc2499..dc62abecc149d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -227,10 +227,10 @@ Detailed status of all doors and windows. | Passenger Door Rear | passenger-rear | String | | Trunk | trunk | String | | Hood | hood | String | -| Driver Door Window | win-driver-front | String | -| Driver Door Rear Window | win-driver-rear | String | -| Passenger Door Window | win-passenger-front | String | -| Passenger Door Rear Window | win-passenger-rear | String | +| Driver Window | win-driver-front | String | +| Driver Rear Window | win-driver-rear | String | +| Passenger Window | win-passenger-front | String | +| Passenger Rear Window | win-passenger-rear | String | | Rear Window | win-rear | String | | Sunroof | sunroof | String | @@ -276,10 +276,10 @@ Charging options with date and time for preferred time windows and charging mode | Channel Label | Channel ID | Type | |------------------------------------|---------------------|--------| -| Air Conditioning at Departure Time | profile-climate | Switch | -| Charging Mode for Profile | profile-mode | String | -| Charging Window Start Time | window-start | String | -| Charging Window End Time | window-end | String | +| A/C at Departure Time | profile-climate | Switch | +| Charge Mode for Profile | profile-mode | String | +| Charge Window Start Time | window-start | String | +| Charge Window End Time | window-end | String | | Timer 1: Departure Time | timer1-departure | String | | Timer 1: Scheduled Days | timer1-days | String | | Timer 1: Enabled | timer1-enabled | Switch | @@ -318,10 +318,10 @@ Statistic values of duration, distance and consumption of the last trip. | Last Trip Date | date | DateTime | | Last Trip Duration | duration | Number:Time | | Last Trip Distance | distance | Number:Length | -| Distance since Last Charge | distance-since-charging | Number:Length | -| Average Power Consumption | avg-consumption | Number:Power | -| Average Power Recuperation | avg-recuperation | Number:Power | -| Average Combined Consumption | avg-combined-consumption | Number:Volume | +| Distance since Charge | distance-since-charging | Number:Length | +| Avg. Power Consumption | avg-consumption | Number:Power | +| Avg. Power Recuperation | avg-recuperation | Number:Power | +| Avg. Combined Consumption | avg-combined-consumption | Number:Volume | #### Lifetime Statistics @@ -335,11 +335,11 @@ Providing lifetime consumption values. | Channel Label | Channel ID | Type | |-----------------------------------------|------------------------------|---------------| -| Cumulated Electric Driven Distance | cumulated-driven-distance | Number:Length | -| Longest Distance with one Charge | single-longest-distance | Number:Length | -| Average Power Consumption | avg-consumption | Number:Power | -| Average Power Recuperation | avg-recuperation | Number:Power | -| Average Combined Consumption | avg-combined-consumption | Number:Volume | +| Total Electric Distance | total-driven-distance | Number:Length | +| Longest 1-Charge Distance | single-longest-distance | Number:Length | +| Avg. Power Consumption | avg-consumption | Number:Power | +| Avg. Power Recuperation | avg-recuperation | Number:Power | +| Avg. Combined Consumption | avg-combined-consumption | Number:Volume | #### Remote Services @@ -385,10 +385,10 @@ If several last destinations are stored in the navigation system the channel _na * Read/Write access -| Channel Label | Channel ID | Type | Access | -|----------------------------------|---------------------|-----------|-------------| -| Destination Name | name | String | Read/Write | -| Destination GPS Coordinates | gps | Location | Read | +| Channel Label | Channel ID | Type | Access | +|----------------------|---------------|-----------|-------------| +| Name | name | String | Read/Write | +| GPS Coordinates | gps | Location | Read | @@ -401,11 +401,11 @@ The possible values are the same mentioned in [Thing Configuration](#thing-confi * Available for all vehicles * Read/Write access -| Channel Label | Channel ID | Type | Access | -|-------------------------------|---------------------|--------|----------| -| Rendered Image of the Vehicle | png | Image | Read | -| Image Viewport | view | String | Write | -| Image Picture Size | size | Number | Write | +| Channel Label | Channel ID | Type | Access | +|----------------------------|---------------------|--------|----------| +| Rendered Vehicle Image | png | Image | Read | +| Image Viewport | view | String | Write | +| Image Picture Size | size | Number | Write | ## Further Descriptions @@ -526,7 +526,7 @@ Number:Energy i3AvgTripConsumption "Average Consumption [%.1f %un Number:Volume i3AvgTripCombined "Average Combined Consumption [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:last-trip#avg-combined-consumption" } Number:Energy i3AvgTripRecuperation "Average Recuperation [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:last-trip#avg-recuperation" } -Number:Length i3CumulatedElectric "Electric Distance Driven [%d %unit%]" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:lifetime#cumulated-driven-distance" } +Number:Length i3TotalElectric "Electric Distance Driven [%d %unit%]" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:lifetime#total-driven-distance" } Number:Length i3LongestEVTrip "Longest Electric Trip [%d %unit%]" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:lifetime#single-longest-distance" } Number:Energy i3AvgConsumption "Average Consumption [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:lifetime#avg-consumption" } Number:Volume i3AvgCombined "Average Combined Consumption [%.1f %unit%]" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:lifetime#avg-combined-consumption" } @@ -622,7 +622,7 @@ sitemap BMW label="BMW" { Text item=i3AvgTripCombined } Frame label="Lifetime" { - Text item=i3CumulatedElectric + Text item=i3TotalElectric Text item=i3LongestEVTrip Text item=i3AvgConsumption Text item=i3AvgRecuperation diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 30730b8ada6db..9a498b85bec4a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -156,7 +156,7 @@ public String toString() { public static final String AVG_RECUPERATION = "avg-recuperation"; // Lifetime + Average Consumptions - public static final String CUMULATED_DRIVEN_DISTANCE = "cumulated-driven-distance"; + public static final String TOTAL_DRIVEN_DISTANCE = "total-driven-distance"; public static final String SINGLE_LONGEST_DISTANCE = "single-longest-distance"; // Image diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index a1900f2e4144d..5247b83e800e5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -125,7 +125,7 @@ public class VehicleChannelHandler extends BaseThingHandler { protected ChannelUID lifeTimeAverageConsumption; protected ChannelUID lifetimeAvgCombinedConsumption; protected ChannelUID lifeTimeAverageRecuperation; - protected ChannelUID lifeTimeCumulatedDrivenDistance; + protected ChannelUID lifeTimeTotalDrivenDistance; protected ChannelUID lifeTimeSingleLongestDistance; // Last Trip Channels @@ -246,8 +246,7 @@ public VehicleChannelHandler(Thing thing, BMWConnectedDriveOptionProvider op, St lifetimeAvgCombinedConsumption = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, AVG_COMBINED_CONSUMPTION); lifeTimeAverageRecuperation = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, AVG_RECUPERATION); - lifeTimeCumulatedDrivenDistance = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, - CUMULATED_DRIVEN_DISTANCE); + lifeTimeTotalDrivenDistance = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, TOTAL_DRIVEN_DISTANCE); lifeTimeSingleLongestDistance = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, SINGLE_LONGEST_DISTANCE); // Location Channels @@ -440,7 +439,7 @@ protected void updateAllTrips(AllTrips allTrips) { avgCombinedConsumption *= Constants.MILES_TO_KM_RATIO; avgRecuperation *= Constants.MILES_TO_KM_RATIO; } - updateState(lifeTimeCumulatedDrivenDistance, + updateState(lifeTimeTotalDrivenDistance, QuantityType.valueOf(Converter.round(totalElectricDistance), lengthUnit)); updateState(lifeTimeSingleLongestDistance, QuantityType.valueOf(Converter.round(longestElectricTrip), lengthUnit)); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties index 861a6ae6afd0c..6919ef9a699ff 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties @@ -171,15 +171,9 @@ channel-type.bmwconnecteddrive.range-radius-hybrid-channel.label = Hybrider Reic channel-type.bmwconnecteddrive.service-name-channel.label = Service channel-type.bmwconnecteddrive.service-date-channel.label = Service Termin channel-type.bmwconnecteddrive.service-mileage-channel.label = Service in Kilometern -channel-type.bmwconnecteddrive.service-size-channel.label = Anzahl der Service Termine -channel-type.bmwconnecteddrive.service-index-channel.label = Index des ausgewählten Service -channel-type.bmwconnecteddrive.service-next-channel.label = Nächster Service channel-type.bmwconnecteddrive.checkcontrol-name-channel.label = Warnung channel-type.bmwconnecteddrive.checkcontrol-mileage-channel.label = Warnung bei Kilometer -channel-type.bmwconnecteddrive.checkcontrol-size-channel.label = Anzahl aktueller Warnungen -channel-type.bmwconnecteddrive.checkcontrol-index-channel.label = Index der ausgewählten Warnung -channel-type.bmwconnecteddrive.checkcontrol-next-channel.label = Nächste Warnung channel-type.bmwconnecteddrive.profile-climate-channel.label = Klimatisierung bei Abfahrt channel-type.bmwconnecteddrive.profile-mode-channel.label = Ladeprofil Einstellung @@ -197,9 +191,6 @@ channel-type.bmwconnecteddrive.timer3-enabled-channel.label = Zeitprofil 3 - Akt channel-type.bmwconnecteddrive.destination-name-channel.label = Zieladresse channel-type.bmwconnecteddrive.destination-gps-channel.label = Ziel Koordinaten -channel-type.bmwconnecteddrive.destination-size-channel.label = Anzahl der Fahrzeugziele -channel-type.bmwconnecteddrive.destination-index-channel.label = Index des Ausgewählten Ziels -channel-type.bmwconnecteddrive.destination-next-channel.label = Nächstes Ziel channel-type.bmwconnecteddrive.gps-channel.label = Koordinaten channel-type.bmwconnecteddrive.heading-channel.label = Ausrichtung @@ -207,14 +198,14 @@ channel-type.bmwconnecteddrive.heading-channel.label = Ausrichtung channel-type.bmwconnecteddrive.trip-date-time-channel.label = Datum channel-type.bmwconnecteddrive.trip-duration-channel.label = Dauer channel-type.bmwconnecteddrive.distance-channel.label = Distanz -channel-type.bmwconnecteddrive.distance-since-charging-channel.label = Distanz seit letzter Ladung +channel-type.bmwconnecteddrive.distance-since-charging-channel.label = Strecke seit Ladung channel-type.bmwconnecteddrive.average-consumption-channel.label = Elektrischer Verbrauch channel-type.bmwconnecteddrive.average-consumption-channel.description = Elektrischer Durchnittsverbaruch über 100 km/mi channel-type.bmwconnecteddrive.average-combined-consumption-channel.label = Kombinierter Verbrauch channel-type.bmwconnecteddrive.average-combined-consumption-channel.description = Kombinierter Durchnittsverbaruch in Liter über 100 km/mi channel-type.bmwconnecteddrive.average-recuperation-channel.label = Rekuperation Durchschnitt -channel-type.bmwconnecteddrive.average-recuperation-channel.label = Durchschnittliche Rekuperation über 100 km/mi -channel-type.bmwconnecteddrive.cumulated-driven-distance-channel.label = Elektrisch gefahrene Distanz +channel-type.bmwconnecteddrive.average-recuperation-channel.description = Durchschnittliche Rekuperation über 100 km/mi +channel-type.bmwconnecteddrive.total-driven-distance-channel.label = Elektrisch gefahrene Distanz channel-type.bmwconnecteddrive.single-longest-distance-channel.label = Längste Fahrt mit einer Ladung channel-type.bmwconnecteddrive.remote-command-channel.label = Kommando Auswahl diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml index cf261f7fa2136..c8ac18fcc4b3d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml @@ -5,19 +5,19 @@ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> Switch - + String - + String - + String - + String diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-channel-types.xml index 94c4ad3f5e479..4e87558a7db26 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/destination-channel-types.xml @@ -5,10 +5,10 @@ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> String - + Location - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/door-status-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/door-status-channel-types.xml index 00495611c94fb..dacd93e016901 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/door-status-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/door-status-channel-types.xml @@ -29,19 +29,19 @@ String - + String - + String - + String - + String diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/ev-lifetime-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/ev-lifetime-group.xml index b570bb09a7be3..fcf1a658413f0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/ev-lifetime-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/ev-lifetime-group.xml @@ -9,7 +9,7 @@ - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/hybrid-lifetime-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/hybrid-lifetime-group.xml index e8046bd9b4792..1def2fc89f5c7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/hybrid-lifetime-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/hybrid-lifetime-group.xml @@ -10,7 +10,7 @@ - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/image-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/image-channel-types.xml index 3ec6e8b74ab1d..a472e0c651503 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/image-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/image-channel-types.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> Image - + String diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/last-trip-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/last-trip-channel-types.xml index 28d2830057b78..df9fa0434a108 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/last-trip-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/last-trip-channel-types.xml @@ -22,17 +22,17 @@ Number:Energy - + Average electric power consumption per 100 km/mi Number:Volume - + Average combined consumption in liter per 100 km/mi Number:Energy - + Average electric recuperation per 100 km/mi diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/lifetime-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/lifetime-channel-types.xml index 007698fdc972b..4b1d42df36e7c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/lifetime-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/lifetime-channel-types.xml @@ -3,27 +3,27 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> + + Number:Length + + + + Number:Length + + Number:Energy - - Average electric power consumption per 100 km/mi + + Average Combined Consumption electric power consumption per 100 km/mi Number:Energy - + Average electric recuperation per 100 km/mi - - Number:Length - - Number:Volume - + Average combined consumption in liter per 100 km/mi - - Number:Length - - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java index 7efe5e1f8eeb4..648a99b2989c5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java @@ -129,16 +129,17 @@ private void checkResult(ChannelUID channelUID, State state) { assertEquals(allTrips.chargecycleRange.userHigh, qt.floatValue(), 0.1, "Longest Distance"); } break; - case CUMULATED_DRIVEN_DISTANCE: + case TOTAL_DRIVEN_DISTANCE: assertTrue(state instanceof QuantityType); qt = ((QuantityType) state); if (imperial) { assertEquals(MILES, qt.getUnit(), "Miles"); assertEquals(allTrips.totalElectricDistance.userTotal / Constants.MILES_TO_KM_RATIO, - qt.floatValue(), 0.1, "Cumulated Distance"); + qt.floatValue(), 0.1, "Total Electric Distance"); } else { assertEquals(KILOMETRE, qt.getUnit(), "KM"); - assertEquals(allTrips.totalElectricDistance.userTotal, qt.floatValue(), 0.1, "Cumulated Distance"); + assertEquals(allTrips.totalElectricDistance.userTotal, qt.floatValue(), 0.1, + "Total Electric Distance"); } break; case AVG_CONSUMPTION: From dce959b5fe08439d3bf97b2d9ea0b8a6392a00e9 Mon Sep 17 00:00:00 2001 From: Bernd Date: Sat, 2 Jan 2021 15:06:24 +0100 Subject: [PATCH 095/176] update readme refs to thing-configuration Signed-off-by: Bernd --- bundles/org.openhab.binding.bmwconnecteddrive/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index dc62abecc149d..6dee166e9fe13 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -311,7 +311,7 @@ Statistic values of duration, distance and consumption of the last trip. * Channel Group ID is **last-trip** * Available if *Statistics* is present in *Services Supported*. See [Vehicle Properties](#properties) for further details * Read-only values -* Depending on units configuration in [Thing Configuration](#thing_configuration) average values are given for 100 kilometers or miles +* Depending on units configuration in [Thing Configuration](#thing-configuration) average values are given for 100 kilometers or miles | Channel Label | Channel ID | Type | |-----------------------------------------|------------------------------|---------------| @@ -331,7 +331,7 @@ Providing lifetime consumption values. * Channel Group ID is **lifetime** * Available if *Statistics* is present in *Services Supported*. See [Vehicle Properties](#properties) for further details * Read-only values -* Depending on units configuration in [Thing Configuration](#thing_configuration) average values are given for 100 kilometers or miles +* Depending on units configuration in [Thing Configuration](#thing-configuration) average values are given for 100 kilometers or miles | Channel Label | Channel ID | Type | |-----------------------------------------|------------------------------|---------------| From 61acc7f909755b7bae592699723fc28f5368722d Mon Sep 17 00:00:00 2001 From: Bernd Date: Wed, 6 Jan 2021 00:27:05 +0100 Subject: [PATCH 096/176] remove local gitignore Signed-off-by: Bernd --- bundles/org.openhab.binding.bmwconnecteddrive/.gitignore | 1 - 1 file changed, 1 deletion(-) delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/.gitignore diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/.gitignore b/bundles/org.openhab.binding.bmwconnecteddrive/.gitignore deleted file mode 100644 index fbee6f910ae62..0000000000000 --- a/bundles/org.openhab.binding.bmwconnecteddrive/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/.README.md.html From fb398b1ea45fd143959c6e02cd034571a27a8f56 Mon Sep 17 00:00:00 2001 From: Bernd Date: Wed, 6 Jan 2021 23:11:28 +0100 Subject: [PATCH 097/176] Use QuantityType to convert km values into mi Signed-off-by: Bernd --- .../handler/VehicleChannelHandler.java | 146 +++++++++--------- .../internal/utils/Constants.java | 1 - .../internal/utils/Converter.java | 18 +++ .../internal/dto/LifetimeWrapper.java | 14 +- .../internal/dto/StatusWrapper.java | 30 ++-- .../internal/dto/TripWrapper.java | 9 +- 6 files changed, 119 insertions(+), 99 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 5247b83e800e5..3e674c07aac8c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -18,7 +18,6 @@ import java.util.List; import java.util.Optional; -import javax.measure.Unit; import javax.measure.quantity.Length; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -321,12 +320,14 @@ protected void selectCC(String selection) { if (selection.equals(entry.ccmDescriptionShort)) { selectedCC = selection; updateState(checkControlName, StringType.valueOf(entry.ccmDescriptionShort)); + QuantityType qtLength = QuantityType.valueOf(Converter.round(entry.ccmMileage), + MetricPrefix.KILO(SIUnits.METRE)); if (imperial) { updateState(checkControlMileage, QuantityType.valueOf(Converter.round(entry.ccmMileage), ImperialUnits.MILE)); + } else { - updateState(checkControlMileage, - QuantityType.valueOf(Converter.round(entry.ccmMileage), MetricPrefix.KILO(SIUnits.METRE))); + updateState(checkControlMileage, qtLength); } return; } @@ -423,28 +424,29 @@ private void setOptions(ChannelUID cuid, List options) { } protected void updateAllTrips(AllTrips allTrips) { - Unit lengthUnit = MetricPrefix.KILO(SIUnits.METRE); - double totalElectricDistance = allTrips.totalElectricDistance.userTotal; - double longestElectricTrip = allTrips.chargecycleRange.userHigh; - double distanceSinceCharging = allTrips.chargecycleRange.userCurrentChargeCycle; + QuantityType qtTotalElectric = QuantityType + .valueOf(Converter.round(allTrips.totalElectricDistance.userTotal), MetricPrefix.KILO(SIUnits.METRE)); + QuantityType qtLongestElectricRange = QuantityType + .valueOf(Converter.round(allTrips.chargecycleRange.userHigh), MetricPrefix.KILO(SIUnits.METRE)); + QuantityType qtDistanceSinceCharge = QuantityType.valueOf( + Converter.round(allTrips.chargecycleRange.userCurrentChargeCycle), MetricPrefix.KILO(SIUnits.METRE)); double avgConsumotion = allTrips.avgElectricConsumption.userAverage; double avgCombinedConsumption = allTrips.avgCombinedConsumption.userAverage; double avgRecuperation = allTrips.avgRecuperation.userAverage; if (imperial) { - lengthUnit = ImperialUnits.MILE; - totalElectricDistance /= Constants.MILES_TO_KM_RATIO; - longestElectricTrip /= Constants.MILES_TO_KM_RATIO; - distanceSinceCharging /= Constants.MILES_TO_KM_RATIO; - avgConsumotion *= Constants.MILES_TO_KM_RATIO; - avgCombinedConsumption *= Constants.MILES_TO_KM_RATIO; - avgRecuperation *= Constants.MILES_TO_KM_RATIO; + updateState(lifeTimeTotalDrivenDistance, Converter.getMiles(qtTotalElectric)); + updateState(lifeTimeSingleLongestDistance, Converter.getMiles(qtLongestElectricRange)); + updateState(tripDistanceSinceCharging, Converter.getMiles(qtDistanceSinceCharge)); + + // Conversion from kwh/100km to kwh/10mi has to be done manually + avgConsumotion *= Converter.MILES_TO_KM_RATIO; + avgCombinedConsumption *= Converter.MILES_TO_KM_RATIO; + avgRecuperation *= Converter.MILES_TO_KM_RATIO; + } else { + updateState(lifeTimeTotalDrivenDistance, qtTotalElectric); + updateState(lifeTimeSingleLongestDistance, qtLongestElectricRange); + updateState(tripDistanceSinceCharging, qtDistanceSinceCharge); } - updateState(lifeTimeTotalDrivenDistance, - QuantityType.valueOf(Converter.round(totalElectricDistance), lengthUnit)); - updateState(lifeTimeSingleLongestDistance, - QuantityType.valueOf(Converter.round(longestElectricTrip), lengthUnit)); - updateState(tripDistanceSinceCharging, - QuantityType.valueOf(Converter.round(distanceSinceCharging), lengthUnit)); updateState(lifeTimeAverageConsumption, QuantityType.valueOf(Converter.round(avgConsumotion), Units.KILOWATT_HOUR)); updateState(lifetimeAvgCombinedConsumption, @@ -457,21 +459,21 @@ protected void updateLastTrip(LastTrip trip) { // Whyever the Last Trip DateTime is delivered without offest - so LocalTime updateState(tripDateTime, DateTimeType.valueOf(Converter.getLocalDateTimeWithoutOffest(trip.date))); updateState(tripDuration, QuantityType.valueOf(trip.duration, Units.MINUTE)); - - double distance = trip.totalDistance; + QuantityType qtTotalDistance = QuantityType.valueOf(Converter.round(trip.totalDistance), + MetricPrefix.KILO(SIUnits.METRE)); double avgConsumtption = trip.avgElectricConsumption; double avgCombinedConsumption = trip.avgCombinedConsumption; double avgRecuperation = trip.avgRecuperation; - Unit lengthUnit = MetricPrefix.KILO(SIUnits.METRE); - if (imperial) { - distance /= Constants.MILES_TO_KM_RATIO; - avgConsumtption *= Constants.MILES_TO_KM_RATIO; - avgCombinedConsumption *= Constants.MILES_TO_KM_RATIO; - avgRecuperation *= Constants.MILES_TO_KM_RATIO; - lengthUnit = ImperialUnits.MILE; + updateState(tripDistance, Converter.getMiles(qtTotalDistance)); + + // Conversion from kwh/100km to kwh/10mi has to be done manually + avgConsumtption *= Converter.MILES_TO_KM_RATIO; + avgCombinedConsumption *= Converter.MILES_TO_KM_RATIO; + avgRecuperation *= Converter.MILES_TO_KM_RATIO; + } else { + updateState(tripDistance, qtTotalDistance); } - updateState(tripDistance, QuantityType.valueOf(Converter.round(distance), lengthUnit)); updateState(tripAvgConsumption, QuantityType.valueOf(Converter.round(avgConsumtption), Units.KILOWATT_HOUR)); updateState(tripAvgCombinedConsumption, QuantityType.valueOf(Converter.round(avgCombinedConsumption), Units.LITRE)); @@ -561,52 +563,52 @@ protected void updateVehicleStatus(VehicleStatus vStatus) { // Range values // based on unit of length decide if range shall be reported in km or miles - if (!imperial) { - updateState(mileage, QuantityType.valueOf(vStatus.mileage, MetricPrefix.KILO(SIUnits.METRE))); - float totalRange = 0; - if (isElectric) { - totalRange += vStatus.remainingRangeElectric; - updateState(remainingRangeElectric, - QuantityType.valueOf(vStatus.remainingRangeElectric, MetricPrefix.KILO(SIUnits.METRE))); - updateState(rangeRadiusElectric, QuantityType.valueOf( - Converter.guessRangeRadius(vStatus.remainingRangeElectric), MetricPrefix.KILO(SIUnits.METRE))); + float totalRange = 0; + if (isElectric) { + totalRange += vStatus.remainingRangeElectric; + QuantityType qtElectricRange = QuantityType.valueOf(vStatus.remainingRangeElectric, + MetricPrefix.KILO(SIUnits.METRE)); + QuantityType qtElectricRadius = QuantityType.valueOf( + Converter.guessRangeRadius(vStatus.remainingRangeElectric), MetricPrefix.KILO(SIUnits.METRE)); + if (imperial) { + updateState(remainingRangeElectric, Converter.getMiles(qtElectricRange)); + updateState(rangeRadiusElectric, Converter.getMiles(qtElectricRadius)); + } else { + updateState(remainingRangeElectric, qtElectricRange); + updateState(rangeRadiusElectric, qtElectricRadius); } - if (hasFuel) { - totalRange += vStatus.remainingRangeFuel; - updateState(remainingRangeFuel, - QuantityType.valueOf(vStatus.remainingRangeFuel, MetricPrefix.KILO(SIUnits.METRE))); - updateState(rangeRadiusFuel, QuantityType.valueOf( - Converter.guessRangeRadius(vStatus.remainingRangeFuel), MetricPrefix.KILO(SIUnits.METRE))); + } + if (hasFuel) { + totalRange += vStatus.remainingRangeFuel; + QuantityType qtFuealRange = QuantityType.valueOf(vStatus.remainingRangeFuel, + MetricPrefix.KILO(SIUnits.METRE)); + QuantityType qtFuelRadius = QuantityType + .valueOf(Converter.guessRangeRadius(vStatus.remainingRangeFuel), MetricPrefix.KILO(SIUnits.METRE)); + if (imperial) { + updateState(remainingRangeFuel, Converter.getMiles(qtFuealRange)); + updateState(rangeRadiusFuel, Converter.getMiles(qtFuelRadius)); + } else { + updateState(remainingRangeFuel, qtFuealRange); + updateState(rangeRadiusFuel, qtFuelRadius); } - if (isHybrid) { - updateState(remainingRangeHybrid, - QuantityType.valueOf(Converter.round(totalRange), MetricPrefix.KILO(SIUnits.METRE))); - updateState(rangeRadiusHybrid, - QuantityType.valueOf(Converter.guessRangeRadius(totalRange), MetricPrefix.KILO(SIUnits.METRE))); + } + if (isHybrid) { + QuantityType qtHybridRange = QuantityType.valueOf(totalRange, MetricPrefix.KILO(SIUnits.METRE)); + QuantityType qtHybridRadius = QuantityType.valueOf(Converter.guessRangeRadius(totalRange), + MetricPrefix.KILO(SIUnits.METRE)); + if (imperial) { + updateState(remainingRangeHybrid, Converter.getMiles(qtHybridRange)); + updateState(rangeRadiusHybrid, Converter.getMiles(qtHybridRadius)); + } else { + updateState(remainingRangeHybrid, qtHybridRange); + updateState(rangeRadiusHybrid, qtHybridRadius); } - } else { + } + + if (imperial) { updateState(mileage, QuantityType.valueOf(vStatus.mileage, ImperialUnits.MILE)); - float totalRange = 0; - if (isElectric) { - totalRange += vStatus.remainingRangeElectricMls; - updateState(remainingRangeElectric, - QuantityType.valueOf(vStatus.remainingRangeElectricMls, ImperialUnits.MILE)); - updateState(rangeRadiusElectric, QuantityType - .valueOf(Converter.guessRangeRadius(vStatus.remainingRangeElectricMls), ImperialUnits.MILE)); - } - if (hasFuel) { - totalRange += vStatus.remainingRangeFuelMls; - updateState(remainingRangeFuel, - QuantityType.valueOf(vStatus.remainingRangeFuelMls, ImperialUnits.MILE)); - updateState(rangeRadiusFuel, QuantityType - .valueOf(Converter.guessRangeRadius(vStatus.remainingRangeFuelMls), ImperialUnits.MILE)); - } - if (isHybrid) { - updateState(remainingRangeHybrid, - QuantityType.valueOf(Converter.round(totalRange), ImperialUnits.MILE)); - updateState(rangeRadiusHybrid, - QuantityType.valueOf(Converter.guessRangeRadius(totalRange), ImperialUnits.MILE)); - } + } else { + updateState(mileage, QuantityType.valueOf(vStatus.mileage, MetricPrefix.KILO(SIUnits.METRE))); } if (isElectric) { updateState(remainingSoc, QuantityType.valueOf(vStatus.chargingLevelHv, Units.PERCENT)); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java index ffd486f1e4afd..82681df3db477 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -60,7 +60,6 @@ public class Constants { public static final String ANONYMOUS = "Anonymous"; public static final int MILES_TO_FEET_FACTOR = 5280; - public static final double MILES_TO_KM_RATIO = 1.60934; public static final String EMPTY_VEHICLES = "{}"; @SuppressWarnings("serial") diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java index 38b9875b51972..ac5e19d3adecb 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java @@ -19,9 +19,13 @@ import java.time.format.DateTimeParseException; import java.util.Optional; +import javax.measure.quantity.Length; + import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.core.i18n.TimeZoneProvider; +import org.openhab.core.library.types.QuantityType; +import org.openhab.core.library.unit.ImperialUnits; import com.google.gson.Gson; @@ -50,6 +54,8 @@ public class Converter { private static final Gson GSON = new Gson(); private static final double SCALE = 10; + public static final double MILES_TO_KM_RATIO = 1.60934; + private static final QuantityType UNDEF_MILES = QuantityType.valueOf(-1, ImperialUnits.MILE); public static Optional timeZoneProvider = Optional.empty(); @@ -162,4 +168,16 @@ public static double measureDistance(double sourceLatitude, double sourceLongitu public static double guessRangeRadius(double range) { return range * 0.8; } + + public static QuantityType getMiles(QuantityType qtLength) { + if (qtLength.intValue() == -1) { + return UNDEF_MILES; + } + QuantityType qt = qtLength.toUnit(ImperialUnits.MILE); + if (qt != null) { + return qt; + } else { + return QuantityType.valueOf(qtLength.doubleValue() / MILES_TO_KM_RATIO, ImperialUnits.MILE); + } + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java index 648a99b2989c5..7d0abe62c9cbe 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java @@ -27,7 +27,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTrips; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTripsContainer; -import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.unit.ImperialUnits; import org.openhab.core.library.unit.MetricPrefix; @@ -109,7 +109,7 @@ private void checkResult(ChannelUID channelUID, State state) { qt = ((QuantityType) state); if (imperial) { assertEquals(MILES, qt.getUnit(), "Miles"); - assertEquals(allTrips.chargecycleRange.userCurrentChargeCycle / Constants.MILES_TO_KM_RATIO, + assertEquals(allTrips.chargecycleRange.userCurrentChargeCycle / Converter.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, "Distance since charging"); } else { assertEquals(KILOMETRE, qt.getUnit(), "KM"); @@ -122,7 +122,7 @@ private void checkResult(ChannelUID channelUID, State state) { qt = ((QuantityType) state); if (imperial) { assertEquals(MILES, qt.getUnit(), "Miles"); - assertEquals(allTrips.chargecycleRange.userHigh / Constants.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, + assertEquals(allTrips.chargecycleRange.userHigh / Converter.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, "Longest Distance"); } else { assertEquals(KILOMETRE, qt.getUnit(), "KM"); @@ -134,7 +134,7 @@ private void checkResult(ChannelUID channelUID, State state) { qt = ((QuantityType) state); if (imperial) { assertEquals(MILES, qt.getUnit(), "Miles"); - assertEquals(allTrips.totalElectricDistance.userTotal / Constants.MILES_TO_KM_RATIO, + assertEquals(allTrips.totalElectricDistance.userTotal / Converter.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, "Total Electric Distance"); } else { assertEquals(KILOMETRE, qt.getUnit(), "KM"); @@ -148,7 +148,7 @@ private void checkResult(ChannelUID channelUID, State state) { qt = ((QuantityType) state); assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw/h"); if (imperial) { - assertEquals(allTrips.avgElectricConsumption.userAverage * Constants.MILES_TO_KM_RATIO, + assertEquals(allTrips.avgElectricConsumption.userAverage * Converter.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, "Avg Consumption"); } else { assertEquals(allTrips.avgElectricConsumption.userAverage, qt.floatValue(), 0.1, "Avg Consumption"); @@ -160,7 +160,7 @@ private void checkResult(ChannelUID channelUID, State state) { qt = ((QuantityType) state); assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw/h"); if (imperial) { - assertEquals(allTrips.avgRecuperation.userAverage * Constants.MILES_TO_KM_RATIO, qt.floatValue(), + assertEquals(allTrips.avgRecuperation.userAverage * Converter.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, "Avg Recuperation"); } else { assertEquals(allTrips.avgRecuperation.userAverage, qt.floatValue(), 0.1, "Avg Recuperation"); @@ -172,7 +172,7 @@ private void checkResult(ChannelUID channelUID, State state) { qt = ((QuantityType) state); assertEquals(Units.LITRE, qt.getUnit(), "Liter"); if (imperial) { - assertEquals(allTrips.avgCombinedConsumption.userAverage * Constants.MILES_TO_KM_RATIO, + assertEquals(allTrips.avgCombinedConsumption.userAverage * Converter.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, "Avg Combined Consumption"); } else { assertEquals(allTrips.avgCombinedConsumption.userAverage, qt.floatValue(), 0.1, diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index eb6ee93171f19..7ec66d6e38361 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -55,6 +55,8 @@ public class StatusWrapper { private static final Gson GSON = new Gson(); private static final Unit KILOMETRE = MetricPrefix.KILO(SIUnits.METRE); + private static double ALLOWED_MILE_CONVERSION_DEVIATION = 1.5; + private static double ALLOWED_KM_ROUND_DEVIATION = 0.1; private VehicleStatus vStatus; private boolean imperial; @@ -154,11 +156,11 @@ private void checkResult(ChannelUID channelUID, State state) { if (imperial) { assertEquals(ImperialUnits.MILE, qt.getUnit(), "Miles"); assertEquals(Converter.round(qt.floatValue()), Converter.round(vStatus.remainingRangeElectricMls), - 0.01, "Mileage"); + ALLOWED_MILE_CONVERSION_DEVIATION, "Mileage"); } else { assertEquals(KILOMETRE, qt.getUnit(), "KM"); assertEquals(Converter.round(qt.floatValue()), Converter.round(vStatus.remainingRangeElectric), - 0.01, "Mileage"); + ALLOWED_KM_ROUND_DEVIATION, "Mileage"); } break; case RANGE_FUEL: @@ -167,12 +169,12 @@ private void checkResult(ChannelUID channelUID, State state) { qt = ((QuantityType) state); if (imperial) { assertEquals(ImperialUnits.MILE, qt.getUnit(), "Miles"); - assertEquals(Converter.round(qt.floatValue()), Converter.round(vStatus.remainingRangeFuelMls), 0.01, - "Mileage"); + assertEquals(Converter.round(qt.floatValue()), Converter.round(vStatus.remainingRangeFuelMls), + ALLOWED_MILE_CONVERSION_DEVIATION, "Mileage"); } else { assertEquals(KILOMETRE, qt.getUnit(), "KM"); - assertEquals(Converter.round(qt.floatValue()), Converter.round(vStatus.remainingRangeFuel), 0.01, - "Mileage"); + assertEquals(Converter.round(qt.floatValue()), Converter.round(vStatus.remainingRangeFuel), + ALLOWED_KM_ROUND_DEVIATION, "Mileage"); } break; case RANGE_HYBRID: @@ -182,13 +184,13 @@ private void checkResult(ChannelUID channelUID, State state) { if (imperial) { assertEquals(ImperialUnits.MILE, qt.getUnit(), "Miles"); assertEquals(Converter.round(qt.floatValue()), - Converter.round(vStatus.remainingRangeElectricMls + vStatus.remainingRangeFuelMls), 0.01, - "Mileage"); + Converter.round(vStatus.remainingRangeElectricMls + vStatus.remainingRangeFuelMls), + ALLOWED_MILE_CONVERSION_DEVIATION, "Mileage"); } else { assertEquals(KILOMETRE, qt.getUnit(), "KM"); assertEquals(Converter.round(qt.floatValue()), - Converter.round(vStatus.remainingRangeElectric + vStatus.remainingRangeFuel), 0.01, - "Mileage"); + Converter.round(vStatus.remainingRangeElectric + vStatus.remainingRangeFuel), + ALLOWED_KM_ROUND_DEVIATION, "Mileage"); } break; case REMAINING_FUEL: @@ -283,7 +285,7 @@ private void checkResult(ChannelUID channelUID, State state) { assertTrue(isElectric); qt = (QuantityType) state; if (imperial) { - assertEquals(Converter.guessRangeRadius(vStatus.remainingRangeElectricMls), qt.floatValue(), 0.1, + assertEquals(Converter.guessRangeRadius(vStatus.remainingRangeElectricMls), qt.floatValue(), 1, "Range Radius Electric mi"); } else { assertEquals(Converter.guessRangeRadius(vStatus.remainingRangeElectric), qt.floatValue(), 0.1, @@ -295,7 +297,7 @@ private void checkResult(ChannelUID channelUID, State state) { assertTrue(hasFuel); qt = (QuantityType) state; if (imperial) { - assertEquals(Converter.guessRangeRadius(vStatus.remainingRangeFuelMls), qt.floatValue(), 0.1, + assertEquals(Converter.guessRangeRadius(vStatus.remainingRangeFuelMls), qt.floatValue(), 1, "Range Radius Fuel mi"); } else { assertEquals(Converter.guessRangeRadius(vStatus.remainingRangeFuel), qt.floatValue(), 0.1, @@ -310,11 +312,11 @@ private void checkResult(ChannelUID channelUID, State state) { assertEquals( Converter.guessRangeRadius( vStatus.remainingRangeElectricMls + vStatus.remainingRangeFuelMls), - qt.floatValue(), 0.1, "Range Radius Hybrid mi"); + qt.floatValue(), ALLOWED_MILE_CONVERSION_DEVIATION, "Range Radius Hybrid mi"); } else { assertEquals( Converter.guessRangeRadius(vStatus.remainingRangeElectric + vStatus.remainingRangeFuel), - qt.floatValue(), 0.1, "Range Radius Hybrid km"); + qt.floatValue(), ALLOWED_KM_ROUND_DEVIATION, "Range Radius Hybrid km"); } break; case DOOR_DRIVER_FRONT: diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java index 8b1dbd8650a40..1a8feed605df3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java @@ -27,7 +27,6 @@ import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTrip; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTripContainer; -import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.QuantityType; @@ -124,7 +123,7 @@ private void checkResult(ChannelUID channelUID, State state) { qt = ((QuantityType) state); if (imperial) { assertEquals(MILES, qt.getUnit(), "Miles"); - assertEquals(lastTrip.totalDistance / Constants.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, + assertEquals(lastTrip.totalDistance / Converter.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, "Distance"); } else { @@ -137,7 +136,7 @@ private void checkResult(ChannelUID channelUID, State state) { qt = ((QuantityType) state); assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw/h"); if (imperial) { - assertEquals(lastTrip.avgElectricConsumption * Constants.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, + assertEquals(lastTrip.avgElectricConsumption * Converter.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, "Avg Consumption"); } else { assertEquals(lastTrip.avgElectricConsumption, qt.floatValue(), 0.1, "Avg Consumption"); @@ -149,7 +148,7 @@ private void checkResult(ChannelUID channelUID, State state) { qt = ((QuantityType) state); assertEquals(Units.LITRE, qt.getUnit(), "Liter"); if (imperial) { - assertEquals(Converter.round(lastTrip.avgCombinedConsumption * Constants.MILES_TO_KM_RATIO), + assertEquals(Converter.round(lastTrip.avgCombinedConsumption * Converter.MILES_TO_KM_RATIO), qt.floatValue(), 0.01, "Percent"); } else { assertEquals(Converter.round(lastTrip.avgCombinedConsumption), qt.floatValue(), 0.01, "Percent"); @@ -160,7 +159,7 @@ private void checkResult(ChannelUID channelUID, State state) { qt = ((QuantityType) state); assertEquals(Units.KILOWATT_HOUR, qt.getUnit(), "kw/h"); if (imperial) { - assertEquals(lastTrip.avgRecuperation * Constants.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, + assertEquals(lastTrip.avgRecuperation * Converter.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, "Avg Recuperation"); } else { assertEquals(lastTrip.avgRecuperation, qt.floatValue(), 0.1, "Avg Recuperation"); From f026bb546a2bfa5775c7efef95b5288acbc2ba2d Mon Sep 17 00:00:00 2001 From: Bernd Date: Fri, 8 Jan 2021 10:33:23 +0100 Subject: [PATCH 098/176] select int index instead of string value Signed-off-by: Bernd --- .../handler/VehicleChannelHandler.java | 121 ++++++++++-------- .../internal/handler/VehicleHandler.java | 21 ++- .../internal/utils/Converter.java | 9 ++ .../internal/dto/StatusWrapper.java | 4 +- 4 files changed, 96 insertions(+), 59 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 3e674c07aac8c..c1a6136d12f4e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -299,39 +299,41 @@ protected void updateCheckControls(List ccl) { // add all elements to options checkControlList = ccl; - List options = new ArrayList<>(); + List ccmDescriptionOptions = new ArrayList<>(); + List ccmMileageOptions = new ArrayList<>(); boolean isSelectedElementIn = false; + int index = 0; for (CCMMessage ccEntry : checkControlList) { - options.add(new StateOption(ccEntry.ccmDescriptionShort, ccEntry.ccmDescriptionShort)); + ccmDescriptionOptions.add(new StateOption(Integer.toString(index), ccEntry.ccmDescriptionShort)); + ccmMileageOptions.add(new StateOption(Integer.toString(index), Integer.toString(ccEntry.ccmMileage))); if (selectedCC.equals(ccEntry.ccmDescriptionShort)) { isSelectedElementIn = true; } + index++; } - setOptions(checkControlName, options); + setOptions(checkControlName, ccmDescriptionOptions); + setOptions(checkControlMileage, ccmMileageOptions); // if current selected item isn't anymore in the list select first entry if (!isSelectedElementIn) { - selectCC(checkControlList.get(0).ccmDescriptionShort); + selectCheckControl(0); } } - protected void selectCC(String selection) { - checkControlList.forEach(entry -> { - if (selection.equals(entry.ccmDescriptionShort)) { - selectedCC = selection; - updateState(checkControlName, StringType.valueOf(entry.ccmDescriptionShort)); - QuantityType qtLength = QuantityType.valueOf(Converter.round(entry.ccmMileage), - MetricPrefix.KILO(SIUnits.METRE)); - if (imperial) { - updateState(checkControlMileage, - QuantityType.valueOf(Converter.round(entry.ccmMileage), ImperialUnits.MILE)); - - } else { - updateState(checkControlMileage, qtLength); - } - return; + protected void selectCheckControl(int index) { + if (index >= 0 && index < checkControlList.size()) { + CCMMessage ccEntry = checkControlList.get(index); + selectedCC = ccEntry.ccmDescriptionShort; + updateState(checkControlName, StringType.valueOf(ccEntry.ccmDescriptionShort)); + QuantityType qtLength = QuantityType.valueOf(Converter.round(ccEntry.ccmMileage), + MetricPrefix.KILO(SIUnits.METRE)); + if (imperial) { + updateState(checkControlMileage, + QuantityType.valueOf(Converter.round(ccEntry.ccmMileage), ImperialUnits.MILE)); + } else { + updateState(checkControlMileage, qtLength); } - }); + } } protected void updateServices(List sl) { @@ -344,38 +346,46 @@ protected void updateServices(List sl) { // add all elements to options serviceList = sl; - List options = new ArrayList<>(); + List serviceNameOptions = new ArrayList<>(); + List serviceDateOptions = new ArrayList<>(); + List serviceMileageOptions = new ArrayList<>(); boolean isSelectedElementIn = false; + int index = 0; for (CBSMessage serviceEntry : serviceList) { - options.add(new StateOption(serviceEntry.getType(), serviceEntry.getType())); + // create StateOption with "value = list index" and "label = human readable string" + serviceNameOptions.add(new StateOption(Integer.toString(index), serviceEntry.getType())); + serviceDateOptions.add(new StateOption(Integer.toString(index), serviceEntry.getDueDate())); + serviceMileageOptions + .add(new StateOption(Integer.toString(index), Integer.toString(serviceEntry.cbsRemainingMileage))); if (selectedService.equals(serviceEntry.getType())) { isSelectedElementIn = true; } + index++; } - setOptions(serviceName, options); + setOptions(serviceName, serviceNameOptions); + setOptions(serviceDate, serviceDateOptions); + setOptions(serviceMileage, serviceMileageOptions); // if current selected item isn't anymore in the list select first entry if (!isSelectedElementIn) { - selectService(serviceList.get(0).getType()); + selectService(0); } } - protected void selectService(String selection) { - serviceList.forEach(entry -> { - if (selection.equals(entry.getType())) { - selectedService = selection; - updateState(serviceName, StringType.valueOf(Converter.toTitleCase(entry.getType()))); - updateState(serviceDate, DateTimeType.valueOf(Converter.getLocalDateTime(entry.getDueDate()))); - if (imperial) { - updateState(serviceMileage, - QuantityType.valueOf(Converter.round(entry.cbsRemainingMileage), ImperialUnits.MILE)); - } else { - updateState(serviceMileage, QuantityType.valueOf(Converter.round(entry.cbsRemainingMileage), - MetricPrefix.KILO(SIUnits.METRE))); - } - return; + protected void selectService(int index) { + if (index >= 0 && index < serviceList.size()) { + CBSMessage serviceEntry = serviceList.get(index); + selectedService = serviceEntry.cbsType; + updateState(serviceName, StringType.valueOf(Converter.toTitleCase(serviceEntry.getType()))); + updateState(serviceDate, DateTimeType.valueOf(Converter.getLocalDateTime(serviceEntry.getDueDate()))); + if (imperial) { + updateState(serviceMileage, + QuantityType.valueOf(Converter.round(serviceEntry.cbsRemainingMileage), ImperialUnits.MILE)); + } else { + updateState(serviceMileage, QuantityType.valueOf(Converter.round(serviceEntry.cbsRemainingMileage), + MetricPrefix.KILO(SIUnits.METRE))); } - }); + } } protected void updateDestinations(List dl) { @@ -390,33 +400,36 @@ protected void updateDestinations(List dl) { // add all elements to options destinationList = dl; - List options = new ArrayList<>(); + List destinationNameOptions = new ArrayList<>(); + List destinationGPSOptions = new ArrayList<>(); boolean isSelectedElementIn = false; + int index = 0; for (Destination destination : destinationList) { - options.add(new StateOption(destination.getAddress(), destination.getAddress())); + destinationNameOptions.add(new StateOption(Integer.toString(index), destination.getAddress())); + destinationGPSOptions.add(new StateOption(Integer.toString(index), destination.getCoordinates())); if (selectedDestination.equals(destination.getAddress())) { isSelectedElementIn = true; } + index++; } - setOptions(destinationName, options); + setOptions(destinationName, destinationNameOptions); + setOptions(destinationLocation, destinationGPSOptions); // if current selected item isn't anymore in the list select first entry if (!isSelectedElementIn) { - selectDestination(destinationList.get(0).getAddress()); + selectDestination(0); } } - protected void selectDestination(String selection) { - destinationList.forEach(entry -> { - if (selection.equals(entry.getAddress())) { - // update selected Item - selectedDestination = selection; - // update coordinates according to new set location - updateState(destinationName, StringType.valueOf(entry.getAddress())); - updateState(destinationLocation, PointType.valueOf(entry.getCoordinates())); - return; - } - }); + protected void selectDestination(int index) { + if (index >= 0 && index < destinationList.size()) { + Destination destinationEntry = destinationList.get(index); + // update selected Item + selectedDestination = destinationEntry.getAddress(); + // update coordinates according to new set location + updateState(destinationName, StringType.valueOf(destinationEntry.getAddress())); + updateState(destinationLocation, PointType.valueOf(destinationEntry.getCoordinates())); + } } private void setOptions(ChannelUID cuid, List options) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index ba4843663d5f1..5a1b1b39dadf0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -169,15 +169,30 @@ public void handleCommand(ChannelUID channelUID, Command command) { } } else if (CHANNEL_GROUP_DESTINATION.equals(group)) { if (command instanceof StringType) { - selectDestination(((StringType) command).toFullString()); + int index = Converter.getIndex(command.toFullString()); + if (index != -1) { + selectDestination(index); + } else { + logger.debug("Cannot select Destination index {}", command.toFullString()); + } } } else if (CHANNEL_GROUP_SERVICE.equals(group)) { if (command instanceof StringType) { - selectService(((StringType) command).toFullString()); + int index = Converter.getIndex(command.toFullString()); + if (index != -1) { + selectService(index); + } else { + logger.debug("Cannot select Service index {}", command.toFullString()); + } } } else if (CHANNEL_GROUP_CHECK_CONTROL.equals(group)) { if (command instanceof StringType) { - selectCC(((StringType) command).toFullString()); + int index = Converter.getIndex(command.toFullString()); + if (index != -1) { + selectCheckControl(index); + } else { + logger.debug("Cannot select CheckControl index {}", command.toFullString()); + } } } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java index ac5e19d3adecb..261c61071119b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java @@ -180,4 +180,13 @@ public static QuantityType getMiles(QuantityType qtLength) { return QuantityType.valueOf(qtLength.doubleValue() / MILES_TO_KM_RATIO, ImperialUnits.MILE); } } + + public static int getIndex(String fullString) { + int index = -1; + try { + index = Integer.parseInt(fullString); + } catch (NumberFormatException nfe) { + } + return index; + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index 7ec66d6e38361..1f01d19b91bb9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -55,8 +55,8 @@ public class StatusWrapper { private static final Gson GSON = new Gson(); private static final Unit KILOMETRE = MetricPrefix.KILO(SIUnits.METRE); - private static double ALLOWED_MILE_CONVERSION_DEVIATION = 1.5; - private static double ALLOWED_KM_ROUND_DEVIATION = 0.1; + private static final double ALLOWED_MILE_CONVERSION_DEVIATION = 1.5; + private static final double ALLOWED_KM_ROUND_DEVIATION = 0.1; private VehicleStatus vStatus; private boolean imperial; From d09988b42c886d1cd3e1534edb7cb4e66215f725 Mon Sep 17 00:00:00 2001 From: Bernd Date: Fri, 8 Jan 2021 13:46:22 +0100 Subject: [PATCH 099/176] improve address conversion and undef values Signed-off-by: Bernd --- .../internal/dto/Destination.java | 41 +++++++++++-------- .../internal/dto/status/CBSMessage.java | 14 +++++-- .../internal/dto/status/VehicleStatus.java | 10 ++--- .../internal/utils/Constants.java | 1 + .../internal/utils/Converter.java | 24 ++++++++--- .../internal/utils/VehicleStatusUtils.java | 3 +- .../internal/util/LocaleTest.java | 3 +- 7 files changed, 61 insertions(+), 35 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java index c76c501123d91..eb6f29705e71c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java @@ -32,29 +32,38 @@ public class Destination { public String type; public String createdAt; + private String address = null; + private String coordinates = null; + public String getAddress() { - StringBuilder buf = new StringBuilder(); - if (street != null) { - buf.append(street); - if (streetNumber != null) { - buf.append(SPACE).append(streetNumber); + if (address == null) { + StringBuilder buf = new StringBuilder(); + if (street != null) { + buf.append(street); + if (streetNumber != null) { + buf.append(SPACE).append(streetNumber); + } } - } - if (city != null) { - if (buf.length() > 0) { - buf.append(COMMA).append(SPACE).append(city); + if (city != null) { + if (buf.length() > 0) { + buf.append(COMMA).append(SPACE).append(city); + } else { + buf.append(city); + } + } + if (buf.length() == 0) { + address = UNDEF; } else { - buf.append(city); + address = Converter.toTitleCase(buf.toString()); } } - if (buf.length() == 0) { - return UNDEF; - } else { - return Converter.toTitleCase(buf.toString()); - } + return address; } public String getCoordinates() { - return new StringBuilder().append(lat).append(Constants.COMMA).append(lon).toString(); + if (coordinates == null) { + coordinates = new StringBuilder().append(lat).append(Constants.COMMA).append(lon).toString(); + } + return coordinates; } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java index 6d7862c92d635..5ef08fdb45604 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java @@ -13,6 +13,7 @@ package org.openhab.binding.bmwconnecteddrive.internal.dto.status; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; /** * The {@link CBSMessage} Data Transfer Object @@ -26,6 +27,8 @@ public class CBSMessage { public String cbsDescription;// ": "Next change due at the latest by the stated date." public int cbsRemainingMileage = -1; // 46000 + public String cbsTypeConverted = null; + public String getDueDate() { if (cbsDueDate == null) { return Constants.NULL_DATE; @@ -35,11 +38,14 @@ public String getDueDate() { } public String getType() { - if (cbsType == null) { - return Constants.INVALID; - } else { - return cbsType; + if (cbsTypeConverted == null) { + if (cbsType == null) { + cbsTypeConverted = Constants.INVALID; + } else { + cbsTypeConverted = Converter.toTitleCase(cbsType); + } } + return cbsTypeConverted; } @Override diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java index 9641896f31791..80e8fe303b500 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java @@ -25,13 +25,13 @@ * @author Bernd Weymann - Initial contribution */ public class VehicleStatus { - public int mileage;// ": 17273, - public double remainingFuel;// ": 4, - public double remainingRangeElectric;// ": 148, + public int mileage = Constants.INT_UNDEF;// ": 17273, + public double remainingFuel = Constants.INT_UNDEF;// ": 4, + public double remainingRangeElectric = Constants.INT_UNDEF;// ": 148, public double remainingRangeElectricMls;// ": 91, - public double remainingRangeFuel;// ": 70," + public double remainingRangeFuel = Constants.INT_UNDEF;// ": 70," public double remainingRangeFuelMls;// ":43," - public double maxRangeElectric;// ":216," + public double maxRangeElectric = Constants.INT_UNDEF;// ":216," public double maxRangeElectricMls;// ":134," public double maxFuel;// ":8.5, public double chargingLevelHv;// ":71, diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java index 82681df3db477..69b91edd35452 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -37,6 +37,7 @@ public class Constants { public static final String UNDEF = UnDefType.UNDEF.toFullString(); public static final String UTC_APPENDIX = "-01T12:00:00"; public static final String NULL_DATE = "1900-01-01T00:00:00"; + public static final int INT_UNDEF = -1; // Services to query public static final String SERVICES_SUPPORTED = "servicesSupported"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java index 261c61071119b..0fe90229558c2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java @@ -56,6 +56,8 @@ public class Converter { private static final double SCALE = 10; public static final double MILES_TO_KM_RATIO = 1.60934; private static final QuantityType UNDEF_MILES = QuantityType.valueOf(-1, ImperialUnits.MILE); + private static final String SPLIT_HYPHEN = "-"; + private static final String SPLIT_BRACKET = "\\("; public static Optional timeZoneProvider = Optional.empty(); @@ -108,16 +110,26 @@ public static void setTimeZoneProvider(TimeZoneProvider tzp) { public static String toTitleCase(@Nullable String input) { if (input == null) { - return Converter.toTitleCase(Constants.UNDEF); + return toTitleCase(Constants.UNDEF); } else { String lower = input.replaceAll(Constants.UNDERLINE, Constants.SPACE).toLowerCase(); - String[] arr = lower.split(Constants.SPACE); - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < arr.length; i++) { - sb.append(Character.toUpperCase(arr[i].charAt(0))).append(arr[i].substring(1)).append(" "); + String converted = toTitleCase(lower, Constants.SPACE); + converted = toTitleCase(converted, SPLIT_HYPHEN); + converted = toTitleCase(converted, SPLIT_BRACKET); + return converted; + } + } + + private static String toTitleCase(String input, String splitter) { + String[] arr = input.split(splitter); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < arr.length; i++) { + if (i > 0) { + sb.append(splitter.replaceAll("\\\\", Constants.EMPTY)); } - return sb.toString().trim(); + sb.append(Character.toUpperCase(arr[i].charAt(0))).append(arr[i].substring(1)); } + return sb.toString().trim(); } public static String capitalizeFirst(String str) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/VehicleStatusUtils.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/VehicleStatusUtils.java index bdbb80b9b0866..f537c71386c0b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/VehicleStatusUtils.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/VehicleStatusUtils.java @@ -136,9 +136,8 @@ public static String checkClosed(Object dto) { } } } catch (IllegalArgumentException | IllegalAccessException e) { - return UNDEF; } } - return overallState; + return Converter.toTitleCase(overallState); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java index 98cb7aba38eb8..ee024bd364c14 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java @@ -27,8 +27,7 @@ import com.google.gson.Gson; /** - * The {@link LocaleTest} is responsible for handling commands, which are - * sent to one of the channels. + * The {@link LocaleTest} is testing locale settings * * @author Bernd Weymann - Initial contribution */ From 99b3a159c14cfec55f3a7194e743ce46e090927a Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sun, 17 Jan 2021 01:29:47 +0100 Subject: [PATCH 100/176] implement edit and send of ChargeProfile Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../internal/ConnectedDriveConstants.java | 69 +++- .../internal/dto/charge/ChargeProfile.java | 23 +- .../internal/dto/charge/ChargingWindow.java | 36 +- .../internal/dto/charge/Timer.java | 54 ++- .../internal/dto/charge/WeeklyPlanner.java | 53 ++- .../internal/handler/ConnectedDriveProxy.java | 6 +- .../handler/RemoteServiceHandler.java | 10 +- .../handler/VehicleChannelHandler.java | 118 ++++++- .../internal/handler/VehicleHandler.java | 310 +++++++++++++++++- .../internal/utils/ChargeProfileUtils.java | 43 +++ .../internal/utils/Constants.java | 17 +- .../OH-INF/thing/charge-channel-groups.xml | 33 ++ .../OH-INF/thing/charge-channel-types.xml | 160 +++++++++ 13 files changed, 908 insertions(+), 24 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 9a498b85bec4a..212d0513a2e52 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -22,6 +22,7 @@ * used across the whole binding. * * @author Bernd Weymann - Initial contribution + * @author Norbert Truchsess - contributor */ @NonNullByDefault public class ConnectedDriveConstants { @@ -47,7 +48,7 @@ public enum VehicleType { private final String type; - VehicleType(String s) { + private VehicleType(String s) { type = s; } @@ -57,6 +58,35 @@ public String toString() { } } + public enum Day { + MONDAY, + TUESDAY, + WEDNESDAY, + THURSDAY, + FRIDAY, + SATURDAY, + SUNDAY + } + + public enum ChargingMode { + IMMEDIATE_CHARGING, + DELAYED_CHARGING + } + + public enum ChargingPreference { + CHARGING_WINDOW + } + + public enum ChargeControlVersion { + REMOTE, + EDIT + } + + public enum ChargeControlCommand { + CANCEL, + SEND + } + public static final Set FUEL_VEHICLES = Set.of(VehicleType.CONVENTIONAL.toString(), VehicleType.PLUGIN_HYBRID.toString(), VehicleType.ELECTRIC_REX.toString()); public static final Set ELECTRIC_VEHICLES = Set.of(VehicleType.ELECTRIC.toString(), @@ -126,16 +156,49 @@ public String toString() { public static final String CHARGE_PROFILE_CLIMATE = "profile-climate"; public static final String CHARGE_PROFILE_MODE = "profile-mode"; public static final String CHARGE_WINDOW_START = "window-start"; + public static final String CHARGE_WINDOW_START_HOUR = "window-start-hour"; + public static final String CHARGE_WINDOW_START_MINUTE = "window-start-minute"; public static final String CHARGE_WINDOW_END = "window-end"; + public static final String CHARGE_WINDOW_END_HOUR = "window-end-hour"; + public static final String CHARGE_WINDOW_END_MINUTE = "window-end-minute"; public static final String CHARGE_TIMER1_DEPARTURE = "timer1-departure"; + public static final String CHARGE_TIMER1_DEPARTURE_HOUR = "timer1-departure-hour"; + public static final String CHARGE_TIMER1_DEPARTURE_MINUTE = "timer1-departure-minute"; public static final String CHARGE_TIMER1_DAYS = "timer1-days"; + public static final String CHARGE_TIMER1_DAYS_MON = "timer1-days-monday"; + public static final String CHARGE_TIMER1_DAYS_TUE = "timer1-days-tuesday"; + public static final String CHARGE_TIMER1_DAYS_WED = "timer1-days-wednesday"; + public static final String CHARGE_TIMER1_DAYS_THU = "timer1-days-thursday"; + public static final String CHARGE_TIMER1_DAYS_FRI = "timer1-days-friday"; + public static final String CHARGE_TIMER1_DAYS_SAT = "timer1-days-saturday"; + public static final String CHARGE_TIMER1_DAYS_SUN = "timer1-days-sunday"; public static final String CHARGE_TIMER1_ENABLED = "timer1-enabled"; public static final String CHARGE_TIMER2_DEPARTURE = "timer2-departure"; + public static final String CHARGE_TIMER2_DEPARTURE_HOUR = "timer2-departure-hour"; + public static final String CHARGE_TIMER2_DEPARTURE_MINUTE = "timer2-departure-minute"; public static final String CHARGE_TIMER2_DAYS = "timer2-days"; + public static final String CHARGE_TIMER2_DAYS_MON = "timer2-days-monday"; + public static final String CHARGE_TIMER2_DAYS_TUE = "timer2-days-tuesday"; + public static final String CHARGE_TIMER2_DAYS_WED = "timer2-days-wednesday"; + public static final String CHARGE_TIMER2_DAYS_THU = "timer2-days-thursday"; + public static final String CHARGE_TIMER2_DAYS_FRI = "timer2-days-friday"; + public static final String CHARGE_TIMER2_DAYS_SAT = "timer2-days-saturday"; + public static final String CHARGE_TIMER2_DAYS_SUN = "timer2-days-sunday"; public static final String CHARGE_TIMER2_ENABLED = "timer2-enabled"; public static final String CHARGE_TIMER3_DEPARTURE = "timer3-departure"; - public static final String CHARGE_TIMER3_ENABLED = "timer3-days"; - public static final String CHARGE_TIMER3_DAYS = "timer3-enabled"; + public static final String CHARGE_TIMER3_DEPARTURE_HOUR = "timer3-departure-hour"; + public static final String CHARGE_TIMER3_DEPARTURE_MINUTE = "timer3-departure-minute"; + public static final String CHARGE_TIMER3_DAYS = "timer3-days"; + public static final String CHARGE_TIMER3_DAYS_MON = "timer3-days-monday"; + public static final String CHARGE_TIMER3_DAYS_TUE = "timer3-days-tuesday"; + public static final String CHARGE_TIMER3_DAYS_WED = "timer3-days-wednesday"; + public static final String CHARGE_TIMER3_DAYS_THU = "timer3-days-thursday"; + public static final String CHARGE_TIMER3_DAYS_FRI = "timer3-days-friday"; + public static final String CHARGE_TIMER3_DAYS_SAT = "timer3-days-saturday"; + public static final String CHARGE_TIMER3_DAYS_SUN = "timer3-days-sunday"; + public static final String CHARGE_TIMER3_ENABLED = "timer3-enabled"; + public static final String CHARGE_CONTROL_COMMAND = "command"; + public static final String CHARGE_CONTROL_VERSION = "version"; // Range public static final String RANGE_HYBRID = "hybrid"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargeProfile.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargeProfile.java index 67326b31fbdf7..389ba44b9e320 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargeProfile.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargeProfile.java @@ -16,7 +16,28 @@ * The {@link ChargeProfile} Data Transfer Object * * @author Bernd Weymann - Initial contribution + * @author Norbert Truchsess - contributor */ -public class ChargeProfile { +public class ChargeProfile implements Cloneable { public WeeklyPlanner weeklyPlanner; + + public static ChargeProfile defaultChargeProfile() { + final ChargeProfile cp = new ChargeProfile(); + return cp.completeChargeProfile(); + } + + public ChargeProfile completeChargeProfile() { + if (weeklyPlanner == null) { + weeklyPlanner = new WeeklyPlanner(); + } + weeklyPlanner.completeWeeklyPlanner(); + return this; + } + + @Override + public Object clone() throws CloneNotSupportedException { + final ChargeProfile cp = (ChargeProfile) super.clone(); + cp.weeklyPlanner = (WeeklyPlanner) weeklyPlanner.clone(); + return cp; + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargingWindow.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargingWindow.java index cfa4ad82be67d..1f640c3b8e0bd 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargingWindow.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargingWindow.java @@ -12,12 +12,46 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.dto.charge; +import org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileUtils; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; + /** * The {@link ChargingWindow} Data Transfer Object * * @author Bernd Weymann - Initial contribution + * @author Norbert Truchsess - contributor */ -public class ChargingWindow { +public class ChargingWindow implements Cloneable { public String startTime;// ":"11:00", public String endTime;// ":"17:00"}} + + public void completeChargingWindow() { + if (startTime == null) { + startTime = Constants.NULL_TIME; + } + if (endTime == null) { + endTime = Constants.NULL_TIME; + } + } + + public void setStartMinute(int minute) { + startTime = ChargeProfileUtils.withMinute(startTime, minute); + } + + public void setStartHour(int hour) { + startTime = ChargeProfileUtils.withHour(startTime, hour); + } + + public void setEndMinute(int minute) { + endTime = ChargeProfileUtils.withMinute(endTime, minute); + } + + public void setEndHour(int hour) { + endTime = ChargeProfileUtils.withHour(endTime, hour); + } + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java index 6799e5d96de6e..64912c56ba450 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java @@ -12,16 +12,22 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.dto.charge; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.Day; +import org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileUtils; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; /** * The {@link Timer} Data Transfer Object * * @author Bernd Weymann - Initial contribution + * @author Norbert Truchsess - contributor */ -public class Timer { +public class Timer implements Cloneable { public String departureTime;// ": "05:00", public boolean timerEnabled;// ": false, public List weekdays; @@ -48,4 +54,50 @@ public String getDays() { }); return days.toString(); } + + public void completeTimer() { + if (weekdays == null) { + weekdays = new ArrayList<>(); + } + if (departureTime == null || departureTime.isEmpty()) { + departureTime = Constants.NULL_TIME; + } + } + + public void dayOn(final Day day) { + if (!weekdays.contains(day.name())) { + weekdays.add(day.toString()); + Collections.sort(weekdays, new Comparator<>() { + + @Override + public int compare(String day0, String day1) { + return Day.valueOf(day0).ordinal() - Day.valueOf(day1).ordinal(); + } + }); + } + } + + public void dayOff(final Day day) { + weekdays.remove(day.name()); + } + + public boolean isDayOn(final Day day) { + return weekdays.contains(day.name()); + } + + public void setDepartureMinute(int minute) { + departureTime = ChargeProfileUtils.withMinute(departureTime, minute); + } + + public void setDepartureHour(int hour) { + departureTime = ChargeProfileUtils.withHour(departureTime, hour); + } + + @Override + public Object clone() throws CloneNotSupportedException { + final Timer t = (Timer) super.clone(); + t.weekdays = new ArrayList<>(); + t.weekdays.addAll(weekdays); + return (Object) t; + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/WeeklyPlanner.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/WeeklyPlanner.java index b2f5359451b77..47630a85eba0a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/WeeklyPlanner.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/WeeklyPlanner.java @@ -12,12 +12,16 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.dto.charge; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.ChargingMode; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.ChargingPreference; + /** * The {@link WeeklyPlanner} Data Transfer Object * * @author Bernd Weymann - Initial contribution + * @author Norbert Truchsess - contributor */ -public class WeeklyPlanner { +public class WeeklyPlanner implements Cloneable { public boolean climatizationEnabled; // ": true, public String chargingMode;// ": "IMMEDIATE_CHARGING", public String chargingPreferences; // ": "CHARGING_WINDOW", @@ -26,4 +30,51 @@ public class WeeklyPlanner { public Timer timer3;// ":{"departureTime":"00:00","timerEnabled":false,"weekdays":[]}," public Timer overrideTimer;// ":{"departureTime":"12:00","timerEnabled":false,"weekdays":["SATURDAY"]}," public ChargingWindow preferredChargingWindow;// ":{"startTime":"11:00","endTime":"17:00"}} + + public void completeWeeklyPlanner() { + + if (chargingMode == null) { + chargingMode = ChargingMode.IMMEDIATE_CHARGING.name(); + } + + if (chargingPreferences == null) { + chargingPreferences = ChargingPreference.CHARGING_WINDOW.name(); + } + + if (timer1 == null) { + timer1 = new Timer(); + } + timer1.completeTimer(); + + if (timer2 == null) { + timer2 = new Timer(); + } + timer2.completeTimer(); + + if (timer3 == null) { + timer3 = new Timer(); + } + timer3.completeTimer(); + + if (overrideTimer == null) { + overrideTimer = new Timer(); + } + overrideTimer.completeTimer(); + + if (preferredChargingWindow == null) { + preferredChargingWindow = new ChargingWindow(); + } + preferredChargingWindow.completeChargingWindow(); + } + + @Override + public Object clone() throws CloneNotSupportedException { + final WeeklyPlanner wp = (WeeklyPlanner) super.clone(); + wp.timer1 = (Timer) timer1.clone(); + wp.timer2 = (Timer) timer2.clone(); + wp.timer3 = (Timer) timer3.clone(); + wp.overrideTimer = (Timer) overrideTimer.clone(); + wp.preferredChargingWindow = (ChargingWindow) preferredChargingWindow.clone(); + return (Object) wp; + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index 3e32ebe69ea86..67dfc8b9399a9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -54,6 +54,7 @@ * https://customer.bmwgroup.com/one/app/oauth.js * * @author Bernd Weymann - Initial contribution + * @author Norbert Truchsess - contributor */ @NonNullByDefault public class ConnectedDriveProxy { @@ -121,9 +122,8 @@ private synchronized void call(String url, boolean post, Optional dataMap = new MultiMap(); dataMap.add(SERVICE_TYPE, service.toString()); + if (data.length > 0) { + dataMap.add(DATA, data[0]); + } proxy.post(serviceExecutionAPI, Optional.of(dataMap), this); return true; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index c1a6136d12f4e..87cdd9e73332e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -14,6 +14,7 @@ import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; +import java.time.LocalTime; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -21,6 +22,7 @@ import javax.measure.quantity.Length; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.ChargeControlVersion; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; import org.openhab.binding.bmwconnecteddrive.internal.dto.Destination; import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.ChargeProfile; @@ -35,10 +37,12 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Position; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Windows; +import org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileUtils; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.openhab.binding.bmwconnecteddrive.internal.utils.VehicleStatusUtils; import org.openhab.core.library.types.DateTimeType; +import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.PointType; import org.openhab.core.library.types.QuantityType; @@ -60,6 +64,7 @@ * sent to one of the channels. * * @author Bernd Weymann - Initial contribution + * @author Norbert Truchsess - contributor */ @NonNullByDefault public class VehicleChannelHandler extends BaseThingHandler { @@ -153,16 +158,49 @@ public class VehicleChannelHandler extends BaseThingHandler { protected ChannelUID chargeProfileClimate; protected ChannelUID chargeProfileChargeMode; protected ChannelUID chargeWindowStart; + protected ChannelUID chargeWindowStartHour; + protected ChannelUID chargeWindowStartMinute; protected ChannelUID chargeWindowEnd; + protected ChannelUID chargeWindowEndHour; + protected ChannelUID chargeWindowEndMinute; protected ChannelUID timer1Departure; + protected ChannelUID timer1DepartureHour; + protected ChannelUID timer1DepartureMinute; protected ChannelUID timer1Enabled; protected ChannelUID timer1Days; + protected ChannelUID timer1DaysMon; + protected ChannelUID timer1DaysTue; + protected ChannelUID timer1DaysWed; + protected ChannelUID timer1DaysThu; + protected ChannelUID timer1DaysFri; + protected ChannelUID timer1DaysSat; + protected ChannelUID timer1DaysSun; protected ChannelUID timer2Departure; + protected ChannelUID timer2DepartureHour; + protected ChannelUID timer2DepartureMinute; protected ChannelUID timer2Enabled; protected ChannelUID timer2Days; + protected ChannelUID timer2DaysMon; + protected ChannelUID timer2DaysTue; + protected ChannelUID timer2DaysWed; + protected ChannelUID timer2DaysThu; + protected ChannelUID timer2DaysFri; + protected ChannelUID timer2DaysSat; + protected ChannelUID timer2DaysSun; protected ChannelUID timer3Departure; + protected ChannelUID timer3DepartureHour; + protected ChannelUID timer3DepartureMinute; protected ChannelUID timer3Enabled; protected ChannelUID timer3Days; + protected ChannelUID timer3DaysMon; + protected ChannelUID timer3DaysTue; + protected ChannelUID timer3DaysWed; + protected ChannelUID timer3DaysThu; + protected ChannelUID timer3DaysFri; + protected ChannelUID timer3DaysSat; + protected ChannelUID timer3DaysSun; + protected ChannelUID chargeControl; + protected ChannelUID chargeControlVersion; // Image protected ChannelUID imageChannel; @@ -174,6 +212,9 @@ public class VehicleChannelHandler extends BaseThingHandler { protected Optional lastTripCache = Optional.empty(); protected Optional allTripsCache = Optional.empty(); protected Optional chargeProfileCache = Optional.empty(); + protected Optional chargeProfile = Optional.empty(); + protected Optional chargeProfileEdit = Optional.empty(); + protected Optional chargeProfileError = Optional.empty(); protected Optional rangeMapCache = Optional.empty(); protected Optional destinationCache = Optional.empty(); protected Optional imageCache = Optional.empty(); @@ -256,16 +297,49 @@ public VehicleChannelHandler(Thing thing, BMWConnectedDriveOptionProvider op, St chargeProfileClimate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_PROFILE_CLIMATE); chargeProfileChargeMode = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_PROFILE_MODE); chargeWindowStart = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_WINDOW_START); + chargeWindowStartHour = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_WINDOW_START_HOUR); + chargeWindowStartMinute = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_WINDOW_START_MINUTE); chargeWindowEnd = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_WINDOW_END); + chargeWindowEndHour = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_WINDOW_END_HOUR); + chargeWindowEndMinute = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_WINDOW_END_MINUTE); timer1Departure = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DEPARTURE); + timer1DepartureHour = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DEPARTURE_HOUR); + timer1DepartureMinute = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DEPARTURE_MINUTE); timer1Enabled = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_ENABLED); timer1Days = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DAYS); + timer1DaysMon = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DAYS_MON); + timer1DaysTue = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DAYS_TUE); + timer1DaysWed = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DAYS_WED); + timer1DaysThu = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DAYS_THU); + timer1DaysFri = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DAYS_FRI); + timer1DaysSat = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DAYS_SAT); + timer1DaysSun = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DAYS_SUN); timer2Departure = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DEPARTURE); + timer2DepartureHour = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DEPARTURE_HOUR); + timer2DepartureMinute = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DEPARTURE_MINUTE); timer2Enabled = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_ENABLED); timer2Days = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DAYS); + timer2DaysMon = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DAYS_MON); + timer2DaysTue = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DAYS_TUE); + timer2DaysWed = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DAYS_WED); + timer2DaysThu = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DAYS_THU); + timer2DaysFri = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DAYS_FRI); + timer2DaysSat = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DAYS_SAT); + timer2DaysSun = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DAYS_SUN); timer3Departure = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DEPARTURE); - timer3Enabled = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAYS); - timer3Days = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_ENABLED); + timer3DepartureHour = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DEPARTURE_HOUR); + timer3DepartureMinute = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DEPARTURE_MINUTE); + timer3Enabled = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_ENABLED); + timer3Days = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAYS); + timer3DaysMon = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAYS_MON); + timer3DaysTue = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAYS_TUE); + timer3DaysWed = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAYS_WED); + timer3DaysThu = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAYS_THU); + timer3DaysFri = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAYS_FRI); + timer3DaysSat = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAYS_SAT); + timer3DaysSun = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAYS_SUN); + chargeControl = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_CONTROL_COMMAND); + chargeControlVersion = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_CONTROL_VERSION); remoteCommandChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_COMMAND); remoteStateChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_STATE); @@ -499,23 +573,63 @@ protected void updateChargeProfile(ChargeProfile cp) { updateState(chargeProfileChargeMode, StringType.valueOf(Converter.toTitleCase(planner.chargingMode))); ChargingWindow cw = planner.preferredChargingWindow; + LocalTime startTime = ChargeProfileUtils.parseTime(cw.startTime); updateState(chargeWindowStart, StringType.valueOf(cw.startTime)); + updateState(chargeWindowStartHour, new DecimalType(startTime.getHour())); + updateState(chargeWindowStartMinute, new DecimalType(startTime.getMinute())); + LocalTime endTime = ChargeProfileUtils.parseTime(cw.endTime); updateState(chargeWindowEnd, StringType.valueOf(cw.endTime)); + updateState(chargeWindowEndHour, new DecimalType(endTime.getHour())); + updateState(chargeWindowEndMinute, new DecimalType(endTime.getMinute())); Timer t1 = planner.timer1; + LocalTime departureTime1 = ChargeProfileUtils.parseTime(t1.departureTime); updateState(timer1Departure, StringType.valueOf(t1.departureTime)); + updateState(timer1DepartureHour, new DecimalType(departureTime1.getHour())); + updateState(timer1DepartureMinute, new DecimalType(departureTime1.getMinute())); updateState(timer1Enabled, OnOffType.from(t1.timerEnabled)); updateState(timer1Days, StringType.valueOf(t1.getDays())); + updateState(timer1DaysMon, OnOffType.from(t1.isDayOn(Day.MONDAY))); + updateState(timer1DaysTue, OnOffType.from(t1.isDayOn(Day.TUESDAY))); + updateState(timer1DaysWed, OnOffType.from(t1.isDayOn(Day.WEDNESDAY))); + updateState(timer1DaysThu, OnOffType.from(t1.isDayOn(Day.THURSDAY))); + updateState(timer1DaysFri, OnOffType.from(t1.isDayOn(Day.FRIDAY))); + updateState(timer1DaysSat, OnOffType.from(t1.isDayOn(Day.SATURDAY))); + updateState(timer1DaysSun, OnOffType.from(t1.isDayOn(Day.SUNDAY))); Timer t2 = planner.timer2; + LocalTime departureTime2 = ChargeProfileUtils.parseTime(t2.departureTime); updateState(timer2Departure, StringType.valueOf(t2.departureTime)); + updateState(timer2DepartureHour, new DecimalType(departureTime2.getHour())); + updateState(timer2DepartureMinute, new DecimalType(departureTime2.getMinute())); updateState(timer2Enabled, OnOffType.from(t2.timerEnabled)); updateState(timer2Days, StringType.valueOf(t2.getDays())); + updateState(timer2DaysMon, OnOffType.from(t2.isDayOn(Day.MONDAY))); + updateState(timer2DaysTue, OnOffType.from(t2.isDayOn(Day.TUESDAY))); + updateState(timer2DaysWed, OnOffType.from(t2.isDayOn(Day.WEDNESDAY))); + updateState(timer2DaysThu, OnOffType.from(t2.isDayOn(Day.THURSDAY))); + updateState(timer2DaysFri, OnOffType.from(t2.isDayOn(Day.FRIDAY))); + updateState(timer2DaysSat, OnOffType.from(t2.isDayOn(Day.SATURDAY))); + updateState(timer2DaysSun, OnOffType.from(t2.isDayOn(Day.SUNDAY))); Timer t3 = planner.timer3; + LocalTime departureTime3 = ChargeProfileUtils.parseTime(t2.departureTime); updateState(timer3Departure, StringType.valueOf(t3.departureTime)); + updateState(timer3DepartureHour, new DecimalType(departureTime3.getHour())); + updateState(timer3DepartureMinute, new DecimalType(departureTime3.getMinute())); updateState(timer3Enabled, OnOffType.from(t3.timerEnabled)); updateState(timer3Days, StringType.valueOf(t3.getDays())); + updateState(timer3DaysMon, OnOffType.from(t3.isDayOn(Day.MONDAY))); + updateState(timer3DaysTue, OnOffType.from(t3.isDayOn(Day.TUESDAY))); + updateState(timer3DaysWed, OnOffType.from(t3.isDayOn(Day.WEDNESDAY))); + updateState(timer3DaysThu, OnOffType.from(t3.isDayOn(Day.THURSDAY))); + updateState(timer3DaysFri, OnOffType.from(t3.isDayOn(Day.FRIDAY))); + updateState(timer3DaysSat, OnOffType.from(t3.isDayOn(Day.SATURDAY))); + updateState(timer3DaysSun, OnOffType.from(t3.isDayOn(Day.SUNDAY))); + } + + protected void updateChargeControlVersion(ChargeControlVersion version) { + updateState(chargeControlVersion, StringType.valueOf(version.name())); } protected void updateDoors(Doors doorState) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 5a1b1b39dadf0..012462059b691 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -26,6 +26,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.DestinationContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.ChargeProfile; +import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.WeeklyPlanner; import org.openhab.binding.bmwconnecteddrive.internal.dto.compat.VehicleAttributesContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTrips; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTripsContainer; @@ -33,12 +34,14 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTripContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; +import org.openhab.binding.bmwconnecteddrive.internal.handler.RemoteServiceHandler.ExecutionState; import org.openhab.binding.bmwconnecteddrive.internal.handler.RemoteServiceHandler.RemoteService; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.openhab.binding.bmwconnecteddrive.internal.utils.ImageProperties; import org.openhab.core.io.net.http.HttpUtil; import org.openhab.core.library.types.DecimalType; +import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.RawType; import org.openhab.core.library.types.StringType; import org.openhab.core.thing.Bridge; @@ -55,6 +58,7 @@ * sent to one of the channels. * * @author Bernd Weymann - Initial contribution + * @author Norbert Truchsess - contributor */ @NonNullByDefault public class VehicleHandler extends VehicleChannelHandler { @@ -98,7 +102,15 @@ public void handleCommand(ChannelUID channelUID, Command command) { } else if (CHANNEL_GROUP_STATUS.equals(group)) { vehicleStatusCallback.onResponse(vehicleStatusCache); } else if (CHANNEL_GROUP_CHARGE.equals(group)) { - vehicleStatusCallback.onResponse(chargeProfileCache); + if (chargeProfileEdit.isEmpty()) { + if (!chargeProfile.isEmpty()) { + updateChargeProfile(chargeProfile.get()); + } + updateChargeControlVersion(ChargeControlVersion.REMOTE); + } else { + updateChargeProfile(chargeProfileEdit.get()); + updateChargeControlVersion(ChargeControlVersion.EDIT); + } } else if (CHANNEL_GROUP_VEHICLE_IMAGE.equals(group)) { imageCallback.onResponse(imageCache); } @@ -194,6 +206,280 @@ public void handleCommand(ChannelUID channelUID, Command command) { logger.debug("Cannot select CheckControl index {}", command.toFullString()); } } + } else if (CHANNEL_GROUP_CHARGE.equals(group)) { + + final String id = channelUID.getIdWithoutGroup(); + + if (CHARGE_CONTROL_COMMAND.equals(id) + && ChargeControlCommand.CANCEL.name().equals(command.toFullString())) { + chargeProfileEdit = Optional.empty(); + if (chargeProfile.isPresent()) { + updateChargeProfile(chargeProfile.get()); + updateChargeControlVersion(ChargeControlVersion.REMOTE); + } + } else { + try { + if (chargeProfileEdit.isEmpty()) { + if (chargeProfile.isPresent()) { + chargeProfileEdit = Optional.of((ChargeProfile) chargeProfile.get().clone()); + } else { + chargeProfileEdit = Optional.of(ChargeProfile.defaultChargeProfile()); + } + updateChargeControlVersion(ChargeControlVersion.EDIT); + } + + final WeeklyPlanner wp = chargeProfileEdit.get().weeklyPlanner; + + if (command instanceof StringType) { + final String serviceCommand = ((StringType) command).toFullString(); + switch (id) { + case CHARGE_PROFILE_MODE: + wp.chargingMode = serviceCommand; + break; + case CHARGE_CONTROL_COMMAND: + if (ChargeControlCommand.SEND.name().equals(serviceCommand) && remote.isPresent()) { + remote.get().execute(RemoteService.CHARGING_CONTROL, + Converter.getGson().toJson(chargeProfileEdit.get())); + } + break; + } + } + + if (command instanceof OnOffType) { + switch (id) { + case CHARGE_PROFILE_CLIMATE: + wp.climatizationEnabled = OnOffType.ON.equals(command) ? true : false; + break; + case CHARGE_TIMER1_ENABLED: + wp.timer1.timerEnabled = OnOffType.ON.equals(command) ? true : false; + break; + case CHARGE_TIMER1_DAYS_MON: + if (OnOffType.ON.equals(command)) { + wp.timer1.dayOn(Day.MONDAY); + } else { + wp.timer1.dayOff(Day.MONDAY); + } + updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + break; + case CHARGE_TIMER1_DAYS_TUE: + if (OnOffType.ON.equals(command)) { + wp.timer1.dayOn(Day.TUESDAY); + } else { + wp.timer1.dayOff(Day.TUESDAY); + } + updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + break; + case CHARGE_TIMER1_DAYS_WED: + if (OnOffType.ON.equals(command)) { + wp.timer1.dayOn(Day.WEDNESDAY); + } else { + wp.timer1.dayOff(Day.WEDNESDAY); + } + updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + break; + case CHARGE_TIMER1_DAYS_THU: + if (OnOffType.ON.equals(command)) { + wp.timer1.dayOn(Day.THURSDAY); + } else { + wp.timer1.dayOff(Day.THURSDAY); + } + updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + break; + case CHARGE_TIMER1_DAYS_FRI: + if (OnOffType.ON.equals(command)) { + wp.timer1.dayOn(Day.FRIDAY); + } else { + wp.timer1.dayOff(Day.FRIDAY); + } + updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + break; + case CHARGE_TIMER1_DAYS_SAT: + if (OnOffType.ON.equals(command)) { + wp.timer1.dayOn(Day.SATURDAY); + } else { + wp.timer1.dayOff(Day.SATURDAY); + } + updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + break; + case CHARGE_TIMER1_DAYS_SUN: + if (OnOffType.ON.equals(command)) { + wp.timer1.dayOn(Day.SUNDAY); + } else { + wp.timer1.dayOff(Day.SUNDAY); + } + updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + break; + case CHARGE_TIMER2_ENABLED: + wp.timer2.timerEnabled = OnOffType.ON.equals(command) ? true : false; + break; + case CHARGE_TIMER2_DAYS_MON: + if (OnOffType.ON.equals(command)) { + wp.timer2.dayOn(Day.MONDAY); + } else { + wp.timer2.dayOff(Day.MONDAY); + } + updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + break; + case CHARGE_TIMER2_DAYS_TUE: + if (OnOffType.ON.equals(command)) { + wp.timer2.dayOn(Day.TUESDAY); + } else { + wp.timer2.dayOff(Day.TUESDAY); + } + updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + break; + case CHARGE_TIMER2_DAYS_WED: + if (OnOffType.ON.equals(command)) { + wp.timer2.dayOn(Day.WEDNESDAY); + } else { + wp.timer2.dayOff(Day.WEDNESDAY); + } + updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + break; + case CHARGE_TIMER2_DAYS_THU: + if (OnOffType.ON.equals(command)) { + wp.timer2.dayOn(Day.THURSDAY); + } else { + wp.timer2.dayOff(Day.THURSDAY); + } + updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + break; + case CHARGE_TIMER2_DAYS_FRI: + if (OnOffType.ON.equals(command)) { + wp.timer2.dayOn(Day.FRIDAY); + } else { + wp.timer2.dayOff(Day.FRIDAY); + } + updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + break; + case CHARGE_TIMER2_DAYS_SAT: + if (OnOffType.ON.equals(command)) { + wp.timer2.dayOn(Day.SATURDAY); + } else { + wp.timer2.dayOff(Day.SATURDAY); + } + updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + break; + case CHARGE_TIMER2_DAYS_SUN: + if (OnOffType.ON.equals(command)) { + wp.timer2.dayOn(Day.SUNDAY); + } else { + wp.timer2.dayOff(Day.SUNDAY); + } + updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + break; + case CHARGE_TIMER3_ENABLED: + wp.timer3.timerEnabled = OnOffType.ON.equals(command) ? true : false; + break; + case CHARGE_TIMER3_DAYS_MON: + if (OnOffType.ON.equals(command)) { + wp.timer3.dayOn(Day.MONDAY); + } else { + wp.timer3.dayOff(Day.MONDAY); + } + updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + break; + case CHARGE_TIMER3_DAYS_TUE: + if (OnOffType.ON.equals(command)) { + wp.timer3.dayOn(Day.TUESDAY); + } else { + wp.timer3.dayOff(Day.TUESDAY); + } + updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + break; + case CHARGE_TIMER3_DAYS_WED: + if (OnOffType.ON.equals(command)) { + wp.timer3.dayOn(Day.WEDNESDAY); + } else { + wp.timer3.dayOff(Day.WEDNESDAY); + } + updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + break; + case CHARGE_TIMER3_DAYS_THU: + if (OnOffType.ON.equals(command)) { + wp.timer3.dayOn(Day.THURSDAY); + } else { + wp.timer3.dayOff(Day.THURSDAY); + } + updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + break; + case CHARGE_TIMER3_DAYS_FRI: + if (OnOffType.ON.equals(command)) { + wp.timer3.dayOn(Day.FRIDAY); + } else { + wp.timer3.dayOff(Day.FRIDAY); + } + updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + break; + case CHARGE_TIMER3_DAYS_SAT: + if (OnOffType.ON.equals(command)) { + wp.timer3.dayOn(Day.SATURDAY); + } else { + wp.timer3.dayOff(Day.SATURDAY); + } + updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + break; + case CHARGE_TIMER3_DAYS_SUN: + if (OnOffType.ON.equals(command)) { + wp.timer3.dayOn(Day.SUNDAY); + } else { + wp.timer3.dayOff(Day.SUNDAY); + } + updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + break; + } + } + if (command instanceof DecimalType) { + final int numberCommand = ((DecimalType) command).intValue(); + switch (id) { + case CHARGE_WINDOW_START_HOUR: + wp.preferredChargingWindow.setStartHour(numberCommand); + updateState(chargeWindowStart, + StringType.valueOf(wp.preferredChargingWindow.startTime)); + break; + case CHARGE_WINDOW_START_MINUTE: + wp.preferredChargingWindow.setStartMinute(numberCommand); + updateState(chargeWindowStart, + StringType.valueOf(wp.preferredChargingWindow.startTime)); + break; + case CHARGE_WINDOW_END_HOUR: + wp.preferredChargingWindow.setEndHour(numberCommand); + updateState(chargeWindowEnd, StringType.valueOf(wp.preferredChargingWindow.endTime)); + break; + case CHARGE_WINDOW_END_MINUTE: + wp.preferredChargingWindow.setEndMinute(numberCommand); + updateState(chargeWindowEnd, StringType.valueOf(wp.preferredChargingWindow.endTime)); + break; + case CHARGE_TIMER1_DEPARTURE_HOUR: + wp.timer1.setDepartureHour(numberCommand); + updateState(timer1Departure, StringType.valueOf(wp.timer1.departureTime)); + break; + case CHARGE_TIMER1_DEPARTURE_MINUTE: + wp.timer1.setDepartureMinute(numberCommand); + updateState(timer1Departure, StringType.valueOf(wp.timer1.departureTime)); + break; + case CHARGE_TIMER2_DEPARTURE_HOUR: + wp.timer2.setDepartureHour(numberCommand); + updateState(timer2Departure, StringType.valueOf(wp.timer2.departureTime)); + break; + case CHARGE_TIMER2_DEPARTURE_MINUTE: + wp.timer2.setDepartureMinute(numberCommand); + updateState(timer2Departure, StringType.valueOf(wp.timer2.departureTime)); + break; + case CHARGE_TIMER3_DEPARTURE_HOUR: + wp.timer3.setDepartureHour(numberCommand); + updateState(timer3Departure, StringType.valueOf(wp.timer3.departureTime)); + break; + case CHARGE_TIMER3_DEPARTURE_MINUTE: + wp.timer3.setDepartureMinute(numberCommand); + updateState(timer3Departure, StringType.valueOf(wp.timer3.departureTime)); + break; + } + } + } catch (CloneNotSupportedException e) { + logger.error("ChargeProfile is not Cloneable"); + } + } } } @@ -407,6 +693,16 @@ private boolean isSupported(String service) { } public void updateRemoteExecutionStatus(String service, String status) { + if (service.equals(RemoteService.CHARGING_CONTROL.toString()) + && status.equals(ExecutionState.EXECUTED.toString())) { + if (chargeProfileEdit.isPresent()) { + final ChargeProfile cp = chargeProfileEdit.get(); + chargeProfileCache = Optional.of(Converter.getGson().toJson(cp)); + chargeProfile = Optional.of(cp); + chargeProfileEdit = Optional.empty(); + updateChargeControlVersion(ChargeControlVersion.REMOTE); + } + } updateState(remoteStateChannel, StringType .valueOf(Converter.toTitleCase(new StringBuilder(service).append(" ").append(status).toString()))); } @@ -432,9 +728,16 @@ public void onResponse(Optional content) { chargeProfileCache = content; if (content.isPresent()) { ChargeProfile cp = Converter.getGson().fromJson(content.get(), ChargeProfile.class); - if (cp != null) { - updateChargeProfile(cp); + if (cp == null) { + chargeProfile = Optional.empty(); + } else { + chargeProfile = Optional.of(cp.completeChargeProfile()); + if (!chargeProfileEdit.isPresent()) { + updateChargeProfile(cp); + } } + } else { + chargeProfile = Optional.empty(); } removeCallback(this); } @@ -446,6 +749,7 @@ public void onResponse(Optional content) { public void onError(NetworkError error) { logger.debug("{}", error.toString()); chargeProfileCache = Optional.of(Converter.getGson().toJson(error)); + chargeProfile = Optional.empty(); removeCallback(this); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java new file mode 100644 index 0000000000000..14ae11cb2a7e7 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2010-2020 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.bmwconnecteddrive.internal.utils; + +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link ChargeProfileUtils} class holds static utility methods dealing with + * conversion of String-, LocalTime- and integer hours + minutes format of charge-profile + * timers and time-windows. + * + * @author Norbert Truchsess - Initial contribution + */ +@NonNullByDefault +public class ChargeProfileUtils { + + public static final DateTimeFormatter TIMEFORMATER = DateTimeFormatter.ofPattern("HH:mm"); + + public static String withMinute(String time, int minute) { + return LocalTime.parse(time, TIMEFORMATER).withMinute(minute).format(TIMEFORMATER); + } + + public static String withHour(String time, int hour) { + return LocalTime.parse(time, TIMEFORMATER).withHour(hour).format(TIMEFORMATER); + } + + public static LocalTime parseTime(String time) { + return LocalTime.parse(time, TIMEFORMATER); + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java index 69b91edd35452..ee2f6f02bd382 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -16,12 +16,14 @@ import java.util.Map; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.Day; import org.openhab.core.types.UnDefType; /** * The {@link Constants} General Constant Definitions * * @author Bernd Weymann - Initial contribution + * @author Norbert Truchsess - contributor */ @NonNullByDefault public class Constants { @@ -37,6 +39,7 @@ public class Constants { public static final String UNDEF = UnDefType.UNDEF.toFullString(); public static final String UTC_APPENDIX = "-01T12:00:00"; public static final String NULL_DATE = "1900-01-01T00:00:00"; + public static final String NULL_TIME = "00:00"; public static final int INT_UNDEF = -1; // Services to query @@ -66,13 +69,13 @@ public class Constants { @SuppressWarnings("serial") public static final Map DAYS = new HashMap() { { - put("MONDAY", "Mon"); - put("TUESDAY", "Tue"); - put("WEDNESDAY", "Wed"); - put("THURSDAY", "Thu"); - put("FRIDAY", "Fri"); - put("SATURDAY", "Sat"); - put("SUNDAY", "Sun"); + put(Day.MONDAY.name(), "Mon"); + put(Day.TUESDAY.name(), "Tue"); + put(Day.WEDNESDAY.name(), "Wed"); + put(Day.THURSDAY.name(), "Thu"); + put(Day.FRIDAY.name(), "Fri"); + put(Day.SATURDAY.name(), "Sat"); + put(Day.SUNDAY.name(), "Sun"); } }; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-groups.xml index 837a8004d0544..f6d0f0b81f8b7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-groups.xml @@ -10,16 +10,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml index c8ac18fcc4b3d..39101de72571f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml @@ -10,23 +10,87 @@ String + + + + + + String + + Number + + + + + Number + + + String + + Number + + + + + Number + + + String + + Number + + + + + Number + + + String + + Switch + + + + Switch + + + + Switch + + + + Switch + + + + Switch + + + + Switch + + + + Switch + + Switch @@ -35,10 +99,48 @@ String + + Number + + + + + Number + + + String + + Switch + + + + Switch + + + + Switch + + + + Switch + + + + Switch + + + + Switch + + + + Switch + + Switch @@ -47,12 +149,70 @@ String + + Number + + + + + Number + + + String + + Switch + + + + Switch + + + + Switch + + + + Switch + + + + Switch + + + + Switch + + + + Switch + + Switch + + String + + + + + + + + + + String + + + + + + + + From 54e737a43ceea68cd850f4c94bc67232d906b321 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sun, 17 Jan 2021 11:42:36 +0100 Subject: [PATCH 101/176] adapt ChargeProfileTest to latest changes Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../bmwconnecteddrive/internal/handler/ChargeProfileTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java index 7c27b36e47c79..c659e87e9b543 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java @@ -44,7 +44,7 @@ public class ChargeProfileTest { private final Logger logger = LoggerFactory.getLogger(VehicleHandler.class); - private static final int PROFILE_CALLBACK_NUMBER = 13; + private static final int PROFILE_CALLBACK_NUMBER = 44; @Nullable ArgumentCaptor channelCaptor; From 125d3f6f9587f3deb9c91426fcc6ea1d133654b4 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sun, 17 Jan 2021 18:48:39 +0100 Subject: [PATCH 102/176] update channel state when receiving commands (fixes UI not updating on change of hours/minutes) Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../internal/handler/VehicleHandler.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 012462059b691..67d45cde38643 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -249,9 +249,11 @@ public void handleCommand(ChannelUID channelUID, Command command) { switch (id) { case CHARGE_PROFILE_CLIMATE: wp.climatizationEnabled = OnOffType.ON.equals(command) ? true : false; + updateState(chargeProfileClimate, (OnOffType) command); break; case CHARGE_TIMER1_ENABLED: wp.timer1.timerEnabled = OnOffType.ON.equals(command) ? true : false; + updateState(timer1Enabled, (OnOffType) command); break; case CHARGE_TIMER1_DAYS_MON: if (OnOffType.ON.equals(command)) { @@ -260,6 +262,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer1.dayOff(Day.MONDAY); } updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + updateState(timer1DaysMon, (OnOffType) command); break; case CHARGE_TIMER1_DAYS_TUE: if (OnOffType.ON.equals(command)) { @@ -268,6 +271,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer1.dayOff(Day.TUESDAY); } updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + updateState(timer1DaysTue, (OnOffType) command); break; case CHARGE_TIMER1_DAYS_WED: if (OnOffType.ON.equals(command)) { @@ -276,6 +280,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer1.dayOff(Day.WEDNESDAY); } updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + updateState(timer1DaysWed, (OnOffType) command); break; case CHARGE_TIMER1_DAYS_THU: if (OnOffType.ON.equals(command)) { @@ -284,6 +289,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer1.dayOff(Day.THURSDAY); } updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + updateState(timer1DaysThu, (OnOffType) command); break; case CHARGE_TIMER1_DAYS_FRI: if (OnOffType.ON.equals(command)) { @@ -292,6 +298,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer1.dayOff(Day.FRIDAY); } updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + updateState(timer1DaysFri, (OnOffType) command); break; case CHARGE_TIMER1_DAYS_SAT: if (OnOffType.ON.equals(command)) { @@ -300,6 +307,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer1.dayOff(Day.SATURDAY); } updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + updateState(timer1DaysSat, (OnOffType) command); break; case CHARGE_TIMER1_DAYS_SUN: if (OnOffType.ON.equals(command)) { @@ -308,9 +316,11 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer1.dayOff(Day.SUNDAY); } updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + updateState(timer1DaysSun, (OnOffType) command); break; case CHARGE_TIMER2_ENABLED: wp.timer2.timerEnabled = OnOffType.ON.equals(command) ? true : false; + updateState(timer2Enabled, (OnOffType) command); break; case CHARGE_TIMER2_DAYS_MON: if (OnOffType.ON.equals(command)) { @@ -319,6 +329,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer2.dayOff(Day.MONDAY); } updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + updateState(timer2DaysMon, (OnOffType) command); break; case CHARGE_TIMER2_DAYS_TUE: if (OnOffType.ON.equals(command)) { @@ -327,6 +338,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer2.dayOff(Day.TUESDAY); } updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + updateState(timer2DaysTue, (OnOffType) command); break; case CHARGE_TIMER2_DAYS_WED: if (OnOffType.ON.equals(command)) { @@ -335,6 +347,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer2.dayOff(Day.WEDNESDAY); } updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + updateState(timer2DaysWed, (OnOffType) command); break; case CHARGE_TIMER2_DAYS_THU: if (OnOffType.ON.equals(command)) { @@ -343,6 +356,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer2.dayOff(Day.THURSDAY); } updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + updateState(timer2DaysThu, (OnOffType) command); break; case CHARGE_TIMER2_DAYS_FRI: if (OnOffType.ON.equals(command)) { @@ -351,6 +365,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer2.dayOff(Day.FRIDAY); } updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + updateState(timer2DaysFri, (OnOffType) command); break; case CHARGE_TIMER2_DAYS_SAT: if (OnOffType.ON.equals(command)) { @@ -359,6 +374,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer2.dayOff(Day.SATURDAY); } updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + updateState(timer2DaysSat, (OnOffType) command); break; case CHARGE_TIMER2_DAYS_SUN: if (OnOffType.ON.equals(command)) { @@ -367,6 +383,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer2.dayOff(Day.SUNDAY); } updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + updateState(timer2DaysSun, (OnOffType) command); break; case CHARGE_TIMER3_ENABLED: wp.timer3.timerEnabled = OnOffType.ON.equals(command) ? true : false; @@ -378,6 +395,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer3.dayOff(Day.MONDAY); } updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + updateState(timer3DaysMon, (OnOffType) command); break; case CHARGE_TIMER3_DAYS_TUE: if (OnOffType.ON.equals(command)) { @@ -386,6 +404,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer3.dayOff(Day.TUESDAY); } updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + updateState(timer3DaysTue, (OnOffType) command); break; case CHARGE_TIMER3_DAYS_WED: if (OnOffType.ON.equals(command)) { @@ -394,6 +413,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer3.dayOff(Day.WEDNESDAY); } updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + updateState(timer3DaysWed, (OnOffType) command); break; case CHARGE_TIMER3_DAYS_THU: if (OnOffType.ON.equals(command)) { @@ -402,6 +422,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer3.dayOff(Day.THURSDAY); } updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + updateState(timer3DaysThu, (OnOffType) command); break; case CHARGE_TIMER3_DAYS_FRI: if (OnOffType.ON.equals(command)) { @@ -410,6 +431,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer3.dayOff(Day.FRIDAY); } updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + updateState(timer3DaysFri, (OnOffType) command); break; case CHARGE_TIMER3_DAYS_SAT: if (OnOffType.ON.equals(command)) { @@ -418,6 +440,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer3.dayOff(Day.SATURDAY); } updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + updateState(timer3DaysSat, (OnOffType) command); break; case CHARGE_TIMER3_DAYS_SUN: if (OnOffType.ON.equals(command)) { @@ -426,6 +449,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer3.dayOff(Day.SUNDAY); } updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + updateState(timer3DaysSun, (OnOffType) command); break; } } @@ -436,43 +460,53 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.preferredChargingWindow.setStartHour(numberCommand); updateState(chargeWindowStart, StringType.valueOf(wp.preferredChargingWindow.startTime)); + updateState(chargeWindowStartHour, (DecimalType) command); break; case CHARGE_WINDOW_START_MINUTE: wp.preferredChargingWindow.setStartMinute(numberCommand); updateState(chargeWindowStart, StringType.valueOf(wp.preferredChargingWindow.startTime)); + updateState(chargeWindowStartMinute, (DecimalType) command); break; case CHARGE_WINDOW_END_HOUR: wp.preferredChargingWindow.setEndHour(numberCommand); updateState(chargeWindowEnd, StringType.valueOf(wp.preferredChargingWindow.endTime)); + updateState(chargeWindowEndHour, (DecimalType) command); break; case CHARGE_WINDOW_END_MINUTE: wp.preferredChargingWindow.setEndMinute(numberCommand); updateState(chargeWindowEnd, StringType.valueOf(wp.preferredChargingWindow.endTime)); + updateState(chargeWindowEndMinute, (DecimalType) command); break; case CHARGE_TIMER1_DEPARTURE_HOUR: wp.timer1.setDepartureHour(numberCommand); updateState(timer1Departure, StringType.valueOf(wp.timer1.departureTime)); + updateState(timer1DepartureHour, (DecimalType) command); break; case CHARGE_TIMER1_DEPARTURE_MINUTE: wp.timer1.setDepartureMinute(numberCommand); updateState(timer1Departure, StringType.valueOf(wp.timer1.departureTime)); + updateState(timer1DepartureMinute, (DecimalType) command); break; case CHARGE_TIMER2_DEPARTURE_HOUR: wp.timer2.setDepartureHour(numberCommand); updateState(timer2Departure, StringType.valueOf(wp.timer2.departureTime)); + updateState(timer2DepartureHour, (DecimalType) command); break; case CHARGE_TIMER2_DEPARTURE_MINUTE: wp.timer2.setDepartureMinute(numberCommand); updateState(timer2Departure, StringType.valueOf(wp.timer2.departureTime)); + updateState(timer2DepartureMinute, (DecimalType) command); break; case CHARGE_TIMER3_DEPARTURE_HOUR: wp.timer3.setDepartureHour(numberCommand); updateState(timer3Departure, StringType.valueOf(wp.timer3.departureTime)); + updateState(timer3DepartureHour, (DecimalType) command); break; case CHARGE_TIMER3_DEPARTURE_MINUTE: wp.timer3.setDepartureMinute(numberCommand); updateState(timer3Departure, StringType.valueOf(wp.timer3.departureTime)); + updateState(timer3DepartureMinute, (DecimalType) command); break; } } From b30a9a0a9bdda6fc3990582f412d83156fb49801 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sun, 17 Jan 2021 20:38:57 +0100 Subject: [PATCH 103/176] add pattern to channel-type states, revert last change Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../internal/handler/VehicleHandler.java | 34 ------------------- .../OH-INF/thing/charge-channel-types.xml | 20 +++++------ 2 files changed, 10 insertions(+), 44 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 67d45cde38643..012462059b691 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -249,11 +249,9 @@ public void handleCommand(ChannelUID channelUID, Command command) { switch (id) { case CHARGE_PROFILE_CLIMATE: wp.climatizationEnabled = OnOffType.ON.equals(command) ? true : false; - updateState(chargeProfileClimate, (OnOffType) command); break; case CHARGE_TIMER1_ENABLED: wp.timer1.timerEnabled = OnOffType.ON.equals(command) ? true : false; - updateState(timer1Enabled, (OnOffType) command); break; case CHARGE_TIMER1_DAYS_MON: if (OnOffType.ON.equals(command)) { @@ -262,7 +260,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer1.dayOff(Day.MONDAY); } updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); - updateState(timer1DaysMon, (OnOffType) command); break; case CHARGE_TIMER1_DAYS_TUE: if (OnOffType.ON.equals(command)) { @@ -271,7 +268,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer1.dayOff(Day.TUESDAY); } updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); - updateState(timer1DaysTue, (OnOffType) command); break; case CHARGE_TIMER1_DAYS_WED: if (OnOffType.ON.equals(command)) { @@ -280,7 +276,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer1.dayOff(Day.WEDNESDAY); } updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); - updateState(timer1DaysWed, (OnOffType) command); break; case CHARGE_TIMER1_DAYS_THU: if (OnOffType.ON.equals(command)) { @@ -289,7 +284,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer1.dayOff(Day.THURSDAY); } updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); - updateState(timer1DaysThu, (OnOffType) command); break; case CHARGE_TIMER1_DAYS_FRI: if (OnOffType.ON.equals(command)) { @@ -298,7 +292,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer1.dayOff(Day.FRIDAY); } updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); - updateState(timer1DaysFri, (OnOffType) command); break; case CHARGE_TIMER1_DAYS_SAT: if (OnOffType.ON.equals(command)) { @@ -307,7 +300,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer1.dayOff(Day.SATURDAY); } updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); - updateState(timer1DaysSat, (OnOffType) command); break; case CHARGE_TIMER1_DAYS_SUN: if (OnOffType.ON.equals(command)) { @@ -316,11 +308,9 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer1.dayOff(Day.SUNDAY); } updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); - updateState(timer1DaysSun, (OnOffType) command); break; case CHARGE_TIMER2_ENABLED: wp.timer2.timerEnabled = OnOffType.ON.equals(command) ? true : false; - updateState(timer2Enabled, (OnOffType) command); break; case CHARGE_TIMER2_DAYS_MON: if (OnOffType.ON.equals(command)) { @@ -329,7 +319,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer2.dayOff(Day.MONDAY); } updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); - updateState(timer2DaysMon, (OnOffType) command); break; case CHARGE_TIMER2_DAYS_TUE: if (OnOffType.ON.equals(command)) { @@ -338,7 +327,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer2.dayOff(Day.TUESDAY); } updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); - updateState(timer2DaysTue, (OnOffType) command); break; case CHARGE_TIMER2_DAYS_WED: if (OnOffType.ON.equals(command)) { @@ -347,7 +335,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer2.dayOff(Day.WEDNESDAY); } updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); - updateState(timer2DaysWed, (OnOffType) command); break; case CHARGE_TIMER2_DAYS_THU: if (OnOffType.ON.equals(command)) { @@ -356,7 +343,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer2.dayOff(Day.THURSDAY); } updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); - updateState(timer2DaysThu, (OnOffType) command); break; case CHARGE_TIMER2_DAYS_FRI: if (OnOffType.ON.equals(command)) { @@ -365,7 +351,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer2.dayOff(Day.FRIDAY); } updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); - updateState(timer2DaysFri, (OnOffType) command); break; case CHARGE_TIMER2_DAYS_SAT: if (OnOffType.ON.equals(command)) { @@ -374,7 +359,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer2.dayOff(Day.SATURDAY); } updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); - updateState(timer2DaysSat, (OnOffType) command); break; case CHARGE_TIMER2_DAYS_SUN: if (OnOffType.ON.equals(command)) { @@ -383,7 +367,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer2.dayOff(Day.SUNDAY); } updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); - updateState(timer2DaysSun, (OnOffType) command); break; case CHARGE_TIMER3_ENABLED: wp.timer3.timerEnabled = OnOffType.ON.equals(command) ? true : false; @@ -395,7 +378,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer3.dayOff(Day.MONDAY); } updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); - updateState(timer3DaysMon, (OnOffType) command); break; case CHARGE_TIMER3_DAYS_TUE: if (OnOffType.ON.equals(command)) { @@ -404,7 +386,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer3.dayOff(Day.TUESDAY); } updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); - updateState(timer3DaysTue, (OnOffType) command); break; case CHARGE_TIMER3_DAYS_WED: if (OnOffType.ON.equals(command)) { @@ -413,7 +394,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer3.dayOff(Day.WEDNESDAY); } updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); - updateState(timer3DaysWed, (OnOffType) command); break; case CHARGE_TIMER3_DAYS_THU: if (OnOffType.ON.equals(command)) { @@ -422,7 +402,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer3.dayOff(Day.THURSDAY); } updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); - updateState(timer3DaysThu, (OnOffType) command); break; case CHARGE_TIMER3_DAYS_FRI: if (OnOffType.ON.equals(command)) { @@ -431,7 +410,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer3.dayOff(Day.FRIDAY); } updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); - updateState(timer3DaysFri, (OnOffType) command); break; case CHARGE_TIMER3_DAYS_SAT: if (OnOffType.ON.equals(command)) { @@ -440,7 +418,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer3.dayOff(Day.SATURDAY); } updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); - updateState(timer3DaysSat, (OnOffType) command); break; case CHARGE_TIMER3_DAYS_SUN: if (OnOffType.ON.equals(command)) { @@ -449,7 +426,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.timer3.dayOff(Day.SUNDAY); } updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); - updateState(timer3DaysSun, (OnOffType) command); break; } } @@ -460,53 +436,43 @@ public void handleCommand(ChannelUID channelUID, Command command) { wp.preferredChargingWindow.setStartHour(numberCommand); updateState(chargeWindowStart, StringType.valueOf(wp.preferredChargingWindow.startTime)); - updateState(chargeWindowStartHour, (DecimalType) command); break; case CHARGE_WINDOW_START_MINUTE: wp.preferredChargingWindow.setStartMinute(numberCommand); updateState(chargeWindowStart, StringType.valueOf(wp.preferredChargingWindow.startTime)); - updateState(chargeWindowStartMinute, (DecimalType) command); break; case CHARGE_WINDOW_END_HOUR: wp.preferredChargingWindow.setEndHour(numberCommand); updateState(chargeWindowEnd, StringType.valueOf(wp.preferredChargingWindow.endTime)); - updateState(chargeWindowEndHour, (DecimalType) command); break; case CHARGE_WINDOW_END_MINUTE: wp.preferredChargingWindow.setEndMinute(numberCommand); updateState(chargeWindowEnd, StringType.valueOf(wp.preferredChargingWindow.endTime)); - updateState(chargeWindowEndMinute, (DecimalType) command); break; case CHARGE_TIMER1_DEPARTURE_HOUR: wp.timer1.setDepartureHour(numberCommand); updateState(timer1Departure, StringType.valueOf(wp.timer1.departureTime)); - updateState(timer1DepartureHour, (DecimalType) command); break; case CHARGE_TIMER1_DEPARTURE_MINUTE: wp.timer1.setDepartureMinute(numberCommand); updateState(timer1Departure, StringType.valueOf(wp.timer1.departureTime)); - updateState(timer1DepartureMinute, (DecimalType) command); break; case CHARGE_TIMER2_DEPARTURE_HOUR: wp.timer2.setDepartureHour(numberCommand); updateState(timer2Departure, StringType.valueOf(wp.timer2.departureTime)); - updateState(timer2DepartureHour, (DecimalType) command); break; case CHARGE_TIMER2_DEPARTURE_MINUTE: wp.timer2.setDepartureMinute(numberCommand); updateState(timer2Departure, StringType.valueOf(wp.timer2.departureTime)); - updateState(timer2DepartureMinute, (DecimalType) command); break; case CHARGE_TIMER3_DEPARTURE_HOUR: wp.timer3.setDepartureHour(numberCommand); updateState(timer3Departure, StringType.valueOf(wp.timer3.departureTime)); - updateState(timer3DepartureHour, (DecimalType) command); break; case CHARGE_TIMER3_DEPARTURE_MINUTE: wp.timer3.setDepartureMinute(numberCommand); updateState(timer3Departure, StringType.valueOf(wp.timer3.departureTime)); - updateState(timer3DepartureMinute, (DecimalType) command); break; } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml index 39101de72571f..f720d2548ae48 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml @@ -24,12 +24,12 @@ Number - + Number - + String @@ -38,12 +38,12 @@ Number - + Number - + String @@ -52,12 +52,12 @@ Number - + Number - + String @@ -102,12 +102,12 @@ Number - + Number - + String @@ -152,12 +152,12 @@ Number - + Number - + String From 4eef45af3775b674fde0cad7b3592fd7c837f712 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Mon, 18 Jan 2021 23:35:18 +0100 Subject: [PATCH 104/176] refactoring charge-profile-handling into separate method Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../internal/ConnectedDriveConstants.java | 6 +- .../internal/dto/charge/ChargeProfile.java | 9 +- .../internal/dto/charge/ChargingWindow.java | 7 +- .../internal/dto/charge/Timer.java | 10 +- .../internal/dto/charge/WeeklyPlanner.java | 13 +- .../handler/VehicleChannelHandler.java | 8 +- .../internal/handler/VehicleHandler.java | 598 +++++++++--------- 7 files changed, 315 insertions(+), 336 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 212d0513a2e52..a8b734fcafc5d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -82,10 +82,8 @@ public enum ChargeControlVersion { EDIT } - public enum ChargeControlCommand { - CANCEL, - SEND - } + public static final String CHARGE_CONTROL_CANCEL = "CANCEL"; + public static final String CHARGE_CONTROL_SEND = "SEND"; public static final Set FUEL_VEHICLES = Set.of(VehicleType.CONVENTIONAL.toString(), VehicleType.PLUGIN_HYBRID.toString(), VehicleType.ELECTRIC_REX.toString()); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargeProfile.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargeProfile.java index 389ba44b9e320..6f1195334f6b2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargeProfile.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargeProfile.java @@ -18,7 +18,7 @@ * @author Bernd Weymann - Initial contribution * @author Norbert Truchsess - contributor */ -public class ChargeProfile implements Cloneable { +public class ChargeProfile { public WeeklyPlanner weeklyPlanner; public static ChargeProfile defaultChargeProfile() { @@ -33,11 +33,4 @@ public ChargeProfile completeChargeProfile() { weeklyPlanner.completeWeeklyPlanner(); return this; } - - @Override - public Object clone() throws CloneNotSupportedException { - final ChargeProfile cp = (ChargeProfile) super.clone(); - cp.weeklyPlanner = (WeeklyPlanner) weeklyPlanner.clone(); - return cp; - } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargingWindow.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargingWindow.java index 1f640c3b8e0bd..950ea72c7934a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargingWindow.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargingWindow.java @@ -21,7 +21,7 @@ * @author Bernd Weymann - Initial contribution * @author Norbert Truchsess - contributor */ -public class ChargingWindow implements Cloneable { +public class ChargingWindow { public String startTime;// ":"11:00", public String endTime;// ":"17:00"}} @@ -49,9 +49,4 @@ public void setEndMinute(int minute) { public void setEndHour(int hour) { endTime = ChargeProfileUtils.withHour(endTime, hour); } - - @Override - public Object clone() throws CloneNotSupportedException { - return super.clone(); - } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java index 64912c56ba450..306cbbb6fd880 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java @@ -27,7 +27,7 @@ * @author Bernd Weymann - Initial contribution * @author Norbert Truchsess - contributor */ -public class Timer implements Cloneable { +public class Timer { public String departureTime;// ": "05:00", public boolean timerEnabled;// ": false, public List weekdays; @@ -92,12 +92,4 @@ public void setDepartureMinute(int minute) { public void setDepartureHour(int hour) { departureTime = ChargeProfileUtils.withHour(departureTime, hour); } - - @Override - public Object clone() throws CloneNotSupportedException { - final Timer t = (Timer) super.clone(); - t.weekdays = new ArrayList<>(); - t.weekdays.addAll(weekdays); - return (Object) t; - } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/WeeklyPlanner.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/WeeklyPlanner.java index 47630a85eba0a..15544d3819570 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/WeeklyPlanner.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/WeeklyPlanner.java @@ -21,7 +21,7 @@ * @author Bernd Weymann - Initial contribution * @author Norbert Truchsess - contributor */ -public class WeeklyPlanner implements Cloneable { +public class WeeklyPlanner { public boolean climatizationEnabled; // ": true, public String chargingMode;// ": "IMMEDIATE_CHARGING", public String chargingPreferences; // ": "CHARGING_WINDOW", @@ -66,15 +66,4 @@ public void completeWeeklyPlanner() { } preferredChargingWindow.completeChargingWindow(); } - - @Override - public Object clone() throws CloneNotSupportedException { - final WeeklyPlanner wp = (WeeklyPlanner) super.clone(); - wp.timer1 = (Timer) timer1.clone(); - wp.timer2 = (Timer) timer2.clone(); - wp.timer3 = (Timer) timer3.clone(); - wp.overrideTimer = (Timer) overrideTimer.clone(); - wp.preferredChargingWindow = (ChargingWindow) preferredChargingWindow.clone(); - return (Object) wp; - } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 87cdd9e73332e..35eb623085ac4 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -212,9 +212,6 @@ public class VehicleChannelHandler extends BaseThingHandler { protected Optional lastTripCache = Optional.empty(); protected Optional allTripsCache = Optional.empty(); protected Optional chargeProfileCache = Optional.empty(); - protected Optional chargeProfile = Optional.empty(); - protected Optional chargeProfileEdit = Optional.empty(); - protected Optional chargeProfileError = Optional.empty(); protected Optional rangeMapCache = Optional.empty(); protected Optional destinationCache = Optional.empty(); protected Optional imageCache = Optional.empty(); @@ -629,6 +626,11 @@ protected void updateChargeProfile(ChargeProfile cp) { } protected void updateChargeControlVersion(ChargeControlVersion version) { + if (ChargeControlVersion.EDIT.equals(version)) { + updateState(chargeControl, StringType.valueOf(CHARGE_CONTROL_SEND)); + } else { + updateState(chargeControl, StringType.valueOf(CHARGE_CONTROL_CANCEL)); + } updateState(chargeControlVersion, StringType.valueOf(version.name())); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 012462059b691..65debc7e80975 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -81,6 +81,8 @@ public class VehicleHandler extends VehicleChannelHandler { DestinationsCallback destinationCallback = new DestinationsCallback(); ByteResponseCallback imageCallback = new ImageCallback(); + private Optional chargeProfileEdit = Optional.empty(); + public VehicleHandler(Thing thing, BMWConnectedDriveOptionProvider op, String type, boolean imperial) { super(thing, op, type, imperial); } @@ -103,9 +105,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { vehicleStatusCallback.onResponse(vehicleStatusCache); } else if (CHANNEL_GROUP_CHARGE.equals(group)) { if (chargeProfileEdit.isEmpty()) { - if (!chargeProfile.isEmpty()) { - updateChargeProfile(chargeProfile.get()); - } + chargeProfileCallback.onResponse(chargeProfileCache); updateChargeControlVersion(ChargeControlVersion.REMOTE); } else { updateChargeProfile(chargeProfileEdit.get()); @@ -207,279 +207,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { } } } else if (CHANNEL_GROUP_CHARGE.equals(group)) { - - final String id = channelUID.getIdWithoutGroup(); - - if (CHARGE_CONTROL_COMMAND.equals(id) - && ChargeControlCommand.CANCEL.name().equals(command.toFullString())) { - chargeProfileEdit = Optional.empty(); - if (chargeProfile.isPresent()) { - updateChargeProfile(chargeProfile.get()); - updateChargeControlVersion(ChargeControlVersion.REMOTE); - } - } else { - try { - if (chargeProfileEdit.isEmpty()) { - if (chargeProfile.isPresent()) { - chargeProfileEdit = Optional.of((ChargeProfile) chargeProfile.get().clone()); - } else { - chargeProfileEdit = Optional.of(ChargeProfile.defaultChargeProfile()); - } - updateChargeControlVersion(ChargeControlVersion.EDIT); - } - - final WeeklyPlanner wp = chargeProfileEdit.get().weeklyPlanner; - - if (command instanceof StringType) { - final String serviceCommand = ((StringType) command).toFullString(); - switch (id) { - case CHARGE_PROFILE_MODE: - wp.chargingMode = serviceCommand; - break; - case CHARGE_CONTROL_COMMAND: - if (ChargeControlCommand.SEND.name().equals(serviceCommand) && remote.isPresent()) { - remote.get().execute(RemoteService.CHARGING_CONTROL, - Converter.getGson().toJson(chargeProfileEdit.get())); - } - break; - } - } - - if (command instanceof OnOffType) { - switch (id) { - case CHARGE_PROFILE_CLIMATE: - wp.climatizationEnabled = OnOffType.ON.equals(command) ? true : false; - break; - case CHARGE_TIMER1_ENABLED: - wp.timer1.timerEnabled = OnOffType.ON.equals(command) ? true : false; - break; - case CHARGE_TIMER1_DAYS_MON: - if (OnOffType.ON.equals(command)) { - wp.timer1.dayOn(Day.MONDAY); - } else { - wp.timer1.dayOff(Day.MONDAY); - } - updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); - break; - case CHARGE_TIMER1_DAYS_TUE: - if (OnOffType.ON.equals(command)) { - wp.timer1.dayOn(Day.TUESDAY); - } else { - wp.timer1.dayOff(Day.TUESDAY); - } - updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); - break; - case CHARGE_TIMER1_DAYS_WED: - if (OnOffType.ON.equals(command)) { - wp.timer1.dayOn(Day.WEDNESDAY); - } else { - wp.timer1.dayOff(Day.WEDNESDAY); - } - updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); - break; - case CHARGE_TIMER1_DAYS_THU: - if (OnOffType.ON.equals(command)) { - wp.timer1.dayOn(Day.THURSDAY); - } else { - wp.timer1.dayOff(Day.THURSDAY); - } - updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); - break; - case CHARGE_TIMER1_DAYS_FRI: - if (OnOffType.ON.equals(command)) { - wp.timer1.dayOn(Day.FRIDAY); - } else { - wp.timer1.dayOff(Day.FRIDAY); - } - updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); - break; - case CHARGE_TIMER1_DAYS_SAT: - if (OnOffType.ON.equals(command)) { - wp.timer1.dayOn(Day.SATURDAY); - } else { - wp.timer1.dayOff(Day.SATURDAY); - } - updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); - break; - case CHARGE_TIMER1_DAYS_SUN: - if (OnOffType.ON.equals(command)) { - wp.timer1.dayOn(Day.SUNDAY); - } else { - wp.timer1.dayOff(Day.SUNDAY); - } - updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); - break; - case CHARGE_TIMER2_ENABLED: - wp.timer2.timerEnabled = OnOffType.ON.equals(command) ? true : false; - break; - case CHARGE_TIMER2_DAYS_MON: - if (OnOffType.ON.equals(command)) { - wp.timer2.dayOn(Day.MONDAY); - } else { - wp.timer2.dayOff(Day.MONDAY); - } - updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); - break; - case CHARGE_TIMER2_DAYS_TUE: - if (OnOffType.ON.equals(command)) { - wp.timer2.dayOn(Day.TUESDAY); - } else { - wp.timer2.dayOff(Day.TUESDAY); - } - updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); - break; - case CHARGE_TIMER2_DAYS_WED: - if (OnOffType.ON.equals(command)) { - wp.timer2.dayOn(Day.WEDNESDAY); - } else { - wp.timer2.dayOff(Day.WEDNESDAY); - } - updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); - break; - case CHARGE_TIMER2_DAYS_THU: - if (OnOffType.ON.equals(command)) { - wp.timer2.dayOn(Day.THURSDAY); - } else { - wp.timer2.dayOff(Day.THURSDAY); - } - updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); - break; - case CHARGE_TIMER2_DAYS_FRI: - if (OnOffType.ON.equals(command)) { - wp.timer2.dayOn(Day.FRIDAY); - } else { - wp.timer2.dayOff(Day.FRIDAY); - } - updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); - break; - case CHARGE_TIMER2_DAYS_SAT: - if (OnOffType.ON.equals(command)) { - wp.timer2.dayOn(Day.SATURDAY); - } else { - wp.timer2.dayOff(Day.SATURDAY); - } - updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); - break; - case CHARGE_TIMER2_DAYS_SUN: - if (OnOffType.ON.equals(command)) { - wp.timer2.dayOn(Day.SUNDAY); - } else { - wp.timer2.dayOff(Day.SUNDAY); - } - updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); - break; - case CHARGE_TIMER3_ENABLED: - wp.timer3.timerEnabled = OnOffType.ON.equals(command) ? true : false; - break; - case CHARGE_TIMER3_DAYS_MON: - if (OnOffType.ON.equals(command)) { - wp.timer3.dayOn(Day.MONDAY); - } else { - wp.timer3.dayOff(Day.MONDAY); - } - updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); - break; - case CHARGE_TIMER3_DAYS_TUE: - if (OnOffType.ON.equals(command)) { - wp.timer3.dayOn(Day.TUESDAY); - } else { - wp.timer3.dayOff(Day.TUESDAY); - } - updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); - break; - case CHARGE_TIMER3_DAYS_WED: - if (OnOffType.ON.equals(command)) { - wp.timer3.dayOn(Day.WEDNESDAY); - } else { - wp.timer3.dayOff(Day.WEDNESDAY); - } - updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); - break; - case CHARGE_TIMER3_DAYS_THU: - if (OnOffType.ON.equals(command)) { - wp.timer3.dayOn(Day.THURSDAY); - } else { - wp.timer3.dayOff(Day.THURSDAY); - } - updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); - break; - case CHARGE_TIMER3_DAYS_FRI: - if (OnOffType.ON.equals(command)) { - wp.timer3.dayOn(Day.FRIDAY); - } else { - wp.timer3.dayOff(Day.FRIDAY); - } - updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); - break; - case CHARGE_TIMER3_DAYS_SAT: - if (OnOffType.ON.equals(command)) { - wp.timer3.dayOn(Day.SATURDAY); - } else { - wp.timer3.dayOff(Day.SATURDAY); - } - updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); - break; - case CHARGE_TIMER3_DAYS_SUN: - if (OnOffType.ON.equals(command)) { - wp.timer3.dayOn(Day.SUNDAY); - } else { - wp.timer3.dayOff(Day.SUNDAY); - } - updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); - break; - } - } - if (command instanceof DecimalType) { - final int numberCommand = ((DecimalType) command).intValue(); - switch (id) { - case CHARGE_WINDOW_START_HOUR: - wp.preferredChargingWindow.setStartHour(numberCommand); - updateState(chargeWindowStart, - StringType.valueOf(wp.preferredChargingWindow.startTime)); - break; - case CHARGE_WINDOW_START_MINUTE: - wp.preferredChargingWindow.setStartMinute(numberCommand); - updateState(chargeWindowStart, - StringType.valueOf(wp.preferredChargingWindow.startTime)); - break; - case CHARGE_WINDOW_END_HOUR: - wp.preferredChargingWindow.setEndHour(numberCommand); - updateState(chargeWindowEnd, StringType.valueOf(wp.preferredChargingWindow.endTime)); - break; - case CHARGE_WINDOW_END_MINUTE: - wp.preferredChargingWindow.setEndMinute(numberCommand); - updateState(chargeWindowEnd, StringType.valueOf(wp.preferredChargingWindow.endTime)); - break; - case CHARGE_TIMER1_DEPARTURE_HOUR: - wp.timer1.setDepartureHour(numberCommand); - updateState(timer1Departure, StringType.valueOf(wp.timer1.departureTime)); - break; - case CHARGE_TIMER1_DEPARTURE_MINUTE: - wp.timer1.setDepartureMinute(numberCommand); - updateState(timer1Departure, StringType.valueOf(wp.timer1.departureTime)); - break; - case CHARGE_TIMER2_DEPARTURE_HOUR: - wp.timer2.setDepartureHour(numberCommand); - updateState(timer2Departure, StringType.valueOf(wp.timer2.departureTime)); - break; - case CHARGE_TIMER2_DEPARTURE_MINUTE: - wp.timer2.setDepartureMinute(numberCommand); - updateState(timer2Departure, StringType.valueOf(wp.timer2.departureTime)); - break; - case CHARGE_TIMER3_DEPARTURE_HOUR: - wp.timer3.setDepartureHour(numberCommand); - updateState(timer3Departure, StringType.valueOf(wp.timer3.departureTime)); - break; - case CHARGE_TIMER3_DEPARTURE_MINUTE: - wp.timer3.setDepartureMinute(numberCommand); - updateState(timer3Departure, StringType.valueOf(wp.timer3.departureTime)); - break; - } - } - } catch (CloneNotSupportedException e) { - logger.error("ChargeProfile is not Cloneable"); - } - } + handleChargeProfileCommand(channelUID, command); } } @@ -695,13 +423,7 @@ private boolean isSupported(String service) { public void updateRemoteExecutionStatus(String service, String status) { if (service.equals(RemoteService.CHARGING_CONTROL.toString()) && status.equals(ExecutionState.EXECUTED.toString())) { - if (chargeProfileEdit.isPresent()) { - final ChargeProfile cp = chargeProfileEdit.get(); - chargeProfileCache = Optional.of(Converter.getGson().toJson(cp)); - chargeProfile = Optional.of(cp); - chargeProfileEdit = Optional.empty(); - updateChargeControlVersion(ChargeControlVersion.REMOTE); - } + saveChargeProfileEdit(); } updateState(remoteStateChannel, StringType .valueOf(Converter.toTitleCase(new StringBuilder(service).append(" ").append(status).toString()))); @@ -726,18 +448,11 @@ public class ChargeProfilesCallback implements StringResponseCallback { @Override public void onResponse(Optional content) { chargeProfileCache = content; - if (content.isPresent()) { + if (content.isPresent() && chargeProfileEdit.isEmpty()) { ChargeProfile cp = Converter.getGson().fromJson(content.get(), ChargeProfile.class); - if (cp == null) { - chargeProfile = Optional.empty(); - } else { - chargeProfile = Optional.of(cp.completeChargeProfile()); - if (!chargeProfileEdit.isPresent()) { - updateChargeProfile(cp); - } + if (cp != null) { + updateChargeProfile(cp); } - } else { - chargeProfile = Optional.empty(); } removeCallback(this); } @@ -749,7 +464,6 @@ public void onResponse(Optional content) { public void onError(NetworkError error) { logger.debug("{}", error.toString()); chargeProfileCache = Optional.of(Converter.getGson().toJson(error)); - chargeProfile = Optional.empty(); removeCallback(this); } } @@ -971,4 +685,300 @@ public void onError(NetworkError error) { vehicleStatusCallback.onError(error); } } + + private void handleChargeProfileCommand(ChannelUID channelUID, Command command) { + + final String id = channelUID.getIdWithoutGroup(); + + if (CHARGE_CONTROL_COMMAND.equals(id) && command instanceof StringType) { + if (chargeProfileEdit.isPresent()) { + switch (((StringType) command).toFullString()) { + case CHARGE_CONTROL_CANCEL: + cancelChargeProfileEdit(); + break; + case CHARGE_CONTROL_SEND: + if (remote.isPresent()) { + remote.get().execute(RemoteService.CHARGING_CONTROL, + Converter.getGson().toJson(chargeProfileEdit.get())); + } + break; + } + } + } else { + startChargeProfileEdit(); + + final WeeklyPlanner wp = chargeProfileEdit.get().weeklyPlanner; + + if (command instanceof StringType) { + switch (id) { + case CHARGE_PROFILE_MODE: + wp.chargingMode = ((StringType) command).toFullString(); + break; + default: + cancelChargeProfileEdit(); + break; + } + } else if (command instanceof OnOffType) { + switch (id) { + case CHARGE_PROFILE_CLIMATE: + wp.climatizationEnabled = OnOffType.ON.equals(command) ? true : false; + break; + case CHARGE_TIMER1_ENABLED: + wp.timer1.timerEnabled = OnOffType.ON.equals(command) ? true : false; + break; + case CHARGE_TIMER1_DAYS_MON: + if (OnOffType.ON.equals(command)) { + wp.timer1.dayOn(Day.MONDAY); + } else { + wp.timer1.dayOff(Day.MONDAY); + } + updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + break; + case CHARGE_TIMER1_DAYS_TUE: + if (OnOffType.ON.equals(command)) { + wp.timer1.dayOn(Day.TUESDAY); + } else { + wp.timer1.dayOff(Day.TUESDAY); + } + updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + break; + case CHARGE_TIMER1_DAYS_WED: + if (OnOffType.ON.equals(command)) { + wp.timer1.dayOn(Day.WEDNESDAY); + } else { + wp.timer1.dayOff(Day.WEDNESDAY); + } + updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + break; + case CHARGE_TIMER1_DAYS_THU: + if (OnOffType.ON.equals(command)) { + wp.timer1.dayOn(Day.THURSDAY); + } else { + wp.timer1.dayOff(Day.THURSDAY); + } + updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + break; + case CHARGE_TIMER1_DAYS_FRI: + if (OnOffType.ON.equals(command)) { + wp.timer1.dayOn(Day.FRIDAY); + } else { + wp.timer1.dayOff(Day.FRIDAY); + } + updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + break; + case CHARGE_TIMER1_DAYS_SAT: + if (OnOffType.ON.equals(command)) { + wp.timer1.dayOn(Day.SATURDAY); + } else { + wp.timer1.dayOff(Day.SATURDAY); + } + updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + break; + case CHARGE_TIMER1_DAYS_SUN: + if (OnOffType.ON.equals(command)) { + wp.timer1.dayOn(Day.SUNDAY); + } else { + wp.timer1.dayOff(Day.SUNDAY); + } + updateState(timer1Days, StringType.valueOf(wp.timer1.getDays())); + break; + case CHARGE_TIMER2_ENABLED: + wp.timer2.timerEnabled = OnOffType.ON.equals(command) ? true : false; + break; + case CHARGE_TIMER2_DAYS_MON: + if (OnOffType.ON.equals(command)) { + wp.timer2.dayOn(Day.MONDAY); + } else { + wp.timer2.dayOff(Day.MONDAY); + } + updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + break; + case CHARGE_TIMER2_DAYS_TUE: + if (OnOffType.ON.equals(command)) { + wp.timer2.dayOn(Day.TUESDAY); + } else { + wp.timer2.dayOff(Day.TUESDAY); + } + updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + break; + case CHARGE_TIMER2_DAYS_WED: + if (OnOffType.ON.equals(command)) { + wp.timer2.dayOn(Day.WEDNESDAY); + } else { + wp.timer2.dayOff(Day.WEDNESDAY); + } + updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + break; + case CHARGE_TIMER2_DAYS_THU: + if (OnOffType.ON.equals(command)) { + wp.timer2.dayOn(Day.THURSDAY); + } else { + wp.timer2.dayOff(Day.THURSDAY); + } + updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + break; + case CHARGE_TIMER2_DAYS_FRI: + if (OnOffType.ON.equals(command)) { + wp.timer2.dayOn(Day.FRIDAY); + } else { + wp.timer2.dayOff(Day.FRIDAY); + } + updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + break; + case CHARGE_TIMER2_DAYS_SAT: + if (OnOffType.ON.equals(command)) { + wp.timer2.dayOn(Day.SATURDAY); + } else { + wp.timer2.dayOff(Day.SATURDAY); + } + updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + break; + case CHARGE_TIMER2_DAYS_SUN: + if (OnOffType.ON.equals(command)) { + wp.timer2.dayOn(Day.SUNDAY); + } else { + wp.timer2.dayOff(Day.SUNDAY); + } + updateState(timer2Days, StringType.valueOf(wp.timer2.getDays())); + break; + case CHARGE_TIMER3_ENABLED: + wp.timer3.timerEnabled = OnOffType.ON.equals(command) ? true : false; + break; + case CHARGE_TIMER3_DAYS_MON: + if (OnOffType.ON.equals(command)) { + wp.timer3.dayOn(Day.MONDAY); + } else { + wp.timer3.dayOff(Day.MONDAY); + } + updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + break; + case CHARGE_TIMER3_DAYS_TUE: + if (OnOffType.ON.equals(command)) { + wp.timer3.dayOn(Day.TUESDAY); + } else { + wp.timer3.dayOff(Day.TUESDAY); + } + updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + break; + case CHARGE_TIMER3_DAYS_WED: + if (OnOffType.ON.equals(command)) { + wp.timer3.dayOn(Day.WEDNESDAY); + } else { + wp.timer3.dayOff(Day.WEDNESDAY); + } + updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + break; + case CHARGE_TIMER3_DAYS_THU: + if (OnOffType.ON.equals(command)) { + wp.timer3.dayOn(Day.THURSDAY); + } else { + wp.timer3.dayOff(Day.THURSDAY); + } + updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + break; + case CHARGE_TIMER3_DAYS_FRI: + if (OnOffType.ON.equals(command)) { + wp.timer3.dayOn(Day.FRIDAY); + } else { + wp.timer3.dayOff(Day.FRIDAY); + } + updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + break; + case CHARGE_TIMER3_DAYS_SAT: + if (OnOffType.ON.equals(command)) { + wp.timer3.dayOn(Day.SATURDAY); + } else { + wp.timer3.dayOff(Day.SATURDAY); + } + updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + break; + case CHARGE_TIMER3_DAYS_SUN: + if (OnOffType.ON.equals(command)) { + wp.timer3.dayOn(Day.SUNDAY); + } else { + wp.timer3.dayOff(Day.SUNDAY); + } + updateState(timer3Days, StringType.valueOf(wp.timer3.getDays())); + break; + default: + this.cancelChargeProfileEdit(); + } + } else if (command instanceof DecimalType) { + final int numberCommand = ((DecimalType) command).intValue(); + switch (id) { + case CHARGE_WINDOW_START_HOUR: + wp.preferredChargingWindow.setStartHour(numberCommand); + updateState(chargeWindowStart, StringType.valueOf(wp.preferredChargingWindow.startTime)); + break; + case CHARGE_WINDOW_START_MINUTE: + wp.preferredChargingWindow.setStartMinute(numberCommand); + updateState(chargeWindowStart, StringType.valueOf(wp.preferredChargingWindow.startTime)); + break; + case CHARGE_WINDOW_END_HOUR: + wp.preferredChargingWindow.setEndHour(numberCommand); + updateState(chargeWindowEnd, StringType.valueOf(wp.preferredChargingWindow.endTime)); + break; + case CHARGE_WINDOW_END_MINUTE: + wp.preferredChargingWindow.setEndMinute(numberCommand); + updateState(chargeWindowEnd, StringType.valueOf(wp.preferredChargingWindow.endTime)); + break; + case CHARGE_TIMER1_DEPARTURE_HOUR: + wp.timer1.setDepartureHour(numberCommand); + updateState(timer1Departure, StringType.valueOf(wp.timer1.departureTime)); + break; + case CHARGE_TIMER1_DEPARTURE_MINUTE: + wp.timer1.setDepartureMinute(numberCommand); + updateState(timer1Departure, StringType.valueOf(wp.timer1.departureTime)); + break; + case CHARGE_TIMER2_DEPARTURE_HOUR: + wp.timer2.setDepartureHour(numberCommand); + updateState(timer2Departure, StringType.valueOf(wp.timer2.departureTime)); + break; + case CHARGE_TIMER2_DEPARTURE_MINUTE: + wp.timer2.setDepartureMinute(numberCommand); + updateState(timer2Departure, StringType.valueOf(wp.timer2.departureTime)); + break; + case CHARGE_TIMER3_DEPARTURE_HOUR: + wp.timer3.setDepartureHour(numberCommand); + updateState(timer3Departure, StringType.valueOf(wp.timer3.departureTime)); + break; + case CHARGE_TIMER3_DEPARTURE_MINUTE: + wp.timer3.setDepartureMinute(numberCommand); + updateState(timer3Departure, StringType.valueOf(wp.timer3.departureTime)); + break; + default: + this.cancelChargeProfileEdit(); + } + } else { + this.cancelChargeProfileEdit(); + } + } + } + + private void cancelChargeProfileEdit() { + chargeProfileEdit = Optional.empty(); + final ChargeProfile cp = Converter.getGson().fromJson(chargeProfileCache.get(), ChargeProfile.class); + if (cp != null) { + updateChargeProfile(cp); + } + updateChargeControlVersion(ChargeControlVersion.REMOTE); + } + + private void startChargeProfileEdit() { + if (chargeProfileEdit.isEmpty()) { + final ChargeProfile cp = Converter.getGson().fromJson(chargeProfileCache.get(), ChargeProfile.class); + if (cp == null) { + chargeProfileEdit = Optional.of(ChargeProfile.defaultChargeProfile()); + } else { + chargeProfileEdit = Optional.of(cp.completeChargeProfile()); + } + updateChargeControlVersion(ChargeControlVersion.EDIT); + } + } + + private void saveChargeProfileEdit() { + chargeProfileCache = Optional.of(Converter.getGson().toJson(chargeProfileEdit.get())); + chargeProfileEdit = Optional.empty(); + updateChargeControlVersion(ChargeControlVersion.REMOTE); + } } From 659741d953414475c4d2fd78a49566aa7ac55cd0 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Tue, 19 Jan 2021 00:29:30 +0100 Subject: [PATCH 105/176] some beautification Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../internal/ConnectedDriveConstants.java | 6 +++--- .../internal/handler/VehicleChannelHandler.java | 12 ++++++------ .../internal/handler/VehicleHandler.java | 12 +++++++----- .../resources/OH-INF/thing/charge-channel-types.xml | 4 ++-- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index a8b734fcafc5d..ea04685d24a04 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -77,9 +77,9 @@ public enum ChargingPreference { CHARGING_WINDOW } - public enum ChargeControlVersion { + public enum ChargeProfileVersion { REMOTE, - EDIT + LOCAL } public static final String CHARGE_CONTROL_CANCEL = "CANCEL"; @@ -196,7 +196,7 @@ public enum ChargeControlVersion { public static final String CHARGE_TIMER3_DAYS_SUN = "timer3-days-sunday"; public static final String CHARGE_TIMER3_ENABLED = "timer3-enabled"; public static final String CHARGE_CONTROL_COMMAND = "command"; - public static final String CHARGE_CONTROL_VERSION = "version"; + public static final String CHARGE_PROFILE_VERSION = "version"; // Range public static final String RANGE_HYBRID = "hybrid"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 35eb623085ac4..3b0d9461e1895 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -22,7 +22,7 @@ import javax.measure.quantity.Length; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.ChargeControlVersion; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.ChargeProfileVersion; import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; import org.openhab.binding.bmwconnecteddrive.internal.dto.Destination; import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.ChargeProfile; @@ -200,7 +200,7 @@ public class VehicleChannelHandler extends BaseThingHandler { protected ChannelUID timer3DaysSat; protected ChannelUID timer3DaysSun; protected ChannelUID chargeControl; - protected ChannelUID chargeControlVersion; + protected ChannelUID chargeProfileVersion; // Image protected ChannelUID imageChannel; @@ -336,7 +336,7 @@ public VehicleChannelHandler(Thing thing, BMWConnectedDriveOptionProvider op, St timer3DaysSat = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAYS_SAT); timer3DaysSun = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAYS_SUN); chargeControl = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_CONTROL_COMMAND); - chargeControlVersion = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_CONTROL_VERSION); + chargeProfileVersion = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_PROFILE_VERSION); remoteCommandChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_COMMAND); remoteStateChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_STATE); @@ -625,13 +625,13 @@ protected void updateChargeProfile(ChargeProfile cp) { updateState(timer3DaysSun, OnOffType.from(t3.isDayOn(Day.SUNDAY))); } - protected void updateChargeControlVersion(ChargeControlVersion version) { - if (ChargeControlVersion.EDIT.equals(version)) { + protected void updateChargeProfileVersion(ChargeProfileVersion version) { + if (ChargeProfileVersion.LOCAL.equals(version)) { updateState(chargeControl, StringType.valueOf(CHARGE_CONTROL_SEND)); } else { updateState(chargeControl, StringType.valueOf(CHARGE_CONTROL_CANCEL)); } - updateState(chargeControlVersion, StringType.valueOf(version.name())); + updateState(chargeProfileVersion, StringType.valueOf(version.name())); } protected void updateDoors(Doors doorState) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 65debc7e80975..3f9faa405e37d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -106,10 +106,10 @@ public void handleCommand(ChannelUID channelUID, Command command) { } else if (CHANNEL_GROUP_CHARGE.equals(group)) { if (chargeProfileEdit.isEmpty()) { chargeProfileCallback.onResponse(chargeProfileCache); - updateChargeControlVersion(ChargeControlVersion.REMOTE); + updateChargeProfileVersion(ChargeProfileVersion.REMOTE); } else { updateChargeProfile(chargeProfileEdit.get()); - updateChargeControlVersion(ChargeControlVersion.EDIT); + updateChargeProfileVersion(ChargeProfileVersion.LOCAL); } } else if (CHANNEL_GROUP_VEHICLE_IMAGE.equals(group)) { imageCallback.onResponse(imageCache); @@ -902,6 +902,7 @@ private void handleChargeProfileCommand(ChannelUID channelUID, Command command) break; default: this.cancelChargeProfileEdit(); + break; } } else if (command instanceof DecimalType) { final int numberCommand = ((DecimalType) command).intValue(); @@ -948,6 +949,7 @@ private void handleChargeProfileCommand(ChannelUID channelUID, Command command) break; default: this.cancelChargeProfileEdit(); + break; } } else { this.cancelChargeProfileEdit(); @@ -961,7 +963,7 @@ private void cancelChargeProfileEdit() { if (cp != null) { updateChargeProfile(cp); } - updateChargeControlVersion(ChargeControlVersion.REMOTE); + updateChargeProfileVersion(ChargeProfileVersion.REMOTE); } private void startChargeProfileEdit() { @@ -972,13 +974,13 @@ private void startChargeProfileEdit() { } else { chargeProfileEdit = Optional.of(cp.completeChargeProfile()); } - updateChargeControlVersion(ChargeControlVersion.EDIT); + updateChargeProfileVersion(ChargeProfileVersion.LOCAL); } } private void saveChargeProfileEdit() { chargeProfileCache = Optional.of(Converter.getGson().toJson(chargeProfileEdit.get())); chargeProfileEdit = Optional.empty(); - updateChargeControlVersion(ChargeControlVersion.REMOTE); + updateChargeProfileVersion(ChargeProfileVersion.REMOTE); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml index f720d2548ae48..408778e674d25 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml @@ -207,11 +207,11 @@ String - + - + From c1108ee5f341b439e740f85b2d816941a4bc13ee Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Tue, 19 Jan 2021 14:15:08 +0100 Subject: [PATCH 106/176] use Map.of when declaring constant Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../internal/utils/Constants.java | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java index ee2f6f02bd382..81041eb73d10d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -12,7 +12,6 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.utils; -import java.util.HashMap; import java.util.Map; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -66,16 +65,7 @@ public class Constants { public static final int MILES_TO_FEET_FACTOR = 5280; public static final String EMPTY_VEHICLES = "{}"; - @SuppressWarnings("serial") - public static final Map DAYS = new HashMap() { - { - put(Day.MONDAY.name(), "Mon"); - put(Day.TUESDAY.name(), "Tue"); - put(Day.WEDNESDAY.name(), "Wed"); - put(Day.THURSDAY.name(), "Thu"); - put(Day.FRIDAY.name(), "Fri"); - put(Day.SATURDAY.name(), "Sat"); - put(Day.SUNDAY.name(), "Sun"); - } - }; + public static final Map DAYS = Map.of(Day.MONDAY.name(), "Mon", Day.TUESDAY.name(), "Tue", + Day.WEDNESDAY.name(), "Wed", Day.THURSDAY.name(), "Thu", Day.FRIDAY.name(), "Fri", Day.SATURDAY.name(), + "Sat", Day.SUNDAY.name(), "Sun"); } From ab2841b342ea845f4650e426928a80bba7edbf03 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Tue, 2 Feb 2021 14:16:11 +0100 Subject: [PATCH 107/176] refactoring plus addition of ChargeProfile Action Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../README.md | 177 +++++-- .../internal/ConnectedDriveConstants.java | 64 ++- .../internal/action/ChargeProfileActions.java | 440 ++++++++++++++++ .../internal/dto/charge/ChargeProfile.java | 16 +- .../internal/dto/charge/ChargingWindow.java | 29 -- .../internal/dto/charge/Timer.java | 64 +-- .../internal/dto/charge/WeeklyPlanner.java | 43 +- .../internal/handler/ConnectedDriveProxy.java | 2 +- .../handler/RemoteServiceHandler.java | 3 +- .../handler/VehicleChannelHandler.java | 322 ++++++------ .../internal/handler/VehicleHandler.java | 486 +++++++----------- .../internal/utils/ChargeProfileUtils.java | 31 +- .../internal/utils/ChargeProfileWrapper.java | 279 ++++++++++ .../internal/utils/Constants.java | 21 +- .../OH-INF/thing/charge-channel-groups.xml | 49 +- .../OH-INF/thing/charge-channel-types.xml | 96 ++-- .../thing/remote-services-channel-types.xml | 2 + .../internal/handler/ChargeProfileTest.java | 2 +- 18 files changed, 1371 insertions(+), 755 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 6dee166e9fe13..1a45bc12e4193 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -274,22 +274,54 @@ Charging options with date and time for preferred time windows and charging mode * Available for electric and hybrid vehicles * Read-only values -| Channel Label | Channel ID | Type | -|------------------------------------|---------------------|--------| -| A/C at Departure Time | profile-climate | Switch | -| Charge Mode for Profile | profile-mode | String | -| Charge Window Start Time | window-start | String | -| Charge Window End Time | window-end | String | -| Timer 1: Departure Time | timer1-departure | String | -| Timer 1: Scheduled Days | timer1-days | String | -| Timer 1: Enabled | timer1-enabled | Switch | -| Timer 2: Departure Time | timer2-departure | String | -| Timer 2: Scheduled Days | timer2-days | String | -| Timer 2: Enabled | timer2-enabled | Switch | -| Timer 3: Departure Time | timer3-departure | String | -| Timer 3: Scheduled Days | timer3-days | String | -| Timer 3: Enabled | timer3-enabled | Switch | - +| Channel Label | Channel Group ID | Channel ID | Type | +|---------------------------------------|------------------|---------------------------|----------| +| Charging Mode for Profile | charge | profile-mode | String | +| Charging Preferences for Profile | charge | profile-prefs | String | +| Charging Window Start Time | charge | window-start | DateTime | +| Charging Window Start Time Hour | charge | window-start-hour | Number | +| Charging Window Start Time Minute | charge | window-start-minute | Number | +| Charging Window End Time | charge | window-end | DateTime | +| Charging Window End Time Hour | charge | window-end-hour | Number | +| Charging Window End Time Minute | charge | window-end-minute | Number | +| Air Conditioning at Departure Time | charge | profile-climate | Switch | +| Timer 1: Enabled | charge | timer1-enabled | Switch | +| Timer 1: Departure Time | charge | timer1-departure | DateTime | +| Timer 1: Departure Time Hour | charge | timer1-departure-hour | Number | +| Timer 1: Departure Time Minute | charge | timer1-departure-minute | Number | +| Timer 1: Monday | charge | timer1-day-mon | Switch | +| Timer 1: Tuesday | charge | timer1-day-tue | Switch | +| Timer 1: Wednesday | charge | timer1-day-wed | Switch | +| Timer 1: Thursday | charge | timer1-day-thu | Switch | +| Timer 1: Friday | charge | timer1-day-fri | Switch | +| Timer 1: Saturday | charge | timer1-day-sat | Switch | +| Timer 1: Sunday | charge | timer1-day-sun | Switch | +| Timer 2: Enabled | charge | timer2-enabled | Switch | +| Timer 2: Departure Time | charge | timer2-departure | DateTime | +| Timer 2: Departure Time Hour | charge | timer2-departure-hour | Number | +| Timer 2: Departure Time Minute | charge | timer2-departure-minute | Number | +| Timer 2: Monday | charge | timer2-day-mon | Switch | +| Timer 2: Tuesday | charge | timer2-day-tue | Switch | +| Timer 2: Wednesday | charge | timer2-day-wed | Switch | +| Timer 2: Thursday | charge | timer2-day-thu | Switch | +| Timer 2: Friday | charge | timer2-day-fri | Switch | +| Timer 2: Saturday | charge | timer2-day-sat | Switch | +| Timer 2: Sunday | charge | timer2-day-sun | Switch | +| Timer 3: Enabled | charge | timer3-enabled | Switch | +| Timer 3: Departure Time | charge | timer3-departure | DateTime | +| Timer 3: Departure Time Hour | charge | timer3-departure-hour | Number | +| Timer 3: Departure Time Minute | charge | timer3-departure-minute | Number | +| Timer 3: Monday | charge | timer3-day-mon | Switch | +| Timer 3: Tuesday | charge | timer3-day-tue | Switch | +| Timer 3: Wednesday | charge | timer3-day-wed | Switch | +| Timer 3: Thursday | charge | timer3-day-thu | Switch | +| Timer 3: Friday | charge | timer3-day-fri | Switch | +| Timer 3: Saturday | charge | timer3-day-sat | Switch | +| Timer 3: Sunday | charge | timer3-day-sun | Switch | +| Override Timer: Enabled | charge | override-enabled | Switch | +| Override Timer: Departure Time | charge | override-departure | DateTime | +| Override Timer: Departure Time Hour | charge | override-departure-hour | Number | +| Override Timer: Departure Time Minute | charge | override-departure-minute | Number | #### Location @@ -361,12 +393,14 @@ Parallel execution isn't supported. The channel _command_ provides options -* _Flash Lights_ +* _Flash Lights_ * _Vehicle Finder_ * _Door Lock_ * _Door Unlock_ * _Horn Blow_ * _Climate Control_ +* _Start Charging_ +* _Send Charging Profile_ The channel _state_ shows the progress of the command execution in the following order @@ -563,17 +597,51 @@ Location i3DestLocation "GPS [%s]" Switch i3ChargeProfileClimate "Charge Profile Climatization" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:charge#profile-climate" } String i3ChargeProfileMode "Charge Profile Mode [%s]" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:charge#profile-mode" } -String i3ChargeWindowStart "Charge Window Start [%s]" - + String + + + + + + + + + + DateTime @@ -32,7 +42,7 @@ - String + DateTime @@ -46,7 +56,7 @@ - String + DateTime @@ -63,31 +73,31 @@ String - + Switch - + Switch - + Switch - + Switch - + Switch - + Switch - + Switch @@ -96,7 +106,7 @@ - String + DateTime @@ -113,31 +123,31 @@ String - + Switch - + Switch - + Switch - + Switch - + Switch - + Switch - + Switch @@ -146,7 +156,7 @@ - String + DateTime @@ -163,31 +173,31 @@ String - + Switch - + Switch - + Switch - + Switch - + Switch - + Switch - + Switch @@ -195,24 +205,22 @@ Switch - - String - - - - - - - + + DateTime + - - String - - - - - - - + + Number + + + + + Number + + + + + Switch + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-types.xml index 5b05808cee5a3..2af2e45b6ff6e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-types.xml @@ -14,6 +14,8 @@ + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java index c659e87e9b543..0c3b50432db84 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java @@ -44,7 +44,7 @@ public class ChargeProfileTest { private final Logger logger = LoggerFactory.getLogger(VehicleHandler.class); - private static final int PROFILE_CALLBACK_NUMBER = 44; + private static final int PROFILE_CALLBACK_NUMBER = 49; @Nullable ArgumentCaptor channelCaptor; From b1f68d812f9f514985f5f9a9d1135cf12a3584fb Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Tue, 2 Feb 2021 18:59:19 +0100 Subject: [PATCH 108/176] fix skip of charge-profile-command handling if no profile has been received yet Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../bmwconnecteddrive/internal/handler/VehicleHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index b8c82e9ff9a4b..b7829703e7681 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -777,11 +777,11 @@ private void handleChargeProfileCommand(ChannelUID channelUID, Command command) if (chargeProfileEdit.isEmpty()) { if (chargeProfileCache.isPresent()) { chargeProfileEdit = Optional.ofNullable(getChargeProfileWrapper()); - if (chargeProfileEdit.isPresent()) { - } else { + if (chargeProfileEdit.isEmpty()) { return; } } else { + return; } } From bc96c4246f78568c44a980d7d2a5744aa34828b3 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Tue, 2 Feb 2021 19:18:37 +0100 Subject: [PATCH 109/176] codeowners Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 0f7b8512b56b4..2e1f95d172c38 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -35,7 +35,7 @@ /bundles/org.openhab.binding.bluetooth.govee/ @cpmeister /bundles/org.openhab.binding.bluetooth.roaming/ @cpmeister /bundles/org.openhab.binding.bluetooth.ruuvitag/ @ssalonen -/bundles/org.openhab.binding.bmwconnecteddrive/ @weymann +/bundles/org.openhab.binding.bmwconnecteddrive/ @weymann @ntruchsess /bundles/org.openhab.binding.boschindego/ @jofleck /bundles/org.openhab.binding.boschshc/ @stefan-kaestle @coeing @GerdZanker /bundles/org.openhab.binding.bosesoundtouch/ @marvkis @tratho From 230b981f6ede6fb876b9b17c2d7c52e7c7e18736 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Wed, 3 Feb 2021 12:55:48 +0100 Subject: [PATCH 110/176] some cleanup and logging Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../internal/action/ChargeProfileActions.java | 21 ++-- .../handler/VehicleChannelHandler.java | 11 +- .../internal/handler/VehicleHandler.java | 33 +++--- .../internal/utils/ChargeProfileWrapper.java | 109 +++++++++++------- .../internal/utils/Constants.java | 8 +- 5 files changed, 108 insertions(+), 74 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java index 3f1fdca505a48..c290114426eb4 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java @@ -47,7 +47,7 @@ @NonNullByDefault public class ChargeProfileActions implements ThingActions { - private @Nullable VehicleHandler handler; + private Optional handler = Optional.empty(); private Optional profile = Optional.empty(); @@ -215,8 +215,8 @@ public void setOverrideTimerDays(@ActionInput(name = "days", type = "StringListT @RuleAction(label = "send", description = "sends the charging profile to the vehicle") public void send() { - if (hasProfile() && handler != null) { - handler.sendChargeProfile(profile.get()); + if (hasProfile() && handler.isPresent()) { + handler.get().sendChargeProfile(profile); } } @@ -364,21 +364,18 @@ public static void cancel(ThingActions actions) { @Override public void setThingHandler(@Nullable ThingHandler handler) { if (handler instanceof VehicleHandler) { - this.handler = (VehicleHandler) handler; + this.handler = Optional.of((VehicleHandler) handler); } } @Override public @Nullable ThingHandler getThingHandler() { - return handler; + return handler.get(); } private boolean hasProfile() { - if (profile.isEmpty() && handler != null) { - final ChargeProfileWrapper wrapper = handler.getChargeProfileWrapper(); - if (wrapper != null) { - profile = Optional.of(wrapper); - } + if (profile.isEmpty() && handler.isPresent()) { + profile = Optional.ofNullable(handler.get().getChargeProfileWrapper()); } return profile.isPresent(); } @@ -387,7 +384,7 @@ private boolean hasProfile() { if (hasProfile()) { final LocalTime time = profile.get().getTime(key); if (time != null) { - return new DateTimeType(ZonedDateTime.of(Constants.EPOCHDAY, time, ZoneId.systemDefault())); + return new DateTimeType(ZonedDateTime.of(Constants.EPOCH_DAY, time, ZoneId.systemDefault())); } } return null; @@ -401,7 +398,7 @@ private void setDateTime(ProfileKey key, DateTimeType time) { private @Nullable OnOffType getEnabled(ProfileKey key) { if (hasProfile()) { - Boolean enabled = profile.get().isEnabled(key); + final Boolean enabled = profile.get().isEnabled(key); if (enabled != null) { return OnOffType.from(enabled); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index b50788e2d19cd..ad1aa92d2adaf 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -579,6 +579,15 @@ protected void updateLastTrip(LastTrip trip) { updateState(tripAvgRecuperation, QuantityType.valueOf(Converter.round(avgRecuperation), Units.KILOWATT_HOUR)); } + protected void updateChargeProfile(Optional content) { + if (content.isPresent()) { + final ChargeProfileWrapper profile = ChargeProfileWrapper.fromJson(content.get()); + if (profile != null) { + updateChargeProfile(profile); + } + } + } + protected void updateChargeProfile(ChargeProfileWrapper wrapper) { updateState(chargeProfilePreference, StringType.valueOf(Converter.toTitleCase(wrapper.getPreference()))); updateState(chargeProfileChargeMode, StringType.valueOf(Converter.toTitleCase(wrapper.getMode()))); @@ -599,7 +608,7 @@ protected void updateTimedState(ChargeProfileWrapper profile, ProfileKey key) { // updateState(channels.time, time == null ? UnDefType.UNDEF : // StringType.valueOf(time.format(TIMEFORMATER))); updateState(channels.time, time == null ? UnDefType.UNDEF - : new DateTimeType(ZonedDateTime.of(Constants.EPOCHDAY, time, ZoneId.systemDefault()))); + : new DateTimeType(ZonedDateTime.of(Constants.EPOCH_DAY, time, ZoneId.systemDefault()))); updateState(channels.hour, time == null ? UnDefType.UNDEF : new DecimalType(time.getHour())); updateState(channels.minute, time == null ? UnDefType.UNDEF : new DecimalType(time.getMinute())); if (channels instanceof TimerChannels) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index b7829703e7681..75f1cd31b4a62 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -189,7 +189,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { vehicleStatusCallback.onResponse(vehicleStatusCache); } else if (CHANNEL_GROUP_CHARGE.equals(group)) { if (chargeProfileEdit.isEmpty()) { - chargeProfileCallback.onResponse(chargeProfileCache); + updateChargeProfile(chargeProfileCache); } else { updateChargeProfile(chargeProfileEdit.get()); } @@ -225,7 +225,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { remote.get().execute(RemoteService.CHARGE_NOW); break; case REMOTE_SERVICE_CHARGING_CONTROL: - sendChargeProfile(chargeProfileEdit.get()); + sendChargeProfile(chargeProfileEdit); break; default: logger.info("Remote service execution {} unknown", serviceCommand); @@ -534,11 +534,8 @@ public class ChargeProfilesCallback implements StringResponseCallback { @Override public void onResponse(Optional content) { chargeProfileCache = content; - if (content.isPresent() && chargeProfileEdit.isEmpty()) { - final ChargeProfileWrapper profile = ChargeProfileWrapper.fromJson(content.get()); - if (profile != null) { - updateChargeProfile(profile); - } + if (chargeProfileEdit.isEmpty()) { + updateChargeProfile(chargeProfileCache); } removeCallback(this); } @@ -847,20 +844,22 @@ private void handleChargeProfileCommand(ChannelUID channelUID, Command command) } private void cancelChargeProfileEdit() { + editTimeout = Optional.empty(); chargeProfileEdit = Optional.empty(); - final ChargeProfileWrapper profile = ChargeProfileWrapper.fromJson(chargeProfileCache.get()); - if (profile != null) { - updateChargeProfile(profile); - } + updateChargeProfile(chargeProfileCache); } private void saveChargeProfileSent() { + if (editTimeout.isPresent()) { + editTimeout.get().cancel(true); + editTimeout = Optional.empty(); + } if (chargeProfileSent.isPresent()) { chargeProfileCache = Optional.of(chargeProfileSent.get()); + chargeProfileSent = Optional.empty(); + chargeProfileEdit = Optional.empty(); + updateChargeProfile(chargeProfileCache); } - chargeProfileEdit = Optional.empty(); - chargeProfileSent = Optional.empty(); - chargeProfileCallback.onResponse(chargeProfileCache); } @Override @@ -885,9 +884,9 @@ public ChargeProfileWrapper getChargeProfileWrapper() { } } - public void sendChargeProfile(final @Nullable ChargeProfileWrapper profile) { - if (remote.isPresent() && profile != null) { - final String json = profile.getJson(); + public void sendChargeProfile(Optional profile) { + if (remote.isPresent() && profile.isPresent()) { + final String json = profile.get().getJson(); logger.info("sending charging profile: {}", json); chargeProfileSent = Optional.of(json); remote.get().execute(RemoteService.CHARGING_CONTROL, json); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java index 1a5ab429e2241..0af1f4f2532a4 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java @@ -12,8 +12,12 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.utils; +import static org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileWrapper.ProfileKey.*; +import static org.openhab.binding.bmwconnecteddrive.internal.utils.Constants.NULL_LOCAL_TIME; +import static org.openhab.binding.bmwconnecteddrive.internal.utils.Constants.TIME_FORMATER; + import java.time.LocalTime; -import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.EnumSet; import java.util.HashMap; @@ -30,6 +34,8 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.ChargingWindow; import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.Timer; import org.openhab.binding.bmwconnecteddrive.internal.dto.charge.WeeklyPlanner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The {@link ChargeProfileWrapper} Wrapper for ChargeProfiles @@ -40,7 +46,7 @@ @NonNullByDefault public class ChargeProfileWrapper { - public static final DateTimeFormatter TIMEFORMATER = DateTimeFormatter.ofPattern("HH:mm"); + private final Logger logger = LoggerFactory.getLogger(ChargeProfileWrapper.class); public enum ProfileType { WEEKLY, @@ -58,7 +64,7 @@ public enum ProfileKey { WINDOWEND } - protected ProfileType type = ProfileType.EMPTY; + final protected ProfileType type; @Nullable private ChargingMode mode; @@ -90,26 +96,25 @@ private ChargeProfileWrapper(final ChargeProfile profile) { return; } - preference = planner.chargingPreferences == null ? null - : ChargingPreference.valueOf(planner.chargingPreferences); - mode = planner.chargingMode == null ? null : ChargingMode.valueOf(planner.chargingMode); + setPreference(planner.chargingPreferences); + setMode(planner.chargingMode); - this.setEnabled(ProfileKey.CLIMATE, planner.climatizationEnabled); + setEnabled(CLIMATE, planner.climatizationEnabled); - addTimer(ProfileKey.TIMER1, planner.timer1); - addTimer(ProfileKey.TIMER2, planner.timer2); + addTimer(TIMER1, planner.timer1); + addTimer(TIMER2, planner.timer2); if (planner.preferredChargingWindow != null) { - addTime(ProfileKey.WINDOWSTART, planner.preferredChargingWindow.startTime); - addTime(ProfileKey.WINDOWEND, planner.preferredChargingWindow.endTime); + addTime(WINDOWSTART, planner.preferredChargingWindow.startTime); + addTime(WINDOWEND, planner.preferredChargingWindow.endTime); } else if (ChargingPreference.CHARGING_WINDOW.equals(preference)) { - addTime(ProfileKey.WINDOWSTART, Constants.NULL_TIME); - addTime(ProfileKey.WINDOWEND, Constants.NULL_TIME); + addTime(WINDOWSTART, null); + addTime(WINDOWEND, null); } - if (ProfileType.WEEKLY.equals(type)) { - addTimer(ProfileKey.TIMER3, planner.timer3); - addTimer(ProfileKey.OVERRIDE, planner.overrideTimer); + if (isWeekly()) { + addTimer(TIMER3, planner.timer3); + addTimer(OVERRIDE, planner.overrideTimer); } } @@ -129,6 +134,7 @@ public void setMode(final String mode) { try { this.mode = ChargingMode.valueOf(mode); } catch (IllegalArgumentException iae) { + logger.warn("unexpected value for chargingMode: {}", mode); this.mode = null; } } @@ -141,6 +147,7 @@ public void setPreference(final String preference) { try { this.preference = ChargingPreference.valueOf(preference); } catch (IllegalArgumentException iae) { + logger.warn("unexpected value for chargingPreference: {}", preference); this.preference = null; } } @@ -157,10 +164,16 @@ public void setPreference(final String preference) { return null; } - public void setDays(final ProfileKey key, final List days) { + public void setDays(final ProfileKey key, @Nullable final List days) { final EnumSet daySet = EnumSet.noneOf(Day.class); - for (String day : days) { - daySet.add(Day.valueOf(day)); + if (days != null) { + for (String day : days) { + try { + daySet.add(Day.valueOf(day)); + } catch (IllegalArgumentException iae) { + logger.warn("unexpected value for {} day: {}", key.name(), day); + } + } } daysOfWeek.put(key, daySet); } @@ -197,7 +210,7 @@ public void setTime(final ProfileKey key, LocalTime time) { public void setHour(final ProfileKey key, final int hour) { LocalTime dateTime = times.get(key); if (dateTime == null) { - dateTime = LocalTime.parse(Constants.NULL_TIME, TIMEFORMATER); + dateTime = NULL_LOCAL_TIME; } times.put(key, dateTime.withHour(hour)); } @@ -205,7 +218,7 @@ public void setHour(final ProfileKey key, final int hour) { public void setMinute(final ProfileKey key, int minute) { LocalTime dateTime = times.get(key); if (dateTime == null) { - dateTime = LocalTime.parse(Constants.NULL_TIME, TIMEFORMATER); + dateTime = NULL_LOCAL_TIME; } times.put(key, dateTime.withMinute(minute)); } @@ -215,47 +228,49 @@ public String getJson() { final WeeklyPlanner planner = new WeeklyPlanner(); planner.chargingPreferences = preference == null ? null : preference.name(); - planner.climatizationEnabled = isEnabled(ProfileKey.CLIMATE); + planner.climatizationEnabled = isEnabled(CLIMATE); if (ChargingPreference.CHARGING_WINDOW.equals(preference)) { planner.chargingMode = getMode(); - final LocalTime start = getTime(ProfileKey.WINDOWSTART); - final LocalTime end = getTime(ProfileKey.WINDOWEND); + final LocalTime start = getTime(WINDOWSTART); + final LocalTime end = getTime(WINDOWEND); if (start != null || end != null) { planner.preferredChargingWindow = new ChargingWindow(); - planner.preferredChargingWindow.startTime = start == null ? null : start.format(TIMEFORMATER); - planner.preferredChargingWindow.endTime = end == null ? null : end.format(TIMEFORMATER); + planner.preferredChargingWindow.startTime = start == null ? null : start.format(TIME_FORMATER); + planner.preferredChargingWindow.endTime = end == null ? null : end.format(TIME_FORMATER); } } - planner.timer1 = getTimer(ProfileKey.TIMER1); - planner.timer2 = getTimer(ProfileKey.TIMER2); - if (ProfileType.WEEKLY.equals(type)) { - planner.timer3 = getTimer(ProfileKey.TIMER3); - planner.overrideTimer = getTimer(ProfileKey.OVERRIDE); + planner.timer1 = getTimer(TIMER1); + planner.timer2 = getTimer(TIMER2); + if (isWeekly()) { + planner.timer3 = getTimer(TIMER3); + planner.overrideTimer = getTimer(OVERRIDE); profile.weeklyPlanner = planner; - } else if (ProfileType.TWO_TIMES.equals(type)) { + } else if (isTwoTimes()) { profile.twoTimesTimer = planner; } return Converter.getGson().toJson(profile); } - private void addTime(final ProfileKey key, final String time) { - times.put(key, LocalTime.parse(time, TIMEFORMATER)); + private void addTime(final ProfileKey key, @Nullable final String time) { + try { + times.put(key, time == null ? NULL_LOCAL_TIME : LocalTime.parse(time, TIME_FORMATER)); + } catch (DateTimeParseException dtpe) { + logger.warn("unexpected value for {} time: {}", key.name(), time); + } } private void addTimer(final ProfileKey key, @Nullable final Timer timer) { if (timer == null) { enabled.put(key, false); - addTime(key, Constants.NULL_TIME); - if (ProfileType.WEEKLY.equals(type)) { - setDays(key, List.of()); + addTime(key, null); + if (isWeekly()) { + setDays(key, null); } } else { enabled.put(key, timer.timerEnabled); - addTime(key, timer.departureTime == null ? Constants.NULL_TIME : timer.departureTime); - if (timer.weekdays != null) { + addTime(key, timer.departureTime); + if (isWeekly()) { setDays(key, timer.weekdays); - } else if (ProfileType.WEEKLY.equals(type)) { - setDays(key, List.of()); } } } @@ -264,8 +279,8 @@ private void addTimer(final ProfileKey key, @Nullable final Timer timer) { final Timer timer = new Timer(); timer.timerEnabled = enabled.get(key); final LocalTime time = times.get(key); - timer.departureTime = time == null ? null : time.format(TIMEFORMATER); - if (ProfileType.WEEKLY.equals(type)) { + timer.departureTime = time == null ? null : time.format(TIME_FORMATER); + if (isWeekly()) { final Set days = daysOfWeek.get(key); if (days != null) { timer.weekdays = new ArrayList<>(); @@ -276,4 +291,12 @@ private void addTimer(final ProfileKey key, @Nullable final Timer timer) { } return timer.timerEnabled == null && timer.departureTime == null && timer.weekdays == null ? null : timer; } + + private boolean isWeekly() { + return ProfileType.WEEKLY.equals(type); + } + + private boolean isTwoTimes() { + return ProfileType.TWO_TIMES.equals(type); + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java index b6de06726f9e2..6e311e2b27826 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -12,7 +12,11 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.utils; +import static org.openhab.binding.bmwconnecteddrive.internal.utils.Constants.NULL_TIME; + import java.time.LocalDate; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.Map; @@ -69,7 +73,9 @@ public class Constants { public static final String EMPTY_VEHICLES = "{}"; // Time Constants for DateTime channels - public static final LocalDate EPOCHDAY = LocalDate.ofEpochDay(0); + public static final LocalDate EPOCH_DAY = LocalDate.ofEpochDay(0); + public static final DateTimeFormatter TIME_FORMATER = DateTimeFormatter.ofPattern("HH:mm"); + public static final LocalTime NULL_LOCAL_TIME = LocalTime.parse(NULL_TIME, TIME_FORMATER); @SuppressWarnings("serial") public static final Map DAYS = new HashMap() { From 47931e6e3b7e86f1ed1ddd0a245adbe34473518c Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Thu, 4 Feb 2021 13:29:43 +0100 Subject: [PATCH 111/176] add remaining charging time Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../internal/ConnectedDriveConstants.java | 2 ++ .../internal/dto/status/VehicleStatus.java | 1 + .../internal/handler/VehicleChannelHandler.java | 14 ++++++++++++++ .../OH-INF/thing/ev-vehicle-status-group.xml | 1 + .../thing/vehicle-status-channel-types.xml | 4 ++++ .../internal/dto/StatusWrapper.java | 16 +++++++++++++++- .../internal/handler/VehicleTests.java | 2 +- 7 files changed, 38 insertions(+), 2 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 90436e92b30ae..55ebf57b49474 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -127,6 +127,8 @@ public enum ChargingPreference { public static final String SERVICE_MILEAGE = "service-mileage"; public static final String CHECK_CONTROL = "check-control"; public static final String CHARGE_STATUS = "charge"; + public static final String CHARGE_END_REASON = "reason"; + public static final String CHARGE_REMAINING = "remaining"; public static final String LAST_UPDATE = "last-update"; // Door Details diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java index 80e8fe303b500..7f6beeb5fb45b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java @@ -57,6 +57,7 @@ public class VehicleStatus { public String chargingStatus;// ": "INVALID"," public String lastChargingEndReason;// ": "CHARGING_GOAL_REACHED", public String lastChargingEndResult;// ": "SUCCESS"," + public Double chargingTimeRemaining;// ": "45", public Position position; public String internalDataTimeUTC;// ": "2020-08-24 T15:55:32", public boolean singleImmediateCharging;// ":false, diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index ad1aa92d2adaf..9d932dd1f55b0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -156,6 +156,7 @@ public class VehicleChannelHandler extends BaseThingHandler { // Charging protected ChannelUID chargingStatus; + protected ChannelUID chargingTimeRemaining; protected ChannelUID chargeProfileClimate; protected ChannelUID chargeProfileChargeMode; protected ChannelUID chargeProfilePreference; @@ -241,6 +242,7 @@ public VehicleChannelHandler(Thing thing, BMWConnectedDriveOptionProvider op, St serviceNextMileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, SERVICE_MILEAGE); checkControl = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, CHECK_CONTROL); chargingStatus = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, CHARGE_STATUS); + chargingTimeRemaining = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, CHARGE_REMAINING); lastUpdate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, LAST_UPDATE); serviceDate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, DATE); @@ -767,6 +769,18 @@ protected void updateVehicleStatus(VehicleStatus vStatus) { // State INVALID is somehow misleading. Instead show the Last Charging End Reason updateState(chargingStatus, StringType.valueOf(Converter.toTitleCase(vStatus.chargingStatus))); } + } else { + updateState(chargingStatus, UnDefType.NULL); + } + if (vStatus.chargingTimeRemaining != null) { + try { + updateState(chargingTimeRemaining, + QuantityType.valueOf(vStatus.chargingTimeRemaining, Units.MINUTE)); + } catch (NumberFormatException nfe) { + updateState(chargingTimeRemaining, UnDefType.UNDEF); + } + } else { + updateState(chargingTimeRemaining, UnDefType.NULL); } } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/ev-vehicle-status-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/ev-vehicle-status-group.xml index 3fd292b09dceb..74fbaa8c79a68 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/ev-vehicle-status-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/ev-vehicle-status-group.xml @@ -14,6 +14,7 @@ + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/vehicle-status-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/vehicle-status-channel-types.xml index 129fd3c13eb7c..8f55654dcd280 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/vehicle-status-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/vehicle-status-channel-types.xml @@ -31,6 +31,10 @@ String + + Number:Time + + DateTime diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index 1f01d19b91bb9..34f7f355ddd88 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -21,6 +21,7 @@ import javax.measure.Unit; import javax.measure.quantity.Length; +import javax.measure.quantity.Time; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -42,6 +43,7 @@ import org.openhab.core.library.unit.Units; import org.openhab.core.thing.ChannelUID; import org.openhab.core.types.State; +import org.openhab.core.types.UnDefType; import com.google.gson.Gson; @@ -112,6 +114,7 @@ private void checkResult(ChannelUID channelUID, State state) { String cUid = channelUID.getIdWithoutGroup(); String gUid = channelUID.getGroupId(); QuantityType qt; + QuantityType String - + DateTime @@ -21,7 +21,7 @@ Number:Length - + String From 465f3663f6db0b8bb774598f060f2271b2ecc9b4 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Mon, 15 Feb 2021 23:11:19 +0100 Subject: [PATCH 121/176] fixing review comments (channelUIDs are now dynamic) Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../internal/ConnectedDriveConstants.java | 60 +- .../handler/VehicleChannelHandler.java | 590 ++++++------------ .../internal/handler/VehicleHandler.java | 68 +- .../internal/utils/ChargeProfileWrapper.java | 2 + .../internal/dto/StatusWrapper.java | 2 +- 5 files changed, 223 insertions(+), 499 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 8114082f21c8d..503e646cbb5f3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -128,7 +128,7 @@ public enum ChargingPreference { public static final String DOOR_PASSENGER_REAR = "passenger-rear"; public static final String HOOD = "hood"; public static final String TRUNK = "trunk"; - public static final String WINDOW_DOOR_DRIVER_FORNT = "win-driver-front"; + public static final String WINDOW_DOOR_DRIVER_FRONT = "win-driver-front"; public static final String WINDOW_DOOR_DRIVER_REAR = "win-driver-rear"; public static final String WINDOW_DOOR_PASSENGER_FRONT = "win-passenger-front"; public static final String WINDOW_DOOR_PASSENGER_REAR = "win-passenger-rear"; @@ -143,48 +143,22 @@ public enum ChargingPreference { public static final String CHARGE_WINDOW_START_HOUR = "window-start-hour"; public static final String CHARGE_WINDOW_START_MINUTE = "window-start-minute"; public static final String CHARGE_WINDOW_END = "window-end"; - public static final String CHARGE_WINDOW_END_HOUR = "window-end-hour"; - public static final String CHARGE_WINDOW_END_MINUTE = "window-end-minute"; - public static final String CHARGE_TIMER1_DEPARTURE = "timer1-departure"; - public static final String CHARGE_TIMER1_DEPARTURE_HOUR = "timer1-departure-hour"; - public static final String CHARGE_TIMER1_DEPARTURE_MINUTE = "timer1-departure-minute"; - public static final String CHARGE_TIMER1_DAYS = "timer1-days"; - public static final String CHARGE_TIMER1_DAY_MON = "timer1-day-mon"; - public static final String CHARGE_TIMER1_DAY_TUE = "timer1-day-tue"; - public static final String CHARGE_TIMER1_DAY_WED = "timer1-day-wed"; - public static final String CHARGE_TIMER1_DAY_THU = "timer1-day-thu"; - public static final String CHARGE_TIMER1_DAY_FRI = "timer1-day-fri"; - public static final String CHARGE_TIMER1_DAY_SAT = "timer1-day-sat"; - public static final String CHARGE_TIMER1_DAY_SUN = "timer1-day-sun"; - public static final String CHARGE_TIMER1_ENABLED = "timer1-enabled"; - public static final String CHARGE_TIMER2_DEPARTURE = "timer2-departure"; - public static final String CHARGE_TIMER2_DEPARTURE_HOUR = "timer2-departure-hour"; - public static final String CHARGE_TIMER2_DEPARTURE_MINUTE = "timer2-departure-minute"; - public static final String CHARGE_TIMER2_DAYS = "timer2-days"; - public static final String CHARGE_TIMER2_DAY_MON = "timer2-day-mon"; - public static final String CHARGE_TIMER2_DAY_TUE = "timer2-day-tue"; - public static final String CHARGE_TIMER2_DAY_WED = "timer2-day-wed"; - public static final String CHARGE_TIMER2_DAY_THU = "timer2-day-thu"; - public static final String CHARGE_TIMER2_DAY_FRI = "timer2-day-fri"; - public static final String CHARGE_TIMER2_DAY_SAT = "timer2-day-sat"; - public static final String CHARGE_TIMER2_DAY_SUN = "timer2-day-sun"; - public static final String CHARGE_TIMER2_ENABLED = "timer2-enabled"; - public static final String CHARGE_TIMER3_DEPARTURE = "timer3-departure"; - public static final String CHARGE_TIMER3_DEPARTURE_HOUR = "timer3-departure-hour"; - public static final String CHARGE_TIMER3_DEPARTURE_MINUTE = "timer3-departure-minute"; - public static final String CHARGE_TIMER3_DAYS = "timer3-days"; - public static final String CHARGE_TIMER3_DAY_MON = "timer3-day-mon"; - public static final String CHARGE_TIMER3_DAY_TUE = "timer3-day-tue"; - public static final String CHARGE_TIMER3_DAY_WED = "timer3-day-wed"; - public static final String CHARGE_TIMER3_DAY_THU = "timer3-day-thu"; - public static final String CHARGE_TIMER3_DAY_FRI = "timer3-day-fri"; - public static final String CHARGE_TIMER3_DAY_SAT = "timer3-day-sat"; - public static final String CHARGE_TIMER3_DAY_SUN = "timer3-day-sun"; - public static final String CHARGE_TIMER3_ENABLED = "timer3-enabled"; - public static final String CHARGE_OVERRIDE_DEPARTURE = "override-departure"; - public static final String CHARGE_OVERRIDE_DEPARTURE_HOUR = "override-departure-hour"; - public static final String CHARGE_OVERRIDE_DEPARTURE_MINUTE = "override-departure-minute"; - public static final String CHARGE_OVERRIDE_ENABLED = "override-enabled"; + public static final String CHARGE_TIMER1 = "timer1"; + public static final String CHARGE_TIMER2 = "timer2"; + public static final String CHARGE_TIMER3 = "timer3"; + public static final String CHARGE_OVERRIDE = "override"; + public static final String CHARGE_HOUR = "-hour"; + public static final String CHARGE_MINUTE = "-minute"; + public static final String CHARGE_DEPARTURE = "-departure"; + public static final String CHARGE_ENABLED = "-enabled"; + public static final String CHARGE_DAYS = "-days"; + public static final String CHARGE_DAY_MON = "-day-mon"; + public static final String CHARGE_DAY_TUE = "-day-tue"; + public static final String CHARGE_DAY_WED = "-day-wed"; + public static final String CHARGE_DAY_THU = "-day-thu"; + public static final String CHARGE_DAY_FRI = "-day-fri"; + public static final String CHARGE_DAY_SAT = "-day-sat"; + public static final String CHARGE_DAY_SUN = "-day-sun"; // Range public static final String RANGE_HYBRID = "hybrid"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 17a23ac9f9f83..62a90fb628c4e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -19,6 +19,7 @@ import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.ArrayList; +import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -57,6 +58,7 @@ import org.openhab.core.thing.Thing; import org.openhab.core.thing.binding.BaseThingHandler; import org.openhab.core.types.Command; +import org.openhab.core.types.State; import org.openhab.core.types.StateOption; import org.openhab.core.types.UnDefType; import org.slf4j.Logger; @@ -87,134 +89,43 @@ public class VehicleChannelHandler extends BaseThingHandler { protected BMWConnectedDriveOptionProvider optionProvider; - // Vehicle Status Channels - protected ChannelUID doors; - protected ChannelUID windows; - protected ChannelUID lock; - protected ChannelUID serviceNextDate; - protected ChannelUID serviceNextMileage; - protected ChannelUID checkControl; - protected ChannelUID lastUpdate; - - protected ChannelUID serviceDate; - protected ChannelUID serviceMileage; - protected ChannelUID serviceName; - - protected ChannelUID checkControlMileage; - protected ChannelUID checkControlName; - - protected ChannelUID doorDriverFront; - protected ChannelUID doorDriverRear; - protected ChannelUID doorPassengerFront; - protected ChannelUID doorPassengerRear; - protected ChannelUID doorHood; - protected ChannelUID doorTrunk; - - protected ChannelUID windowDriverFront; - protected ChannelUID windowDriverRear; - protected ChannelUID windowPassengerFront; - protected ChannelUID windowPassengerRear; - protected ChannelUID windowRear; - protected ChannelUID windowSunroof; - - // Range channels - protected ChannelUID mileage; - protected ChannelUID remainingRangeHybrid; - protected ChannelUID remainingRangeElectric; - protected ChannelUID remainingSoc; - protected ChannelUID remainingRangeFuel; - protected ChannelUID remainingFuel; - protected ChannelUID rangeRadiusElectric; - protected ChannelUID rangeRadiusFuel; - protected ChannelUID rangeRadiusHybrid; - - // Lifetime Efficiency Channels - protected ChannelUID lifeTimeAverageConsumption; - protected ChannelUID lifetimeAvgCombinedConsumption; - protected ChannelUID lifeTimeAverageRecuperation; - protected ChannelUID lifeTimeTotalDrivenDistance; - protected ChannelUID lifeTimeSingleLongestDistance; - - // Last Trip Channels - protected ChannelUID tripDateTime; - protected ChannelUID tripDuration; - protected ChannelUID tripDistance; - protected ChannelUID tripDistanceSinceCharging; - protected ChannelUID tripAvgConsumption; - protected ChannelUID tripAvgCombinedConsumption; - protected ChannelUID tripAvgRecuperation; - - // Location Channels - protected ChannelUID gpsLocation; - protected ChannelUID heading; - - // Remote Services - protected ChannelUID remoteCommandChannel; - protected ChannelUID remoteStateChannel; - - // Remote Services - protected ChannelUID destinationName; - protected ChannelUID destinationLocation; - // Charging - protected ChannelUID chargingStatus; - protected ChannelUID chargingTimeRemaining; - protected ChannelUID chargeProfileClimate; - protected ChannelUID chargeProfileChargeMode; - protected ChannelUID chargeProfilePreference; - protected Map timedChannels = new HashMap<>(); - - private class TimedChannels { - TimedChannels(final ChannelUID time, final ChannelUID hour, final ChannelUID minute) { + protected static class TimedChannel { + TimedChannel(final String time, final String timer, final boolean hasDays) { this.time = time; - this.hour = hour; - this.minute = minute; + this.timer = timer; + this.hasDays = hasDays; } - final ChannelUID time; - final ChannelUID hour; - final ChannelUID minute; + final String time; + final String timer; + final boolean hasDays; } - private class TimerChannels extends TimedChannels { - TimerChannels(final ChannelUID time, final ChannelUID hour, final ChannelUID minute, final ChannelUID enabled) { - super(time, hour, minute); - this.enabled = enabled; + @SuppressWarnings("serial") + protected static final Map timedChannels = new HashMap<>() { + { + put(ProfileKey.WINDOWSTART, new TimedChannel(CHARGE_WINDOW_START, null, false)); + put(ProfileKey.WINDOWEND, new TimedChannel(CHARGE_WINDOW_END, null, false)); + put(ProfileKey.TIMER1, new TimedChannel(CHARGE_TIMER1 + CHARGE_DEPARTURE, CHARGE_TIMER1, true)); + put(ProfileKey.TIMER2, new TimedChannel(CHARGE_TIMER2 + CHARGE_DEPARTURE, CHARGE_TIMER2, true)); + put(ProfileKey.TIMER3, new TimedChannel(CHARGE_TIMER3 + CHARGE_DEPARTURE, CHARGE_TIMER3, true)); + put(ProfileKey.OVERRIDE, new TimedChannel(CHARGE_OVERRIDE + CHARGE_DEPARTURE, CHARGE_OVERRIDE, false)); } - - final ChannelUID enabled; - } - - private class TimerDaysChannels extends TimerChannels { - TimerDaysChannels(final ChannelUID time, final ChannelUID hour, final ChannelUID minute, - final ChannelUID enabled, final ChannelUID days, final ChannelUID mon, final ChannelUID tue, - final ChannelUID wed, final ChannelUID thu, final ChannelUID fri, final ChannelUID sat, - final ChannelUID sun) { - super(time, hour, minute, enabled); - this.days = days; - this.mon = mon; - this.tue = tue; - this.wed = wed; - this.thu = thu; - this.fri = fri; - this.sat = sat; - this.sun = sun; + }; + + @SuppressWarnings("serial") + protected static final Map dayChannels = new HashMap<>() { + { + put(DayOfWeek.MONDAY, CHARGE_DAY_MON); + put(DayOfWeek.TUESDAY, CHARGE_DAY_TUE); + put(DayOfWeek.WEDNESDAY, CHARGE_DAY_WED); + put(DayOfWeek.THURSDAY, CHARGE_DAY_THU); + put(DayOfWeek.FRIDAY, CHARGE_DAY_FRI); + put(DayOfWeek.SATURDAY, CHARGE_DAY_SAT); + put(DayOfWeek.SUNDAY, CHARGE_DAY_SUN); } - - final ChannelUID days; - final ChannelUID mon; - final ChannelUID tue; - final ChannelUID wed; - final ChannelUID thu; - final ChannelUID fri; - final ChannelUID sat; - final ChannelUID sun; - } - - // Image - protected ChannelUID imageChannel; - protected ChannelUID imageViewportChannel; - protected ChannelUID imageSizeChannel; + }; // Data Caches protected Optional vehicleStatusCache = Optional.empty(); @@ -235,137 +146,6 @@ public VehicleChannelHandler(Thing thing, BMWConnectedDriveOptionProvider op, St isElectric = type.equals(VehicleType.PLUGIN_HYBRID.toString()) || type.equals(VehicleType.ELECTRIC_REX.toString()) || type.equals(VehicleType.ELECTRIC.toString()); isHybrid = hasFuel && isElectric; - - // Vehicle Status channels - doors = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, DOORS); - windows = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, WINDOWS); - lock = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, LOCK); - serviceNextDate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, SERVICE_DATE); - serviceNextMileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, SERVICE_MILEAGE); - checkControl = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, CHECK_CONTROL); - chargingStatus = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, CHARGE_STATUS); - chargingTimeRemaining = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, CHARGE_REMAINING); - lastUpdate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_STATUS, LAST_UPDATE); - - serviceDate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, DATE); - serviceMileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, MILEAGE); - serviceName = new ChannelUID(thing.getUID(), CHANNEL_GROUP_SERVICE, NAME); - - checkControlMileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHECK_CONTROL, MILEAGE); - checkControlName = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHECK_CONTROL, NAME); - - doorDriverFront = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, DOOR_DRIVER_FRONT); - doorDriverRear = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, DOOR_DRIVER_REAR); - doorPassengerFront = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, DOOR_PASSENGER_FRONT); - doorPassengerRear = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, DOOR_PASSENGER_REAR); - doorHood = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, HOOD); - doorTrunk = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, TRUNK); - - windowDriverFront = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, WINDOW_DOOR_DRIVER_FORNT); - windowDriverRear = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, WINDOW_DOOR_DRIVER_REAR); - windowPassengerFront = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, WINDOW_DOOR_PASSENGER_FRONT); - windowPassengerRear = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, WINDOW_DOOR_PASSENGER_REAR); - windowRear = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, WINDOW_REAR); - windowSunroof = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DOORS, SUNROOF); - - // range Channels - mileage = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, MILEAGE); - remainingRangeHybrid = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, RANGE_HYBRID); - remainingRangeElectric = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, RANGE_ELECTRIC); - remainingRangeFuel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, RANGE_FUEL); - remainingSoc = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, SOC); - remainingFuel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, REMAINING_FUEL); - rangeRadiusElectric = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, RANGE_RADIUS_ELECTRIC); - rangeRadiusFuel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, RANGE_RADIUS_FUEL); - rangeRadiusHybrid = new ChannelUID(thing.getUID(), CHANNEL_GROUP_RANGE, RANGE_RADIUS_HYBRID); - - // Last Trip Channels - tripDateTime = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, DATE); - tripDuration = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, DURATION); - tripDistance = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, DISTANCE); - tripDistanceSinceCharging = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, DISTANCE_SINCE_CHARGING); - tripAvgConsumption = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, AVG_CONSUMPTION); - tripAvgCombinedConsumption = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, AVG_COMBINED_CONSUMPTION); - tripAvgRecuperation = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LAST_TRIP, AVG_RECUPERATION); - - // Lifetime Channels - lifeTimeAverageConsumption = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, AVG_CONSUMPTION); - lifetimeAvgCombinedConsumption = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, - AVG_COMBINED_CONSUMPTION); - lifeTimeAverageRecuperation = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, AVG_RECUPERATION); - lifeTimeTotalDrivenDistance = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, TOTAL_DRIVEN_DISTANCE); - lifeTimeSingleLongestDistance = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LIFETIME, SINGLE_LONGEST_DISTANCE); - - // Location Channels - gpsLocation = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, GPS); - heading = new ChannelUID(thing.getUID(), CHANNEL_GROUP_LOCATION, HEADING); - - // Charge Channels - chargeProfileClimate = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_PROFILE_CLIMATE); - chargeProfileChargeMode = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_PROFILE_MODE); - chargeProfilePreference = new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_PROFILE_PREFERENCE); - timedChannels.put(ProfileKey.WINDOWSTART, - new TimedChannels(new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_WINDOW_START), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_WINDOW_START_HOUR), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_WINDOW_START_MINUTE))); - timedChannels.put(ProfileKey.WINDOWEND, - new TimedChannels(new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_WINDOW_END), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_WINDOW_END_HOUR), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_WINDOW_END_MINUTE))); - timedChannels.put(ProfileKey.TIMER1, - new TimerDaysChannels(new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DEPARTURE), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DEPARTURE_HOUR), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DEPARTURE_MINUTE), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_ENABLED), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DAYS), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DAY_MON), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DAY_TUE), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DAY_WED), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DAY_THU), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DAY_FRI), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DAY_SAT), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER1_DAY_SUN))); - timedChannels.put(ProfileKey.TIMER2, - new TimerDaysChannels(new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DEPARTURE), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DEPARTURE_HOUR), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DEPARTURE_MINUTE), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_ENABLED), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DAYS), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DAY_MON), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DAY_TUE), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DAY_WED), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DAY_THU), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DAY_FRI), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DAY_SAT), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER2_DAY_SUN))); - timedChannels.put(ProfileKey.TIMER3, - new TimerDaysChannels(new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DEPARTURE), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DEPARTURE_HOUR), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DEPARTURE_MINUTE), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_ENABLED), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAYS), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAY_MON), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAY_TUE), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAY_WED), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAY_THU), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAY_FRI), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAY_SAT), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_TIMER3_DAY_SUN))); - timedChannels.put(ProfileKey.OVERRIDE, - new TimerChannels(new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_OVERRIDE_DEPARTURE), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_OVERRIDE_DEPARTURE_HOUR), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_OVERRIDE_DEPARTURE_MINUTE), - new ChannelUID(thing.getUID(), CHANNEL_GROUP_CHARGE, CHARGE_OVERRIDE_ENABLED))); - - remoteCommandChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_COMMAND); - remoteStateChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_REMOTE, REMOTE_STATE); - - destinationName = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, NAME); - destinationLocation = new ChannelUID(thing.getUID(), CHANNEL_GROUP_DESTINATION, GPS); - - imageChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_FORMAT); - imageViewportChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_VIEWPORT); - imageSizeChannel = new ChannelUID(thing.getUID(), CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_SIZE); } @Override @@ -376,6 +156,14 @@ public void handleCommand(ChannelUID channelUID, Command command) { public void initialize() { } + private void setOptions(final String group, final String id, List options) { + optionProvider.setStateOptions(new ChannelUID(thing.getUID(), group, id), options); + } + + protected void updateChannel(final String group, final String id, final State state) { + updateState(new ChannelUID(thing.getUID(), group, id), state); + } + protected void updateCheckControls(List ccl) { if (ccl.size() == 0) { // No Check Control available - show not active @@ -401,8 +189,8 @@ protected void updateCheckControls(List ccl) { } index++; } - setOptions(checkControlName, ccmDescriptionOptions); - setOptions(checkControlMileage, ccmMileageOptions); + setOptions(CHANNEL_GROUP_CHECK_CONTROL, NAME, ccmDescriptionOptions); + setOptions(CHANNEL_GROUP_CHECK_CONTROL, MILEAGE, ccmMileageOptions); // if current selected item isn't anymore in the list select first entry if (!isSelectedElementIn) { @@ -414,15 +202,10 @@ protected void selectCheckControl(int index) { if (index >= 0 && index < checkControlList.size()) { CCMMessage ccEntry = checkControlList.get(index); selectedCC = ccEntry.ccmDescriptionShort; - updateState(checkControlName, StringType.valueOf(ccEntry.ccmDescriptionShort)); - QuantityType qtLength = QuantityType.valueOf(Converter.round(ccEntry.ccmMileage), - MetricPrefix.KILO(SIUnits.METRE)); - if (imperial) { - updateState(checkControlMileage, - QuantityType.valueOf(Converter.round(ccEntry.ccmMileage), ImperialUnits.MILE)); - } else { - updateState(checkControlMileage, qtLength); - } + updateChannel(CHANNEL_GROUP_CHECK_CONTROL, NAME, StringType.valueOf(ccEntry.ccmDescriptionShort)); + updateChannel(CHANNEL_GROUP_CHECK_CONTROL, MILEAGE, + QuantityType.valueOf(Converter.round(ccEntry.ccmMileage), + imperial ? ImperialUnits.MILE : MetricPrefix.KILO(SIUnits.METRE))); } } @@ -452,9 +235,9 @@ protected void updateServices(List sl) { } index++; } - setOptions(serviceName, serviceNameOptions); - setOptions(serviceDate, serviceDateOptions); - setOptions(serviceMileage, serviceMileageOptions); + setOptions(CHANNEL_GROUP_SERVICE, NAME, serviceNameOptions); + setOptions(CHANNEL_GROUP_SERVICE, DATE, serviceDateOptions); + setOptions(CHANNEL_GROUP_SERVICE, MILEAGE, serviceMileageOptions); // if current selected item isn't anymore in the list select first entry if (!isSelectedElementIn) { @@ -466,15 +249,13 @@ protected void selectService(int index) { if (index >= 0 && index < serviceList.size()) { CBSMessage serviceEntry = serviceList.get(index); selectedService = serviceEntry.cbsType; - updateState(serviceName, StringType.valueOf(Converter.toTitleCase(serviceEntry.getType()))); - updateState(serviceDate, DateTimeType.valueOf(Converter.getLocalDateTime(serviceEntry.getDueDate()))); - if (imperial) { - updateState(serviceMileage, - QuantityType.valueOf(Converter.round(serviceEntry.cbsRemainingMileage), ImperialUnits.MILE)); - } else { - updateState(serviceMileage, QuantityType.valueOf(Converter.round(serviceEntry.cbsRemainingMileage), - MetricPrefix.KILO(SIUnits.METRE))); - } + updateChannel(CHANNEL_GROUP_SERVICE, NAME, + StringType.valueOf(Converter.toTitleCase(serviceEntry.getType()))); + updateChannel(CHANNEL_GROUP_SERVICE, DATE, + DateTimeType.valueOf(Converter.getLocalDateTime(serviceEntry.getDueDate()))); + updateChannel(CHANNEL_GROUP_SERVICE, MILEAGE, + QuantityType.valueOf(Converter.round(serviceEntry.cbsRemainingMileage), + imperial ? ImperialUnits.MILE : MetricPrefix.KILO(SIUnits.METRE))); } } @@ -502,8 +283,8 @@ protected void updateDestinations(List dl) { } index++; } - setOptions(destinationName, destinationNameOptions); - setOptions(destinationLocation, destinationGPSOptions); + setOptions(CHANNEL_GROUP_DESTINATION, NAME, destinationNameOptions); + setOptions(CHANNEL_GROUP_DESTINATION, GPS, destinationGPSOptions); // if current selected item isn't anymore in the list select first entry if (!isSelectedElementIn) { @@ -517,15 +298,11 @@ protected void selectDestination(int index) { // update selected Item selectedDestination = destinationEntry.getAddress(); // update coordinates according to new set location - updateState(destinationName, StringType.valueOf(destinationEntry.getAddress())); - updateState(destinationLocation, PointType.valueOf(destinationEntry.getCoordinates())); + updateChannel(CHANNEL_GROUP_DESTINATION, NAME, StringType.valueOf(destinationEntry.getAddress())); + updateChannel(CHANNEL_GROUP_DESTINATION, GPS, PointType.valueOf(destinationEntry.getCoordinates())); } } - private void setOptions(ChannelUID cuid, List options) { - optionProvider.setStateOptions(cuid, options); - } - protected void updateAllTrips(AllTrips allTrips) { QuantityType qtTotalElectric = QuantityType .valueOf(Converter.round(allTrips.totalElectricDistance.userTotal), MetricPrefix.KILO(SIUnits.METRE)); @@ -533,54 +310,55 @@ protected void updateAllTrips(AllTrips allTrips) { .valueOf(Converter.round(allTrips.chargecycleRange.userHigh), MetricPrefix.KILO(SIUnits.METRE)); QuantityType qtDistanceSinceCharge = QuantityType.valueOf( Converter.round(allTrips.chargecycleRange.userCurrentChargeCycle), MetricPrefix.KILO(SIUnits.METRE)); - double avgConsumotion = allTrips.avgElectricConsumption.userAverage; - double avgCombinedConsumption = allTrips.avgCombinedConsumption.userAverage; - double avgRecuperation = allTrips.avgRecuperation.userAverage; - if (imperial) { - updateState(lifeTimeTotalDrivenDistance, Converter.getMiles(qtTotalElectric)); - updateState(lifeTimeSingleLongestDistance, Converter.getMiles(qtLongestElectricRange)); - updateState(tripDistanceSinceCharging, Converter.getMiles(qtDistanceSinceCharge)); - - // Conversion from kwh/100km to kwh/10mi has to be done manually - avgConsumotion *= Converter.MILES_TO_KM_RATIO; - avgCombinedConsumption *= Converter.MILES_TO_KM_RATIO; - avgRecuperation *= Converter.MILES_TO_KM_RATIO; - } else { - updateState(lifeTimeTotalDrivenDistance, qtTotalElectric); - updateState(lifeTimeSingleLongestDistance, qtLongestElectricRange); - updateState(tripDistanceSinceCharging, qtDistanceSinceCharge); - } - updateState(lifeTimeAverageConsumption, + + updateChannel(CHANNEL_GROUP_LIFETIME, TOTAL_DRIVEN_DISTANCE, + imperial ? Converter.getMiles(qtTotalElectric) : qtTotalElectric); + updateChannel(CHANNEL_GROUP_LIFETIME, SINGLE_LONGEST_DISTANCE, + imperial ? Converter.getMiles(qtLongestElectricRange) : qtLongestElectricRange); + updateChannel(CHANNEL_GROUP_LAST_TRIP, DISTANCE_SINCE_CHARGING, + imperial ? Converter.getMiles(qtDistanceSinceCharge) : qtDistanceSinceCharge); + + // Conversion from kwh/100km to kwh/10mi has to be done manually + double avgConsumotion = imperial ? allTrips.avgElectricConsumption.userAverage * Converter.MILES_TO_KM_RATIO + : allTrips.avgElectricConsumption.userAverage; + double avgCombinedConsumption = imperial + ? allTrips.avgCombinedConsumption.userAverage * Converter.MILES_TO_KM_RATIO + : allTrips.avgCombinedConsumption.userAverage; + double avgRecuperation = imperial ? allTrips.avgRecuperation.userAverage * Converter.MILES_TO_KM_RATIO + : allTrips.avgRecuperation.userAverage; + + updateChannel(CHANNEL_GROUP_LIFETIME, AVG_CONSUMPTION, QuantityType.valueOf(Converter.round(avgConsumotion), Units.KILOWATT_HOUR)); - updateState(lifetimeAvgCombinedConsumption, + updateChannel(CHANNEL_GROUP_LIFETIME, AVG_COMBINED_CONSUMPTION, QuantityType.valueOf(Converter.round(avgCombinedConsumption), Units.LITRE)); - updateState(lifeTimeAverageRecuperation, + updateChannel(CHANNEL_GROUP_LIFETIME, AVG_RECUPERATION, QuantityType.valueOf(Converter.round(avgRecuperation), Units.KILOWATT_HOUR)); } protected void updateLastTrip(LastTrip trip) { // Whyever the Last Trip DateTime is delivered without offest - so LocalTime - updateState(tripDateTime, DateTimeType.valueOf(Converter.getLocalDateTimeWithoutOffest(trip.date))); - updateState(tripDuration, QuantityType.valueOf(trip.duration, Units.MINUTE)); + updateChannel(CHANNEL_GROUP_LAST_TRIP, DATE, + DateTimeType.valueOf(Converter.getLocalDateTimeWithoutOffest(trip.date))); + updateChannel(CHANNEL_GROUP_LAST_TRIP, DURATION, QuantityType.valueOf(trip.duration, Units.MINUTE)); + QuantityType qtTotalDistance = QuantityType.valueOf(Converter.round(trip.totalDistance), MetricPrefix.KILO(SIUnits.METRE)); - double avgConsumtption = trip.avgElectricConsumption; - double avgCombinedConsumption = trip.avgCombinedConsumption; - double avgRecuperation = trip.avgRecuperation; - if (imperial) { - updateState(tripDistance, Converter.getMiles(qtTotalDistance)); - - // Conversion from kwh/100km to kwh/10mi has to be done manually - avgConsumtption *= Converter.MILES_TO_KM_RATIO; - avgCombinedConsumption *= Converter.MILES_TO_KM_RATIO; - avgRecuperation *= Converter.MILES_TO_KM_RATIO; - } else { - updateState(tripDistance, qtTotalDistance); - } - updateState(tripAvgConsumption, QuantityType.valueOf(Converter.round(avgConsumtption), Units.KILOWATT_HOUR)); - updateState(tripAvgCombinedConsumption, + updateChannel(CHANNEL_GROUP_LAST_TRIP, DISTANCE, + imperial ? Converter.getMiles(qtTotalDistance) : qtTotalDistance); + + // Conversion from kwh/100km to kwh/10mi has to be done manually + double avgConsumtption = imperial ? trip.avgElectricConsumption * Converter.MILES_TO_KM_RATIO + : trip.avgElectricConsumption; + double avgCombinedConsumption = imperial ? trip.avgCombinedConsumption * Converter.MILES_TO_KM_RATIO + : trip.avgCombinedConsumption; + double avgRecuperation = imperial ? trip.avgRecuperation * Converter.MILES_TO_KM_RATIO : trip.avgRecuperation; + + updateChannel(CHANNEL_GROUP_LAST_TRIP, AVG_CONSUMPTION, + QuantityType.valueOf(Converter.round(avgConsumtption), Units.KILOWATT_HOUR)); + updateChannel(CHANNEL_GROUP_LAST_TRIP, AVG_COMBINED_CONSUMPTION, QuantityType.valueOf(Converter.round(avgCombinedConsumption), Units.LITRE)); - updateState(tripAvgRecuperation, QuantityType.valueOf(Converter.round(avgRecuperation), Units.KILOWATT_HOUR)); + updateChannel(CHANNEL_GROUP_LAST_TRIP, AVG_RECUPERATION, + QuantityType.valueOf(Converter.round(avgRecuperation), Units.KILOWATT_HOUR)); } protected void updateChargeProfileFromContent(String content) { @@ -588,10 +366,13 @@ protected void updateChargeProfileFromContent(String content) { } protected void updateChargeProfile(ChargeProfileWrapper wrapper) { - updateState(chargeProfilePreference, StringType.valueOf(Converter.toTitleCase(wrapper.getPreference()))); - updateState(chargeProfileChargeMode, StringType.valueOf(Converter.toTitleCase(wrapper.getMode()))); + updateChannel(CHANNEL_GROUP_CHARGE, CHARGE_PROFILE_PREFERENCE, + StringType.valueOf(Converter.toTitleCase(wrapper.getPreference()))); + updateChannel(CHANNEL_GROUP_CHARGE, CHARGE_PROFILE_MODE, + StringType.valueOf(Converter.toTitleCase(wrapper.getMode()))); final Boolean climate = wrapper.isEnabled(ProfileKey.CLIMATE); - updateState(chargeProfileClimate, climate == null ? UnDefType.UNDEF : OnOffType.from(climate)); + updateChannel(CHANNEL_GROUP_CHARGE, CHARGE_PROFILE_CLIMATE, + climate == null ? UnDefType.UNDEF : OnOffType.from(climate)); updateTimedState(wrapper, ProfileKey.WINDOWSTART); updateTimedState(wrapper, ProfileKey.WINDOWEND); updateTimedState(wrapper, ProfileKey.TIMER1); @@ -601,93 +382,91 @@ protected void updateChargeProfile(ChargeProfileWrapper wrapper) { } protected void updateTimedState(ChargeProfileWrapper profile, ProfileKey key) { - final TimedChannels channels = timedChannels.get(key); - if (channels != null) { + final TimedChannel timed = timedChannels.get(key); + if (timed != null) { final LocalTime time = profile.getTime(key); - updateState(channels.time, time == null ? UnDefType.UNDEF + updateChannel(CHANNEL_GROUP_CHARGE, timed.time, time == null ? UnDefType.UNDEF : new DateTimeType(ZonedDateTime.of(Constants.EPOCH_DAY, time, ZoneId.systemDefault()))); - updateState(channels.hour, time == null ? UnDefType.UNDEF : new DecimalType(time.getHour())); - updateState(channels.minute, time == null ? UnDefType.UNDEF : new DecimalType(time.getMinute())); - if (channels instanceof TimerChannels) { + updateChannel(CHANNEL_GROUP_CHARGE, timed.time + CHARGE_HOUR, + time == null ? UnDefType.UNDEF : new DecimalType(time.getHour())); + updateChannel(CHANNEL_GROUP_CHARGE, timed.time + CHARGE_MINUTE, + time == null ? UnDefType.UNDEF : new DecimalType(time.getMinute())); + if (timed.timer != null) { final Boolean enabled = profile.isEnabled(key); - updateState(((TimerChannels) channels).enabled, + updateChannel(CHANNEL_GROUP_CHARGE, timed.timer + CHARGE_ENABLED, enabled == null ? UnDefType.UNDEF : OnOffType.from(enabled)); - if (channels instanceof TimerDaysChannels) { + if (timed.hasDays) { final Set days = profile.getDays(key); - updateState(((TimerDaysChannels) channels).days, + updateChannel(CHANNEL_GROUP_CHARGE, timed.timer + CHARGE_DAYS, days == null ? UnDefType.UNDEF : StringType.valueOf(ChargeProfileUtils.formatDays(days))); - updateState(((TimerDaysChannels) channels).mon, - days == null ? UnDefType.UNDEF : OnOffType.from(days.contains(DayOfWeek.MONDAY))); - updateState(((TimerDaysChannels) channels).tue, - days == null ? UnDefType.UNDEF : OnOffType.from(days.contains(DayOfWeek.TUESDAY))); - updateState(((TimerDaysChannels) channels).wed, - days == null ? UnDefType.UNDEF : OnOffType.from(days.contains(DayOfWeek.WEDNESDAY))); - updateState(((TimerDaysChannels) channels).thu, - days == null ? UnDefType.UNDEF : OnOffType.from(days.contains(DayOfWeek.THURSDAY))); - updateState(((TimerDaysChannels) channels).fri, - days == null ? UnDefType.UNDEF : OnOffType.from(days.contains(DayOfWeek.FRIDAY))); - updateState(((TimerDaysChannels) channels).sat, - days == null ? UnDefType.UNDEF : OnOffType.from(days.contains(DayOfWeek.SATURDAY))); - updateState(((TimerDaysChannels) channels).sun, - days == null ? UnDefType.UNDEF : OnOffType.from(days.contains(DayOfWeek.SUNDAY))); + EnumSet.allOf(DayOfWeek.class).forEach(day -> { + updateChannel(CHANNEL_GROUP_CHARGE, timed.timer + dayChannels.get(day), + days == null ? UnDefType.UNDEF : OnOffType.from(days.contains(day))); + }); } } } } protected void updateDoors(Doors doorState) { - updateState(doorDriverFront, StringType.valueOf(Converter.toTitleCase(doorState.doorDriverFront))); - updateState(doorDriverRear, StringType.valueOf(Converter.toTitleCase(doorState.doorDriverRear))); - updateState(doorPassengerFront, StringType.valueOf(Converter.toTitleCase(doorState.doorPassengerFront))); - updateState(doorPassengerRear, StringType.valueOf(Converter.toTitleCase(doorState.doorPassengerRear))); - updateState(doorTrunk, StringType.valueOf(Converter.toTitleCase(doorState.trunk))); - updateState(doorHood, StringType.valueOf(Converter.toTitleCase(doorState.hood))); + updateChannel(CHANNEL_GROUP_DOORS, DOOR_DRIVER_FRONT, + StringType.valueOf(Converter.toTitleCase(doorState.doorDriverFront))); + updateChannel(CHANNEL_GROUP_DOORS, DOOR_DRIVER_REAR, + StringType.valueOf(Converter.toTitleCase(doorState.doorDriverRear))); + updateChannel(CHANNEL_GROUP_DOORS, DOOR_PASSENGER_FRONT, + StringType.valueOf(Converter.toTitleCase(doorState.doorPassengerFront))); + updateChannel(CHANNEL_GROUP_DOORS, DOOR_PASSENGER_REAR, + StringType.valueOf(Converter.toTitleCase(doorState.doorPassengerRear))); + updateChannel(CHANNEL_GROUP_DOORS, TRUNK, StringType.valueOf(Converter.toTitleCase(doorState.trunk))); + updateChannel(CHANNEL_GROUP_DOORS, HOOD, StringType.valueOf(Converter.toTitleCase(doorState.hood))); } protected void updateWindows(Windows windowState) { - updateState(windowDriverFront, StringType.valueOf(Converter.toTitleCase(windowState.windowDriverFront))); - updateState(windowDriverRear, StringType.valueOf(Converter.toTitleCase(windowState.windowDriverRear))); - updateState(windowPassengerFront, StringType.valueOf(Converter.toTitleCase(windowState.windowPassengerFront))); - updateState(windowPassengerRear, StringType.valueOf(Converter.toTitleCase(windowState.windowPassengerRear))); - updateState(windowRear, StringType.valueOf(Converter.toTitleCase(windowState.rearWindow))); - updateState(windowSunroof, StringType.valueOf(Converter.toTitleCase(windowState.sunroof))); + updateChannel(CHANNEL_GROUP_DOORS, WINDOW_DOOR_DRIVER_FRONT, + StringType.valueOf(Converter.toTitleCase(windowState.windowDriverFront))); + updateChannel(CHANNEL_GROUP_DOORS, WINDOW_DOOR_DRIVER_REAR, + StringType.valueOf(Converter.toTitleCase(windowState.windowDriverRear))); + updateChannel(CHANNEL_GROUP_DOORS, WINDOW_DOOR_PASSENGER_FRONT, + StringType.valueOf(Converter.toTitleCase(windowState.windowPassengerFront))); + updateChannel(CHANNEL_GROUP_DOORS, WINDOW_DOOR_PASSENGER_REAR, + StringType.valueOf(Converter.toTitleCase(windowState.windowPassengerRear))); + updateChannel(CHANNEL_GROUP_DOORS, WINDOW_REAR, + StringType.valueOf(Converter.toTitleCase(windowState.rearWindow))); + updateChannel(CHANNEL_GROUP_DOORS, SUNROOF, StringType.valueOf(Converter.toTitleCase(windowState.sunroof))); } protected void updatePosition(Position pos) { - updateState(gpsLocation, PointType.valueOf(pos.getCoordinates())); - updateState(heading, QuantityType.valueOf(pos.heading, Units.DEGREE_ANGLE)); + updateChannel(CHANNEL_GROUP_LOCATION, GPS, PointType.valueOf(pos.getCoordinates())); + updateChannel(CHANNEL_GROUP_LOCATION, HEADING, QuantityType.valueOf(pos.heading, Units.DEGREE_ANGLE)); } protected void updateVehicleStatus(VehicleStatus vStatus) { // Vehicle Status - updateState(lock, StringType.valueOf(Converter.toTitleCase(vStatus.doorLockState))); + updateChannel(CHANNEL_GROUP_STATUS, LOCK, StringType.valueOf(Converter.toTitleCase(vStatus.doorLockState))); // Service Updates - String nextServiceDate = VehicleStatusUtils.getNextServiceDate(vStatus); - updateState(serviceNextDate, DateTimeType.valueOf(Converter.getLocalDateTime(nextServiceDate))); - double nextServiceMileage = VehicleStatusUtils.getNextServiceMileage(vStatus); - if (imperial) { - updateState(serviceNextMileage, - QuantityType.valueOf(Converter.round(nextServiceMileage), ImperialUnits.MILE)); - } else { - updateState(serviceNextMileage, - QuantityType.valueOf(Converter.round(nextServiceMileage), MetricPrefix.KILO(SIUnits.METRE))); - } + updateChannel(CHANNEL_GROUP_STATUS, SERVICE_DATE, + DateTimeType.valueOf(Converter.getLocalDateTime(VehicleStatusUtils.getNextServiceDate(vStatus)))); + + updateChannel(CHANNEL_GROUP_STATUS, SERVICE_MILEAGE, + QuantityType.valueOf(Converter.round(VehicleStatusUtils.getNextServiceMileage(vStatus)), + imperial ? ImperialUnits.MILE : MetricPrefix.KILO(SIUnits.METRE))); // CheckControl Active? - updateState(checkControl, + updateChannel(CHANNEL_GROUP_STATUS, CHECK_CONTROL, StringType.valueOf(Converter.toTitleCase(VehicleStatusUtils.checkControlActive(vStatus)))); // last update Time - updateState(lastUpdate, + updateChannel(CHANNEL_GROUP_STATUS, LAST_UPDATE, DateTimeType.valueOf(Converter.getLocalDateTime(VehicleStatusUtils.getUpdateTime(vStatus)))); Doors doorState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Doors.class); Windows windowState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Windows.class); if (doorState != null) { - updateState(doors, StringType.valueOf(VehicleStatusUtils.checkClosed(doorState))); + updateChannel(CHANNEL_GROUP_STATUS, DOORS, StringType.valueOf(VehicleStatusUtils.checkClosed(doorState))); updateDoors(doorState); } if (windowState != null) { - updateState(windows, StringType.valueOf(VehicleStatusUtils.checkClosed(windowState))); + updateChannel(CHANNEL_GROUP_STATUS, WINDOWS, + StringType.valueOf(VehicleStatusUtils.checkClosed(windowState))); updateWindows(windowState); } @@ -700,75 +479,66 @@ protected void updateVehicleStatus(VehicleStatus vStatus) { MetricPrefix.KILO(SIUnits.METRE)); QuantityType qtElectricRadius = QuantityType.valueOf( Converter.guessRangeRadius(vStatus.remainingRangeElectric), MetricPrefix.KILO(SIUnits.METRE)); - if (imperial) { - updateState(remainingRangeElectric, Converter.getMiles(qtElectricRange)); - updateState(rangeRadiusElectric, Converter.getMiles(qtElectricRadius)); - } else { - updateState(remainingRangeElectric, qtElectricRange); - updateState(rangeRadiusElectric, qtElectricRadius); - } + + updateChannel(CHANNEL_GROUP_RANGE, RANGE_ELECTRIC, + imperial ? Converter.getMiles(qtElectricRange) : qtElectricRange); + updateChannel(CHANNEL_GROUP_RANGE, RANGE_RADIUS_ELECTRIC, + imperial ? Converter.getMiles(qtElectricRadius) : qtElectricRadius); } if (hasFuel) { totalRange += vStatus.remainingRangeFuel; - QuantityType qtFuealRange = QuantityType.valueOf(vStatus.remainingRangeFuel, + QuantityType qtFuelRange = QuantityType.valueOf(vStatus.remainingRangeFuel, MetricPrefix.KILO(SIUnits.METRE)); QuantityType qtFuelRadius = QuantityType .valueOf(Converter.guessRangeRadius(vStatus.remainingRangeFuel), MetricPrefix.KILO(SIUnits.METRE)); - if (imperial) { - updateState(remainingRangeFuel, Converter.getMiles(qtFuealRange)); - updateState(rangeRadiusFuel, Converter.getMiles(qtFuelRadius)); - } else { - updateState(remainingRangeFuel, qtFuealRange); - updateState(rangeRadiusFuel, qtFuelRadius); - } + + updateChannel(CHANNEL_GROUP_RANGE, RANGE_FUEL, imperial ? Converter.getMiles(qtFuelRange) : qtFuelRange); + updateChannel(CHANNEL_GROUP_RANGE, RANGE_RADIUS_FUEL, + imperial ? Converter.getMiles(qtFuelRadius) : qtFuelRadius); } if (isHybrid) { QuantityType qtHybridRange = QuantityType.valueOf(totalRange, MetricPrefix.KILO(SIUnits.METRE)); QuantityType qtHybridRadius = QuantityType.valueOf(Converter.guessRangeRadius(totalRange), MetricPrefix.KILO(SIUnits.METRE)); - if (imperial) { - updateState(remainingRangeHybrid, Converter.getMiles(qtHybridRange)); - updateState(rangeRadiusHybrid, Converter.getMiles(qtHybridRadius)); - } else { - updateState(remainingRangeHybrid, qtHybridRange); - updateState(rangeRadiusHybrid, qtHybridRadius); - } + updateChannel(CHANNEL_GROUP_RANGE, RANGE_HYBRID, + imperial ? Converter.getMiles(qtHybridRange) : qtHybridRange); + updateChannel(CHANNEL_GROUP_RANGE, RANGE_RADIUS_HYBRID, + imperial ? Converter.getMiles(qtHybridRadius) : qtHybridRadius); } - if (imperial) { - updateState(mileage, QuantityType.valueOf(vStatus.mileage, ImperialUnits.MILE)); - } else { - updateState(mileage, QuantityType.valueOf(vStatus.mileage, MetricPrefix.KILO(SIUnits.METRE))); - } + updateChannel(CHANNEL_GROUP_RANGE, MILEAGE, QuantityType.valueOf(vStatus.mileage, + imperial ? ImperialUnits.MILE : MetricPrefix.KILO(SIUnits.METRE))); if (isElectric) { - updateState(remainingSoc, QuantityType.valueOf(vStatus.chargingLevelHv, Units.PERCENT)); + updateChannel(CHANNEL_GROUP_RANGE, SOC, QuantityType.valueOf(vStatus.chargingLevelHv, Units.PERCENT)); } if (hasFuel) { - updateState(remainingFuel, QuantityType.valueOf(vStatus.remainingFuel, Units.LITRE)); + updateChannel(CHANNEL_GROUP_RANGE, REMAINING_FUEL, + QuantityType.valueOf(vStatus.remainingFuel, Units.LITRE)); } // Charge Values if (isElectric) { if (vStatus.chargingStatus != null) { if (Constants.INVALID.equals(vStatus.chargingStatus)) { - updateState(chargingStatus, + updateChannel(CHANNEL_GROUP_STATUS, CHARGE_STATUS, StringType.valueOf(Converter.toTitleCase(vStatus.lastChargingEndReason))); } else { // State INVALID is somehow misleading. Instead show the Last Charging End Reason - updateState(chargingStatus, StringType.valueOf(Converter.toTitleCase(vStatus.chargingStatus))); + updateChannel(CHANNEL_GROUP_STATUS, CHARGE_STATUS, + StringType.valueOf(Converter.toTitleCase(vStatus.chargingStatus))); } } else { - updateState(chargingStatus, UnDefType.NULL); + updateChannel(CHANNEL_GROUP_STATUS, CHARGE_STATUS, UnDefType.NULL); } if (vStatus.chargingTimeRemaining != null) { try { - updateState(chargingTimeRemaining, + updateChannel(CHANNEL_GROUP_STATUS, CHARGE_REMAINING, QuantityType.valueOf(vStatus.chargingTimeRemaining, Units.MINUTE)); } catch (NumberFormatException nfe) { - updateState(chargingTimeRemaining, UnDefType.UNDEF); + updateChannel(CHANNEL_GROUP_STATUS, CHARGE_REMAINING, UnDefType.UNDEF); } } else { - updateState(chargingTimeRemaining, UnDefType.NULL); + updateChannel(CHANNEL_GROUP_STATUS, CHARGE_REMAINING, UnDefType.NULL); } } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 3eb640b51df2b..9e0bc4250a6f9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -118,55 +118,31 @@ private static class ChargeKeyDay { @SuppressWarnings("serial") private static final Map chargeEnableChannelKeys = new HashMap<>() { { + VehicleChannelHandler.timedChannels.forEach((key, channel) -> { + put(channel.timer + CHARGE_ENABLED, key); + }); put(CHARGE_PROFILE_CLIMATE, ProfileKey.CLIMATE); - put(CHARGE_TIMER1_ENABLED, ProfileKey.TIMER1); - put(CHARGE_TIMER2_ENABLED, ProfileKey.TIMER2); - put(CHARGE_TIMER3_ENABLED, ProfileKey.TIMER3); - put(CHARGE_OVERRIDE_ENABLED, ProfileKey.OVERRIDE); } }; @SuppressWarnings("serial") private static final Map chargeTimeChannelKeys = new HashMap<>() { { - put(CHARGE_WINDOW_START_HOUR, new ChargeKeyHour(ProfileKey.WINDOWSTART, true)); - put(CHARGE_WINDOW_START_MINUTE, new ChargeKeyHour(ProfileKey.WINDOWSTART, false)); - put(CHARGE_WINDOW_END_HOUR, new ChargeKeyHour(ProfileKey.WINDOWEND, true)); - put(CHARGE_WINDOW_END_MINUTE, new ChargeKeyHour(ProfileKey.WINDOWEND, false)); - put(CHARGE_TIMER1_DEPARTURE_HOUR, new ChargeKeyHour(ProfileKey.TIMER1, true)); - put(CHARGE_TIMER1_DEPARTURE_MINUTE, new ChargeKeyHour(ProfileKey.TIMER1, false)); - put(CHARGE_TIMER2_DEPARTURE_HOUR, new ChargeKeyHour(ProfileKey.TIMER2, true)); - put(CHARGE_TIMER2_DEPARTURE_MINUTE, new ChargeKeyHour(ProfileKey.TIMER2, false)); - put(CHARGE_TIMER3_DEPARTURE_HOUR, new ChargeKeyHour(ProfileKey.TIMER3, true)); - put(CHARGE_TIMER3_DEPARTURE_MINUTE, new ChargeKeyHour(ProfileKey.TIMER3, false)); - put(CHARGE_OVERRIDE_DEPARTURE_HOUR, new ChargeKeyHour(ProfileKey.OVERRIDE, true)); - put(CHARGE_OVERRIDE_DEPARTURE_MINUTE, new ChargeKeyHour(ProfileKey.OVERRIDE, false)); + VehicleChannelHandler.timedChannels.forEach((key, channel) -> { + put(channel.time + CHARGE_HOUR, new ChargeKeyHour(key, true)); + put(channel.time + CHARGE_MINUTE, new ChargeKeyHour(key, false)); + }); } }; + @SuppressWarnings("serial") private static final Map chargeDayChannelKeys = new HashMap<>() { { - put(CHARGE_TIMER1_DAY_MON, new ChargeKeyDay(ProfileKey.TIMER1, DayOfWeek.MONDAY)); - put(CHARGE_TIMER1_DAY_TUE, new ChargeKeyDay(ProfileKey.TIMER1, DayOfWeek.TUESDAY)); - put(CHARGE_TIMER1_DAY_WED, new ChargeKeyDay(ProfileKey.TIMER1, DayOfWeek.WEDNESDAY)); - put(CHARGE_TIMER1_DAY_THU, new ChargeKeyDay(ProfileKey.TIMER1, DayOfWeek.THURSDAY)); - put(CHARGE_TIMER1_DAY_FRI, new ChargeKeyDay(ProfileKey.TIMER1, DayOfWeek.FRIDAY)); - put(CHARGE_TIMER1_DAY_SAT, new ChargeKeyDay(ProfileKey.TIMER1, DayOfWeek.SATURDAY)); - put(CHARGE_TIMER1_DAY_SUN, new ChargeKeyDay(ProfileKey.TIMER1, DayOfWeek.SUNDAY)); - put(CHARGE_TIMER2_DAY_MON, new ChargeKeyDay(ProfileKey.TIMER2, DayOfWeek.MONDAY)); - put(CHARGE_TIMER2_DAY_TUE, new ChargeKeyDay(ProfileKey.TIMER2, DayOfWeek.TUESDAY)); - put(CHARGE_TIMER2_DAY_WED, new ChargeKeyDay(ProfileKey.TIMER2, DayOfWeek.WEDNESDAY)); - put(CHARGE_TIMER2_DAY_THU, new ChargeKeyDay(ProfileKey.TIMER2, DayOfWeek.THURSDAY)); - put(CHARGE_TIMER2_DAY_FRI, new ChargeKeyDay(ProfileKey.TIMER2, DayOfWeek.FRIDAY)); - put(CHARGE_TIMER2_DAY_SAT, new ChargeKeyDay(ProfileKey.TIMER2, DayOfWeek.SATURDAY)); - put(CHARGE_TIMER2_DAY_SUN, new ChargeKeyDay(ProfileKey.TIMER2, DayOfWeek.SUNDAY)); - put(CHARGE_TIMER3_DAY_MON, new ChargeKeyDay(ProfileKey.TIMER3, DayOfWeek.MONDAY)); - put(CHARGE_TIMER3_DAY_TUE, new ChargeKeyDay(ProfileKey.TIMER3, DayOfWeek.TUESDAY)); - put(CHARGE_TIMER3_DAY_WED, new ChargeKeyDay(ProfileKey.TIMER3, DayOfWeek.WEDNESDAY)); - put(CHARGE_TIMER3_DAY_THU, new ChargeKeyDay(ProfileKey.TIMER3, DayOfWeek.THURSDAY)); - put(CHARGE_TIMER3_DAY_FRI, new ChargeKeyDay(ProfileKey.TIMER3, DayOfWeek.FRIDAY)); - put(CHARGE_TIMER3_DAY_SAT, new ChargeKeyDay(ProfileKey.TIMER3, DayOfWeek.SATURDAY)); - put(CHARGE_TIMER3_DAY_SUN, new ChargeKeyDay(ProfileKey.TIMER3, DayOfWeek.SUNDAY)); + VehicleChannelHandler.dayChannels.forEach((dayOfWeek, dayChannel) -> { + put(CHARGE_TIMER1 + dayChannel, new ChargeKeyDay(ProfileKey.TIMER1, dayOfWeek)); + put(CHARGE_TIMER2 + dayChannel, new ChargeKeyDay(ProfileKey.TIMER2, dayOfWeek)); + put(CHARGE_TIMER3 + dayChannel, new ChargeKeyDay(ProfileKey.TIMER3, dayOfWeek)); + }); } }; @@ -247,7 +223,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { proxy.get().requestImage(configuration.get(), imageProperties, imageCallback); } } - updateState(imageViewportChannel, StringType.valueOf(newViewport)); + updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_VIEWPORT, StringType.valueOf(newViewport)); } } if (command instanceof DecimalType) { @@ -262,7 +238,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { } } } - updateState(imageSizeChannel, new DecimalType(newImageSize)); + updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_SIZE, new DecimalType(newImageSize)); } } } @@ -326,8 +302,10 @@ public void initialize() { imageProperties = new ImageProperties(configuration.get().imageViewport, configuration.get().imageSize); } - updateState(imageViewportChannel, StringType.valueOf((configuration.get().imageViewport))); - updateState(imageSizeChannel, new DecimalType((configuration.get().imageSize))); + updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_VIEWPORT, + StringType.valueOf((configuration.get().imageViewport))); + updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_SIZE, + new DecimalType((configuration.get().imageSize))); // check imperial setting is different to AutoDetect if (!UNITS_AUTODETECT.equals(configuration.get().units)) { @@ -524,7 +502,7 @@ public void updateRemoteExecutionStatus(@Nullable String service, String status) && ExecutionState.EXECUTED.toString().equals(status)) { saveChargeProfileSent(); } - updateState(remoteStateChannel, StringType.valueOf(Converter.toTitleCase( + updateChannel(CHANNEL_GROUP_REMOTE, REMOTE_STATE, StringType.valueOf(Converter.toTitleCase( new StringBuilder(service == null ? "-" : service).append(" ").append(status).toString()))); } @@ -621,7 +599,7 @@ public void onResponse(byte[] content) { if (content.length > 0) { imageCache = Optional.of(content); String contentType = HttpUtil.guessContentTypeFromData(content); - updateState(imageChannel, new RawType(content, contentType)); + updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_FORMAT, new RawType(content, contentType)); } else { synchronized (imageProperties) { imageProperties.failed(); @@ -813,13 +791,13 @@ private void handleChargeProfileCommand(ChannelUID channelUID, Command command) switch (id) { case CHARGE_PROFILE_PREFERENCE: profile.setPreference(stringCommand); - updateState(chargeProfilePreference, + updateChannel(CHANNEL_GROUP_CHARGE, CHARGE_PROFILE_PREFERENCE, StringType.valueOf(Converter.toTitleCase(profile.getPreference()))); processed = true; break; case CHARGE_PROFILE_MODE: profile.setMode(stringCommand); - updateState(chargeProfileChargeMode, + updateChannel(CHANNEL_GROUP_CHARGE, CHARGE_PROFILE_MODE, StringType.valueOf(Converter.toTitleCase(profile.getMode()))); processed = true; break; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java index 0279e05287b13..fcf14f04faba6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java @@ -12,6 +12,7 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.utils; +import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; import static org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileWrapper.ProfileKey.*; import static org.openhab.binding.bmwconnecteddrive.internal.utils.Constants.NULL_LOCAL_TIME; import static org.openhab.binding.bmwconnecteddrive.internal.utils.Constants.TIME_FORMATER; @@ -61,6 +62,7 @@ public enum ProfileKey { TIMER1, TIMER2, TIMER3, + TIMER4, OVERRIDE, WINDOWSTART, WINDOWEND diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index 34f7f355ddd88..5764079858694 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -369,7 +369,7 @@ private void checkResult(ChannelUID channelUID, State state) { wanted = StringType.valueOf(Converter.toTitleCase(vStatus.hood)); assertEquals(wanted.toString(), st.toString(), "Door"); break; - case WINDOW_DOOR_DRIVER_FORNT: + case WINDOW_DOOR_DRIVER_FRONT: assertTrue(state instanceof StringType); st = (StringType) state; wanted = StringType.valueOf(Converter.toTitleCase(vStatus.windowDriverFront)); From 09e73dec528090e23b2a4ac60d21a0b1b53ab9e6 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Tue, 16 Feb 2021 01:07:09 +0100 Subject: [PATCH 122/176] fix unnessary use of StringBuilder and Optional as parameter antipattern Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../handler/ConnectedDriveBridgeHandler.java | 34 ++-- .../internal/handler/ConnectedDriveProxy.java | 146 +++++++++--------- .../handler/RemoteServiceHandler.java | 8 +- 3 files changed, 94 insertions(+), 94 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java index 97469e57674b1..38f9030d0286e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java @@ -73,13 +73,13 @@ public void initialize() { troubleshootFingerprint = Optional.empty(); updateStatus(ThingStatus.UNKNOWN); configuration = Optional.of(getConfigAs(ConnectedDriveConfiguration.class)); - if (configuration.isPresent()) { - proxy = Optional.of(new ConnectedDriveProxy(httpClientFactory, configuration.get())); + configuration.ifPresentOrElse(config -> { + proxy = Optional.of(new ConnectedDriveProxy(httpClientFactory, config)); // give the system some time to create all predefined Vehicles initializerJob = Optional.of(scheduler.schedule(this::requestVehicles, 5, TimeUnit.SECONDS)); - } else { + }, () -> { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR); - } + }); } @Override @@ -92,9 +92,8 @@ public void requestVehicles() { } public String getDiscoveryFingerprint() { - if (troubleshootFingerprint.isPresent()) { - VehiclesContainer container = Converter.getGson().fromJson(troubleshootFingerprint.get(), - VehiclesContainer.class); + return troubleshootFingerprint.map(fingerprint -> { + VehiclesContainer container = Converter.getGson().fromJson(fingerprint, VehiclesContainer.class); if (container != null) { if (container.vehicles != null) { if (container.vehicles.isEmpty()) { @@ -115,13 +114,11 @@ public String getDiscoveryFingerprint() { }); return Converter.getGson().toJson(container); } - } else { - // Vehicles is empty so deliver fingerprint as it is - return troubleshootFingerprint.get(); } } - } - return Constants.INVALID; + // Not a VehiclesContainer or Vehicles is empty so deliver fingerprint as it is + return fingerprint; + }).orElse(Constants.INVALID); } private void logFingerPrint() { @@ -139,14 +136,12 @@ public void onResponse(@Nullable String response) { boolean firstResponse = troubleshootFingerprint.isEmpty(); if (response != null) { updateStatus(ThingStatus.ONLINE); - if (discoveryService.isEmpty()) { - troubleshootFingerprint = Optional.of(response); - } else { + troubleshootFingerprint = discoveryService.map(discovery -> { try { VehiclesContainer container = Converter.getGson().fromJson(response, VehiclesContainer.class); if (container != null) { if (container.vehicles != null) { - discoveryService.get().onResponse(container); + discovery.onResponse(container); container.vehicles.forEach(entry -> { entry.vin = ANONYMOUS; entry.breakdownNumber = ANONYMOUS; @@ -161,12 +156,13 @@ public void onResponse(@Nullable String response) { } }); } + return Converter.getGson().toJson(container); } - troubleshootFingerprint = Optional.of(Converter.getGson().toJson(container)); } catch (JsonSyntaxException jse) { - troubleshootFingerprint = Optional.of(response); } - } + // Unparseable or not a VehiclesContainer: + return response; + }); } else { troubleshootFingerprint = Optional.of(Constants.EMPTY_VEHICLES); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index b92444c2879fc..1a5654318429f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -16,12 +16,12 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import java.util.Optional; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; 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; @@ -45,6 +45,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.gson.JsonSyntaxException; + /** * The {@link ConnectedDriveProxy} This class holds the important constants for the BMW Connected Drive Authorization. * They @@ -60,26 +62,26 @@ public class ConnectedDriveProxy { private final Logger logger = LoggerFactory.getLogger(ConnectedDriveProxy.class); private final Token token = new Token(); - private HttpClient httpClient; - private HttpClient authHttpClient; - private String legacyAuthUri; - private ConnectedDriveConfiguration configuration; + private final HttpClient httpClient; + private final HttpClient authHttpClient; + private final String legacyAuthUri; + private final ConnectedDriveConfiguration configuration; /** * URLs taken from https://github.com/bimmerconnected/bimmer_connected/blob/master/bimmer_connected/const.py */ - String baseUrl; - String vehicleUrl; - String legacyUrl; - String vehicleStatusAPI = "/status"; - String lastTripAPI = "/statistics/lastTrip"; - String allTripsAPI = "/statistics/allTrips"; - String chargeAPI = "/chargingprofile"; - String destinationAPI = "/destinations"; - String imageAPI = "/image"; - String rangeMapAPI = "/rangemap"; - String serviceExecutionAPI = "/executeService"; - String serviceExecutionStateAPI = "/serviceExecutionStatus"; + final String baseUrl; + final String vehicleUrl; + final String legacyUrl; + final String vehicleStatusAPI = "/status"; + final String lastTripAPI = "/statistics/lastTrip"; + final String allTripsAPI = "/statistics/allTrips"; + final String chargeAPI = "/chargingprofile"; + final String destinationAPI = "/destinations"; + final String imageAPI = "/image"; + final String rangeMapAPI = "/rangemap"; + final String serviceExecutionAPI = "/executeService"; + final String serviceExecutionStateAPI = "/serviceExecutionStatus"; public ConnectedDriveProxy(HttpClientFactory httpClientFactory, ConnectedDriveConfiguration config) { httpClient = httpClientFactory.getCommonHttpClient(); @@ -92,7 +94,7 @@ public ConnectedDriveProxy(HttpClientFactory httpClientFactory, ConnectedDriveCo } configuration = config; - StringBuilder legacyAuth = new StringBuilder(); + final StringBuilder legacyAuth = new StringBuilder(); legacyAuth.append("https://"); legacyAuth.append(BimmerConstants.AUTH_SERVER_MAP.get(configuration.region)); legacyAuth.append(BimmerConstants.OAUTH_ENDPOINT); @@ -102,8 +104,8 @@ public ConnectedDriveProxy(HttpClientFactory httpClientFactory, ConnectedDriveCo legacyUrl = "https://" + getRegionServer() + "/api/vehicle/dynamic/v1/"; } - private synchronized void call(String url, boolean post, Optional> params, - ResponseCallback callback) { + private synchronized void call(final String url, final boolean post, final @Nullable MultiMap params, + final ResponseCallback callback) { // only executed in "simulation mode" // SimulationTest.testSimulationOff() assures Injector is off when releasing if (Injector.isActive()) { @@ -116,21 +118,21 @@ private synchronized void call(String url, boolean post, Optional> params, ResponseCallback callback) { + public void get(String url, @Nullable MultiMap params, ResponseCallback callback) { call(url, false, params, callback); } - public void post(String url, Optional> params, ResponseCallback callback) { + public void post(String url, @Nullable MultiMap params, ResponseCallback callback) { call(url, true, params, callback); } public void requestVehicles(StringResponseCallback callback) { - get(vehicleUrl, Optional.empty(), callback); + get(vehicleUrl, null, callback); } public void requestVehcileStatus(VehicleConfiguration config, StringResponseCallback callback) { - get(new StringBuilder(baseUrl).append(config.vin).append(vehicleStatusAPI).toString(), Optional.empty(), - callback); + get(baseUrl + config.vin + vehicleStatusAPI, null, callback); } public void requestLegacyVehcileStatus(VehicleConfiguration config, StringResponseCallback callback) { // see https://github.com/jupe76/bmwcdapi/search?q=dynamic%2Fv1 - get(new StringBuilder(legacyUrl).append(config.vin).append("?offset=-60").toString(), Optional.empty(), - callback); + get(legacyUrl + config.vin + "?offset=-60", null, callback); } public void requestLastTrip(VehicleConfiguration config, StringResponseCallback callback) { - get(new StringBuilder(baseUrl).append(config.vin).append(lastTripAPI).toString(), Optional.empty(), callback); + get(baseUrl + config.vin + lastTripAPI, null, callback); } public void requestAllTrips(VehicleConfiguration config, StringResponseCallback callback) { - get(new StringBuilder(baseUrl).append(config.vin).append(allTripsAPI).toString(), Optional.empty(), callback); + get(baseUrl + config.vin + allTripsAPI, null, callback); } public void requestChargingProfile(VehicleConfiguration config, StringResponseCallback callback) { - get(new StringBuilder(baseUrl).append(config.vin).append(chargeAPI).toString(), Optional.empty(), callback); + get(baseUrl + config.vin + chargeAPI, null, callback); } public void requestDestinations(VehicleConfiguration config, StringResponseCallback callback) { - get(new StringBuilder(baseUrl).append(config.vin).append(destinationAPI).toString(), Optional.empty(), - callback); + get(baseUrl + config.vin + destinationAPI, null, callback); } - public void requestRangeMap(VehicleConfiguration config, Optional> params, + public void requestRangeMap(VehicleConfiguration config, @Nullable MultiMap params, StringResponseCallback callback) { - get(new StringBuilder(baseUrl).append(config.vin).append(rangeMapAPI).toString(), params, callback); + get(baseUrl + config.vin + rangeMapAPI, params, callback); } public void requestImage(VehicleConfiguration config, ImageProperties props, ByteResponseCallback callback) { - String localImageUrl = new StringBuilder(baseUrl).append(config.vin).append(imageAPI).toString(); - MultiMap dataMap = new MultiMap(); + final String localImageUrl = baseUrl + config.vin + imageAPI; + final MultiMap dataMap = new MultiMap(); dataMap.add("width", Integer.toString(props.size)); dataMap.add("height", Integer.toString(props.size)); dataMap.add("view", props.viewport); - get(localImageUrl, Optional.of(dataMap), callback); + get(localImageUrl, dataMap, callback); } private String getRegionServer() { - String retVal = BimmerConstants.SERVER_MAP.get(configuration.region); - if (retVal != null) { - return retVal; - } else { - return Constants.INVALID; - } + final String retVal = BimmerConstants.SERVER_MAP.get(configuration.region); + return retVal == null ? Constants.INVALID : retVal; } RemoteServiceHandler getRemoteServiceHandler(VehicleHandler vehicleHandler) { @@ -251,37 +246,46 @@ public Token getToken() { * @return */ private synchronized void updateToken() { - Request req = authHttpClient.POST(legacyAuthUri); + final Request req = authHttpClient.POST(legacyAuthUri); - req.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); req.header(HttpHeader.CONNECTION, KEEP_ALIVE); req.header(HttpHeader.HOST, BimmerConstants.SERVER_MAP.get(configuration.region)); req.header(HttpHeader.AUTHORIZATION, BimmerConstants.AUTHORIZATION_VALUE_MAP.get(configuration.region)); req.header(CREDENTIALS, BimmerConstants.CREDENTIAL_VALUES); req.header(HttpHeader.REFERER, BimmerConstants.REFERER_URL); - MultiMap dataMap = new MultiMap(); + final MultiMap dataMap = new MultiMap(); dataMap.add("grant_type", "password"); dataMap.add(SCOPE, BimmerConstants.SCOPE_VALUES); dataMap.add(USERNAME, configuration.userName); dataMap.add(PASSWORD, configuration.password); - String urlEncodedData = UrlEncoded.encode(dataMap, Charset.defaultCharset(), false); - req.header(CONTENT_LENGTH, Integer.toString(urlEncodedData.length())); - req.content(new StringContentProvider(urlEncodedData)); + req.content(new StringContentProvider(CONTENT_TYPE_URL_ENCODED, + UrlEncoded.encode(dataMap, Charset.defaultCharset(), false), Charset.defaultCharset())); try { ContentResponse contentResponse = req.timeout(HTTP_TIMEOUT_SEC, TimeUnit.SECONDS).send(); // Status needs to be 302 - Response is stored in Header if (contentResponse.getStatus() == 302) { - HttpFields fields = contentResponse.getHeaders(); - HttpField field = fields.getField(HttpHeader.LOCATION); + final HttpFields fields = contentResponse.getHeaders(); + final HttpField field = fields.getField(HttpHeader.LOCATION); tokenFromUrl(field.getValue()); } else if (contentResponse.getStatus() == 200) { - AuthResponse authResponse = Converter.getGson().fromJson(contentResponse.getContentAsString(), - AuthResponse.class); - if (authResponse != null) { - token.setToken(authResponse.accessToken); - token.setType(authResponse.tokenType); - token.setExpiration(authResponse.expiresIn); + final String stringContent = contentResponse.getContentAsString(); + if (stringContent != null && !stringContent.isEmpty()) { + try { + final AuthResponse authResponse = Converter.getGson().fromJson(stringContent, + AuthResponse.class); + if (authResponse != null) { + token.setToken(authResponse.accessToken); + token.setType(authResponse.tokenType); + token.setExpiration(authResponse.expiresIn); + } else { + logger.debug("not an Authorization response: {}", stringContent); + } + } catch (JsonSyntaxException jse) { + logger.debug("Authorization response unparsable: {}", stringContent); + } + } else { + logger.debug("Authorization response has no content"); } } else { logger.debug("Authorization status {} reason {}", contentResponse.getStatus(), @@ -293,7 +297,7 @@ private synchronized void updateToken() { } void tokenFromUrl(String encodedUrl) { - MultiMap tokenMap = new MultiMap(); + final MultiMap tokenMap = new MultiMap(); UrlEncoded.decodeTo(encodedUrl, tokenMap, StandardCharsets.US_ASCII); tokenMap.forEach((key, value) -> { if (value.size() > 0) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java index 9ac2b7a375bbb..a2fc9900ce413 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -117,12 +117,12 @@ boolean execute(RemoteService service, String... data) { } serviceExecuting = Optional.of(service.toString()); } - MultiMap dataMap = new MultiMap(); + final MultiMap dataMap = new MultiMap(); dataMap.add(SERVICE_TYPE, service.toString()); if (data.length > 0) { dataMap.add(DATA, data[0]); } - proxy.post(serviceExecutionAPI, Optional.of(dataMap), this); + proxy.post(serviceExecutionAPI, dataMap, this); return true; } @@ -135,9 +135,9 @@ public void getState() { handler.getData(); } counter++; - MultiMap dataMap = new MultiMap(); + final MultiMap dataMap = new MultiMap(); dataMap.add(SERVICE_TYPE, serviceExecuting.get()); - proxy.get(serviceExecutionStateAPI, Optional.of(dataMap), this); + proxy.get(serviceExecutionStateAPI, dataMap, this); }, () -> { logger.warn("No Service executed to get state"); }); From 66a59c764d464df21d56d2e25b4440ce1954df05 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Tue, 16 Feb 2021 10:09:56 +0100 Subject: [PATCH 123/176] fix further missing JsonSyntaxException-handling Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../handler/RemoteServiceHandler.java | 60 ++++++++----------- .../handler/VehicleChannelHandler.java | 5 +- .../internal/handler/VehicleHandler.java | 4 +- .../internal/dto/RemoteStatusTest.java | 2 +- 4 files changed, 32 insertions(+), 39 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java index a2fc9900ce413..bf997871b6fa4 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -19,7 +19,6 @@ import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jetty.util.MultiMap; import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; -import org.openhab.binding.bmwconnecteddrive.internal.dto.remote.ExecutionStatus; import org.openhab.binding.bmwconnecteddrive.internal.dto.remote.ExecutionStatusContainer; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; @@ -27,6 +26,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.gson.JsonSyntaxException; + /** * The {@link RemoteServiceHandler} handles executions of remote services towards your Vehicle * @@ -47,23 +48,12 @@ public class RemoteServiceHandler implements StringResponseCallback { private int counter = 0; public enum ExecutionState { - READY("READY"), - INITIATED("INITIATED"), - PENDING("PENDING"), - DELIVERED("DELIVERED"), - EXECUTED("EXECUTED"), - ERROR("ERROR"); - - private final String state; - - ExecutionState(String s) { - state = s; - } - - @Override - public String toString() { - return state; - } + READY, + INITIATED, + PENDING, + DELIVERED, + EXECUTED, + ERROR, } public enum RemoteService { @@ -146,29 +136,31 @@ public void getState() { @Override public void onResponse(@Nullable String result) { if (result != null) { - ExecutionStatusContainer esc = Converter.getGson().fromJson(result, ExecutionStatusContainer.class); - if (esc != null) { - ExecutionStatus execStatus = esc.executionStatus; - handler.updateRemoteExecutionStatus(serviceExecuting.get(), execStatus.status); - if (!ExecutionState.EXECUTED.toString().equals(execStatus.status)) { - handler.getScheduler().schedule(this::getState, STATE_UPDATE_SEC, TimeUnit.SECONDS); - } else { - // refresh loop ends - update of status handled in the normal refreshInterval. Earlier update - // doesn't - // show better results! - reset(); + try { + ExecutionStatusContainer esc = Converter.getGson().fromJson(result, ExecutionStatusContainer.class); + if (esc != null && esc.executionStatus != null) { + String status = esc.executionStatus.status; + handler.updateRemoteExecutionStatus(serviceExecuting.get(), status); + if (ExecutionState.EXECUTED.name().equals(status)) { + // refresh loop ends - update of status handled in the normal refreshInterval. Earlier update + // doesn't + // show better results! + reset(); + return; + } } + } catch (JsonSyntaxException jse) { + logger.debug("RemoteService response is unparseable: {} {}", result, jse.getMessage()); } - } else { - // schedule even if no result is present until retries exceeded - handler.getScheduler().schedule(this::getState, STATE_UPDATE_SEC, TimeUnit.SECONDS); } + // schedule even if no result is present until retries exceeded + handler.getScheduler().schedule(this::getState, STATE_UPDATE_SEC, TimeUnit.SECONDS); } @Override public void onError(NetworkError error) { - handler.updateRemoteExecutionStatus(serviceExecuting.get(), new StringBuilder(ExecutionState.ERROR.toString()) - .append(Constants.SPACE).append(Integer.toString(error.status)).toString()); + handler.updateRemoteExecutionStatus(serviceExecuting.get(), + ExecutionState.ERROR.name() + Constants.SPACE + Integer.toString(error.status)); reset(); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 62a90fb628c4e..f30e84a743f2b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -29,6 +29,7 @@ import javax.measure.quantity.Length; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.bmwconnecteddrive.internal.dto.Destination; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTrips; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTrip; @@ -91,14 +92,14 @@ public class VehicleChannelHandler extends BaseThingHandler { // Charging protected static class TimedChannel { - TimedChannel(final String time, final String timer, final boolean hasDays) { + TimedChannel(final String time, @Nullable final String timer, final boolean hasDays) { this.time = time; this.timer = timer; this.hasDays = hasDays; } final String time; - final String timer; + final @Nullable String timer; final boolean hasDays; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 9e0bc4250a6f9..c6122a0b4ff4b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -497,9 +497,9 @@ private boolean isSupported(String service) { } } - public void updateRemoteExecutionStatus(@Nullable String service, String status) { + public void updateRemoteExecutionStatus(@Nullable String service, @Nullable String status) { if (RemoteService.CHARGING_CONTROL.toString().equals(service) - && ExecutionState.EXECUTED.toString().equals(status)) { + && ExecutionState.EXECUTED.name().equals(status)) { saveChargeProfileSent(); } updateChannel(CHANNEL_GROUP_REMOTE, REMOTE_STATE, StringType.valueOf(Converter.toTitleCase( diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/RemoteStatusTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/RemoteStatusTest.java index 4f4482df38974..b0c07c3a236d0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/RemoteStatusTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/RemoteStatusTest.java @@ -38,6 +38,6 @@ public void testStatus() { String resource1 = FileReader.readFileInString("src/test/resources/webapi/remote-services/pending.json"); ExecutionStatusContainer esc = GSON.fromJson(resource1, ExecutionStatusContainer.class); ExecutionStatus execStatus = esc.executionStatus; - assertEquals(ExecutionState.PENDING.toString(), execStatus.status, "Status"); + assertEquals(ExecutionState.PENDING.name(), execStatus.status, "Status"); } } From af4d27b51a1597d4a7cee4e205ffb4307629de51 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Tue, 16 Feb 2021 11:20:22 +0100 Subject: [PATCH 124/176] fix NoSuchElementException Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../internal/utils/ChargeProfileWrapper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java index fcf14f04faba6..28d20cc38f4a3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java @@ -143,7 +143,7 @@ public void setEnabled(final ProfileKey key, @Nullable final Boolean enabled) { } public @Nullable String getMode() { - return mode.map(m -> m.name()).get(); + return mode.map(m -> m.name()).orElse(null); } public void setMode(final @Nullable String mode) { @@ -159,7 +159,7 @@ public void setMode(final @Nullable String mode) { } public @Nullable String getPreference() { - return preference.map(pref -> pref.name()).get(); + return preference.map(pref -> pref.name()).orElse(null); } public void setPreference(final @Nullable String preference) { From d816b48da3ece6b3818d8a0f6cbba3f977e046a9 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Tue, 16 Feb 2021 11:44:15 +0100 Subject: [PATCH 125/176] fix potential Optional.of NullPointerException Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../internal/handler/VehicleHandler.java | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index c6122a0b4ff4b..77837a05b8a87 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -167,9 +167,8 @@ public void handleCommand(ChannelUID channelUID, Command command) { } else if (CHANNEL_GROUP_STATUS.equals(group)) { vehicleStatusCache.ifPresent(vehicleStatus -> vehicleStatusCallback.onResponse(vehicleStatus)); } else if (CHANNEL_GROUP_CHARGE.equals(group)) { - chargeProfileEdit.ifPresentOrElse(profileEdit -> updateChargeProfile(profileEdit), - () -> chargeProfileCache - .ifPresent(profileCache -> updateChargeProfileFromContent(profileCache))); + chargeProfileEdit.ifPresentOrElse(this::updateChargeProfile, + () -> chargeProfileCache.ifPresent(this::updateChargeProfileFromContent)); } else if (CHANNEL_GROUP_VEHICLE_IMAGE.equals(group)) { imageCache.ifPresent(image -> imageCallback.onResponse(image)); } @@ -278,20 +277,19 @@ public void handleCommand(ChannelUID channelUID, Command command) { public void initialize() { callbackCounter = Optional.of(new ArrayList()); updateStatus(ThingStatus.UNKNOWN); - configuration = Optional.of(getConfigAs(VehicleConfiguration.class)); - if (configuration.isPresent()) { + final VehicleConfiguration config = getConfigAs(VehicleConfiguration.class); + if (config != null) { + configuration = Optional.of(config); scheduler.execute(() -> { Bridge bridge = getBridge(); if (bridge != null) { BridgeHandler handler = bridge.getHandler(); if (handler != null) { bridgeHandler = Optional.of(((ConnectedDriveBridgeHandler) handler)); - proxy = bridgeHandler.get().getProxy(); - if (proxy.isPresent()) { - remote = Optional.of(proxy.get().getRemoteServiceHandler(this)); - } + remote = ((ConnectedDriveBridgeHandler) handler).getProxy() + .map(proxy -> proxy.getRemoteServiceHandler(this)); } else { - logger.debug("Brdige Handler null"); + logger.debug("Bridge Handler null"); } } else { logger.debug("Bridge null"); @@ -299,21 +297,18 @@ public void initialize() { // get Image after init with config values synchronized (imageProperties) { - imageProperties = new ImageProperties(configuration.get().imageViewport, - configuration.get().imageSize); + imageProperties = new ImageProperties(config.imageViewport, config.imageSize); } - updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_VIEWPORT, - StringType.valueOf((configuration.get().imageViewport))); - updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_SIZE, - new DecimalType((configuration.get().imageSize))); + updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_VIEWPORT, StringType.valueOf((config.imageViewport))); + updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_SIZE, new DecimalType((config.imageSize))); // check imperial setting is different to AutoDetect - if (!UNITS_AUTODETECT.equals(configuration.get().units)) { - imperial = UNITS_IMPERIAL.equals(configuration.get().units); + if (!UNITS_AUTODETECT.equals(config.units)) { + imperial = UNITS_IMPERIAL.equals(config.units); } // start update schedule - startSchedule(configuration.get().refreshInterval); + startSchedule(config.refreshInterval); }); } else { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR); @@ -483,7 +478,7 @@ private void logFingerPrint() { * @return */ private boolean isSupported(String service) { - String services = thing.getProperties().get(Constants.SERVICES_SUPPORTED); + final String services = thing.getProperties().get(Constants.SERVICES_SUPPORTED); if (services != null) { if (services.contains(service)) { return true; From 8f205dfaa8e244e73545e06e97ba63c926952cc8 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Tue, 16 Feb 2021 12:36:04 +0100 Subject: [PATCH 126/176] fix more Optional.ifPresent -> Optional.get antipattern Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../handler/RemoteServiceHandler.java | 7 ++-- .../handler/VehicleChannelHandler.java | 2 +- .../internal/handler/VehicleHandler.java | 42 +++++++++---------- 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java index bf997871b6fa4..b93d27484c8f5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -18,6 +18,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jetty.util.MultiMap; +import org.openhab.binding.bmwconnecteddrive.internal.VehicleConfiguration; import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; import org.openhab.binding.bmwconnecteddrive.internal.dto.remote.ExecutionStatusContainer; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; @@ -89,9 +90,9 @@ public RemoteServiceHandler(VehicleHandler vehicleHandler, ConnectedDriveProxy c handler = vehicleHandler; proxy = connectedDriveProxy; if (handler.getConfiguration().isPresent()) { - serviceExecutionAPI = proxy.baseUrl + handler.getConfiguration().get().vin + proxy.serviceExecutionAPI; - serviceExecutionStateAPI = proxy.baseUrl + handler.getConfiguration().get().vin - + proxy.serviceExecutionStateAPI; + final VehicleConfiguration config = handler.getConfiguration().get(); + serviceExecutionAPI = proxy.baseUrl + config.vin + proxy.serviceExecutionAPI; + serviceExecutionStateAPI = proxy.baseUrl + config.vin + proxy.serviceExecutionStateAPI; } else { serviceExecutionAPI = Constants.INVALID; serviceExecutionStateAPI = Constants.INVALID; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index f30e84a743f2b..3a21e4c294ab9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -363,7 +363,7 @@ protected void updateLastTrip(LastTrip trip) { } protected void updateChargeProfileFromContent(String content) { - ChargeProfileWrapper.fromJson(content).ifPresent(wrapper -> updateChargeProfile(wrapper)); + ChargeProfileWrapper.fromJson(content).ifPresent(this::updateChargeProfile); } protected void updateChargeProfile(ChargeProfileWrapper wrapper) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 77837a05b8a87..ee75b26e74e79 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -177,28 +177,28 @@ public void handleCommand(ChannelUID channelUID, Command command) { // Executing Remote Services if (command instanceof StringType) { String serviceCommand = ((StringType) command).toFullString(); - if (remote.isPresent()) { + remote.ifPresent(remot -> { switch (serviceCommand) { case REMOTE_SERVICE_LIGHT_FLASH: - remote.get().execute(RemoteService.LIGHT_FLASH); + remot.execute(RemoteService.LIGHT_FLASH); break; case REMOTE_SERVICE_AIR_CONDITIONING: - remote.get().execute(RemoteService.AIR_CONDITIONING); + remot.execute(RemoteService.AIR_CONDITIONING); break; case REMOTE_SERVICE_DOOR_LOCK: - remote.get().execute(RemoteService.DOOR_LOCK); + remot.execute(RemoteService.DOOR_LOCK); break; case REMOTE_SERVICE_DOOR_UNLOCK: - remote.get().execute(RemoteService.DOOR_UNLOCK); + remot.execute(RemoteService.DOOR_UNLOCK); break; case REMOTE_SERVICE_HORN: - remote.get().execute(RemoteService.HORN); + remot.execute(RemoteService.HORN); break; case REMOTE_SERVICE_VEHICLE_FINDER: - remote.get().execute(RemoteService.VEHICLE_FINDER); + remot.execute(RemoteService.VEHICLE_FINDER); break; case REMOTE_SERVICE_CHARGE_NOW: - remote.get().execute(RemoteService.CHARGE_NOW); + remot.execute(RemoteService.CHARGE_NOW); break; case REMOTE_SERVICE_CHARGING_CONTROL: sendChargeProfile(chargeProfileEdit); @@ -207,11 +207,11 @@ public void handleCommand(ChannelUID channelUID, Command command) { logger.info("Remote service execution {} unknown", serviceCommand); break; } - } + }); } } else if (CHANNEL_GROUP_VEHICLE_IMAGE.equals(group)) { // Image Change - if (configuration.isPresent()) { + configuration.ifPresent(config -> { if (command instanceof StringType) { if (channelUID.getIdWithoutGroup().equals(IMAGE_VIEWPORT)) { String newViewport = command.toString(); @@ -219,7 +219,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { if (!imageProperties.viewport.equals(newViewport)) { imageProperties = new ImageProperties(newViewport, imageProperties.size); imageCache = Optional.empty(); - proxy.get().requestImage(configuration.get(), imageProperties, imageCallback); + proxy.ifPresent(prox -> prox.requestImage(config, imageProperties, imageCallback)); } } updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_VIEWPORT, StringType.valueOf(newViewport)); @@ -233,14 +233,14 @@ public void handleCommand(ChannelUID channelUID, Command command) { if (imageProperties.size != newImageSize) { imageProperties = new ImageProperties(imageProperties.viewport, newImageSize); imageCache = Optional.empty(); - proxy.get().requestImage(configuration.get(), imageProperties, imageCallback); + proxy.ifPresent(prox -> prox.requestImage(config, imageProperties, imageCallback)); } } } updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_SIZE, new DecimalType(newImageSize)); } } - } + }); } else if (CHANNEL_GROUP_DESTINATION.equals(group)) { if (command instanceof StringType) { int index = Converter.getIndex(command.toFullString()); @@ -286,8 +286,8 @@ public void initialize() { BridgeHandler handler = bridge.getHandler(); if (handler != null) { bridgeHandler = Optional.of(((ConnectedDriveBridgeHandler) handler)); - remote = ((ConnectedDriveBridgeHandler) handler).getProxy() - .map(proxy -> proxy.getRemoteServiceHandler(this)); + proxy = ((ConnectedDriveBridgeHandler) handler).getProxy(); + remote = proxy.map(prox -> prox.getRemoteServiceHandler(this)); } else { logger.debug("Bridge Handler null"); } @@ -316,21 +316,19 @@ public void initialize() { } private void startSchedule(int interval) { - if (refreshJob.isPresent()) { - if (refreshJob.get().isCancelled()) { + refreshJob.ifPresentOrElse(job -> { + if (job.isCancelled()) { refreshJob = Optional .of(scheduler.scheduleWithFixedDelay(this::getData, 0, interval, TimeUnit.MINUTES)); } // else - scheduler is already running! - } else { + }, () -> { refreshJob = Optional.of(scheduler.scheduleWithFixedDelay(this::getData, 0, interval, TimeUnit.MINUTES)); - } + }); } @Override public void dispose() { - if (refreshJob.isPresent()) { - refreshJob.get().cancel(true); - } + refreshJob.ifPresent(job -> job.cancel(true)); } public void getData() { From 93d5663102a6235ee7f3d0a7708ab8d578f2103b Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Fri, 19 Feb 2021 16:28:04 +0100 Subject: [PATCH 127/176] use streaming api to join days Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../internal/utils/ChargeProfileUtils.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java index 6ef1d69a2a07c..913b73808b2e9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java @@ -14,6 +14,7 @@ import java.time.DayOfWeek; import java.util.Set; +import java.util.stream.Collectors; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -26,14 +27,6 @@ public class ChargeProfileUtils { public static String formatDays(final Set weekdays) { - StringBuilder days = new StringBuilder(); - weekdays.forEach(entry -> { - if (days.length() == 0) { - days.append(Constants.DAYS.get(entry)); - } else { - days.append(Constants.COMMA).append(Constants.DAYS.get(entry)); - } - }); - return days.toString(); + return weekdays.stream().map(day -> Constants.DAYS.get(day)).collect(Collectors.joining(Constants.COMMA)); } } From 2325d3d6bec49033ae002267a227a17aef9fd4a2 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Mon, 22 Feb 2021 19:21:31 +0100 Subject: [PATCH 128/176] move metadata-classes to ChargeProfileUtils Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../handler/VehicleChannelHandler.java | 46 +------ .../internal/handler/VehicleHandler.java | 63 +--------- .../internal/utils/ChargeProfileUtils.java | 115 ++++++++++++++++++ 3 files changed, 124 insertions(+), 100 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 3a21e4c294ab9..640cb334ac7d8 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -20,16 +20,13 @@ import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.EnumSet; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.Set; import javax.measure.quantity.Length; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.bmwconnecteddrive.internal.dto.Destination; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTrips; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTrip; @@ -40,6 +37,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Windows; import org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileUtils; +import org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileUtils.TimedChannel; import org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileWrapper; import org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileWrapper.ProfileKey; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; @@ -90,44 +88,6 @@ public class VehicleChannelHandler extends BaseThingHandler { protected BMWConnectedDriveOptionProvider optionProvider; - // Charging - protected static class TimedChannel { - TimedChannel(final String time, @Nullable final String timer, final boolean hasDays) { - this.time = time; - this.timer = timer; - this.hasDays = hasDays; - } - - final String time; - final @Nullable String timer; - final boolean hasDays; - } - - @SuppressWarnings("serial") - protected static final Map timedChannels = new HashMap<>() { - { - put(ProfileKey.WINDOWSTART, new TimedChannel(CHARGE_WINDOW_START, null, false)); - put(ProfileKey.WINDOWEND, new TimedChannel(CHARGE_WINDOW_END, null, false)); - put(ProfileKey.TIMER1, new TimedChannel(CHARGE_TIMER1 + CHARGE_DEPARTURE, CHARGE_TIMER1, true)); - put(ProfileKey.TIMER2, new TimedChannel(CHARGE_TIMER2 + CHARGE_DEPARTURE, CHARGE_TIMER2, true)); - put(ProfileKey.TIMER3, new TimedChannel(CHARGE_TIMER3 + CHARGE_DEPARTURE, CHARGE_TIMER3, true)); - put(ProfileKey.OVERRIDE, new TimedChannel(CHARGE_OVERRIDE + CHARGE_DEPARTURE, CHARGE_OVERRIDE, false)); - } - }; - - @SuppressWarnings("serial") - protected static final Map dayChannels = new HashMap<>() { - { - put(DayOfWeek.MONDAY, CHARGE_DAY_MON); - put(DayOfWeek.TUESDAY, CHARGE_DAY_TUE); - put(DayOfWeek.WEDNESDAY, CHARGE_DAY_WED); - put(DayOfWeek.THURSDAY, CHARGE_DAY_THU); - put(DayOfWeek.FRIDAY, CHARGE_DAY_FRI); - put(DayOfWeek.SATURDAY, CHARGE_DAY_SAT); - put(DayOfWeek.SUNDAY, CHARGE_DAY_SUN); - } - }; - // Data Caches protected Optional vehicleStatusCache = Optional.empty(); protected Optional lastTripCache = Optional.empty(); @@ -383,7 +343,7 @@ protected void updateChargeProfile(ChargeProfileWrapper wrapper) { } protected void updateTimedState(ChargeProfileWrapper profile, ProfileKey key) { - final TimedChannel timed = timedChannels.get(key); + final TimedChannel timed = ChargeProfileUtils.getTimedChannel(key); if (timed != null) { final LocalTime time = profile.getTime(key); updateChannel(CHANNEL_GROUP_CHARGE, timed.time, time == null ? UnDefType.UNDEF @@ -401,7 +361,7 @@ protected void updateTimedState(ChargeProfileWrapper profile, ProfileKey key) { updateChannel(CHANNEL_GROUP_CHARGE, timed.timer + CHARGE_DAYS, days == null ? UnDefType.UNDEF : StringType.valueOf(ChargeProfileUtils.formatDays(days))); EnumSet.allOf(DayOfWeek.class).forEach(day -> { - updateChannel(CHANNEL_GROUP_CHARGE, timed.timer + dayChannels.get(day), + updateChannel(CHANNEL_GROUP_CHARGE, timed.timer + ChargeProfileUtils.getDaysChannel(day), days == null ? UnDefType.UNDEF : OnOffType.from(days.contains(day))); }); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index ee75b26e74e79..0e50127915335 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -14,12 +14,9 @@ import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; -import java.time.DayOfWeek; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.concurrent.ScheduledExecutorService; @@ -41,6 +38,9 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; import org.openhab.binding.bmwconnecteddrive.internal.handler.RemoteServiceHandler.ExecutionState; import org.openhab.binding.bmwconnecteddrive.internal.handler.RemoteServiceHandler.RemoteService; +import org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileUtils; +import org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileUtils.ChargeKeyDay; +import org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileUtils.ChargeKeyHour; import org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileWrapper; import org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileWrapper.ProfileKey; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; @@ -95,57 +95,6 @@ public class VehicleHandler extends VehicleChannelHandler { private Optional chargeProfileEdit = Optional.empty(); private Optional chargeProfileSent = Optional.empty(); - private static class ChargeKeyHour { - ChargeKeyHour(final ProfileKey key, final boolean isHour) { - this.key = key; - this.isHour = isHour; - } - - final ProfileKey key; - final boolean isHour; - } - - private static class ChargeKeyDay { - ChargeKeyDay(final ProfileKey key, final DayOfWeek day) { - this.key = key; - this.day = day; - } - - final ProfileKey key; - final DayOfWeek day; - } - - @SuppressWarnings("serial") - private static final Map chargeEnableChannelKeys = new HashMap<>() { - { - VehicleChannelHandler.timedChannels.forEach((key, channel) -> { - put(channel.timer + CHARGE_ENABLED, key); - }); - put(CHARGE_PROFILE_CLIMATE, ProfileKey.CLIMATE); - } - }; - - @SuppressWarnings("serial") - private static final Map chargeTimeChannelKeys = new HashMap<>() { - { - VehicleChannelHandler.timedChannels.forEach((key, channel) -> { - put(channel.time + CHARGE_HOUR, new ChargeKeyHour(key, true)); - put(channel.time + CHARGE_MINUTE, new ChargeKeyHour(key, false)); - }); - } - }; - - @SuppressWarnings("serial") - private static final Map chargeDayChannelKeys = new HashMap<>() { - { - VehicleChannelHandler.dayChannels.forEach((dayOfWeek, dayChannel) -> { - put(CHARGE_TIMER1 + dayChannel, new ChargeKeyDay(ProfileKey.TIMER1, dayOfWeek)); - put(CHARGE_TIMER2 + dayChannel, new ChargeKeyDay(ProfileKey.TIMER2, dayOfWeek)); - put(CHARGE_TIMER3 + dayChannel, new ChargeKeyDay(ProfileKey.TIMER3, dayOfWeek)); - }); - } - }; - public VehicleHandler(Thing thing, BMWConnectedDriveOptionProvider op, String type, boolean imperial) { super(thing, op, type, imperial); } @@ -798,13 +747,13 @@ private void handleChargeProfileCommand(ChannelUID channelUID, Command command) break; } } else if (command instanceof OnOffType) { - final ProfileKey enableKey = chargeEnableChannelKeys.get(id); + final ProfileKey enableKey = ChargeProfileUtils.getEnableKey(id); if (enableKey != null) { profile.setEnabled(enableKey, OnOffType.ON.equals(command)); updateTimedState(profile, enableKey); processed = true; } else { - final ChargeKeyDay chargeKeyDay = chargeDayChannelKeys.get(id); + final ChargeKeyDay chargeKeyDay = ChargeProfileUtils.getKeyDay(id); if (chargeKeyDay != null) { profile.setDayEnabled(chargeKeyDay.key, chargeKeyDay.day, OnOffType.ON.equals(command)); updateTimedState(profile, chargeKeyDay.key); @@ -812,7 +761,7 @@ private void handleChargeProfileCommand(ChannelUID channelUID, Command command) } } } else if (command instanceof DecimalType) { - final ChargeKeyHour keyHour = chargeTimeChannelKeys.get(id); + final ChargeKeyHour keyHour = ChargeProfileUtils.getKeyHour(id); if (keyHour != null) { if (keyHour.isHour) { profile.setHour(keyHour.key, ((DecimalType) command).intValue()); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java index 913b73808b2e9..e4e1b69a14422 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java @@ -12,11 +12,17 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.utils; +import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; + import java.time.DayOfWeek; +import java.util.HashMap; +import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileWrapper.ProfileKey; /** * The {@link ChargeProfileUtils} utility functions for charging profiles @@ -26,6 +32,115 @@ @NonNullByDefault public class ChargeProfileUtils { + // Charging + public static class TimedChannel { + TimedChannel(final String time, @Nullable final String timer, final boolean hasDays) { + this.time = time; + this.timer = timer; + this.hasDays = hasDays; + } + + public final String time; + public final @Nullable String timer; + public final boolean hasDays; + } + + @SuppressWarnings("serial") + private static final Map timedChannels = new HashMap<>() { + { + put(ProfileKey.WINDOWSTART, new TimedChannel(CHARGE_WINDOW_START, null, false)); + put(ProfileKey.WINDOWEND, new TimedChannel(CHARGE_WINDOW_END, null, false)); + put(ProfileKey.TIMER1, new TimedChannel(CHARGE_TIMER1 + CHARGE_DEPARTURE, CHARGE_TIMER1, true)); + put(ProfileKey.TIMER2, new TimedChannel(CHARGE_TIMER2 + CHARGE_DEPARTURE, CHARGE_TIMER2, true)); + put(ProfileKey.TIMER3, new TimedChannel(CHARGE_TIMER3 + CHARGE_DEPARTURE, CHARGE_TIMER3, true)); + put(ProfileKey.OVERRIDE, new TimedChannel(CHARGE_OVERRIDE + CHARGE_DEPARTURE, CHARGE_OVERRIDE, false)); + } + }; + + @SuppressWarnings("serial") + private static final Map dayChannels = new HashMap<>() { + { + put(DayOfWeek.MONDAY, CHARGE_DAY_MON); + put(DayOfWeek.TUESDAY, CHARGE_DAY_TUE); + put(DayOfWeek.WEDNESDAY, CHARGE_DAY_WED); + put(DayOfWeek.THURSDAY, CHARGE_DAY_THU); + put(DayOfWeek.FRIDAY, CHARGE_DAY_FRI); + put(DayOfWeek.SATURDAY, CHARGE_DAY_SAT); + put(DayOfWeek.SUNDAY, CHARGE_DAY_SUN); + } + }; + + public static class ChargeKeyHour { + ChargeKeyHour(final ProfileKey key, final boolean isHour) { + this.key = key; + this.isHour = isHour; + } + + public final ProfileKey key; + public final boolean isHour; + } + + public static class ChargeKeyDay { + ChargeKeyDay(final ProfileKey key, final DayOfWeek day) { + this.key = key; + this.day = day; + } + + public final ProfileKey key; + public final DayOfWeek day; + } + + @SuppressWarnings("serial") + private static final Map chargeEnableChannelKeys = new HashMap<>() { + { + timedChannels.forEach((key, channel) -> { + put(channel.timer + CHARGE_ENABLED, key); + }); + put(CHARGE_PROFILE_CLIMATE, ProfileKey.CLIMATE); + } + }; + + @SuppressWarnings("serial") + private static final Map chargeTimeChannelKeys = new HashMap<>() { + { + timedChannels.forEach((key, channel) -> { + put(channel.time + CHARGE_HOUR, new ChargeKeyHour(key, true)); + put(channel.time + CHARGE_MINUTE, new ChargeKeyHour(key, false)); + }); + } + }; + + @SuppressWarnings("serial") + private static final Map chargeDayChannelKeys = new HashMap<>() { + { + dayChannels.forEach((dayOfWeek, dayChannel) -> { + put(CHARGE_TIMER1 + dayChannel, new ChargeKeyDay(ProfileKey.TIMER1, dayOfWeek)); + put(CHARGE_TIMER2 + dayChannel, new ChargeKeyDay(ProfileKey.TIMER2, dayOfWeek)); + put(CHARGE_TIMER3 + dayChannel, new ChargeKeyDay(ProfileKey.TIMER3, dayOfWeek)); + }); + } + }; + + public static @Nullable TimedChannel getTimedChannel(ProfileKey key) { + return timedChannels.get(key); + } + + public static @Nullable String getDaysChannel(DayOfWeek day) { + return dayChannels.get(day); + } + + public static @Nullable ProfileKey getEnableKey(final String id) { + return chargeEnableChannelKeys.get(id); + } + + public static @Nullable ChargeKeyDay getKeyDay(final String id) { + return chargeDayChannelKeys.get(id); + } + + public static @Nullable ChargeKeyHour getKeyHour(final String id) { + return chargeTimeChannelKeys.get(id); + } + public static String formatDays(final Set weekdays) { return weekdays.stream().map(day -> Constants.DAYS.get(day)).collect(Collectors.joining(Constants.COMMA)); } From 8ded9287e1f5921038788deabb2c710d6610d0aa Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Mon, 22 Feb 2021 20:35:05 +0100 Subject: [PATCH 129/176] fix racecondition resulting in 'NoSuchElementException: No value present' Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../handler/RemoteServiceHandler.java | 61 ++++++++++--------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java index b93d27484c8f5..2fc1839165ec4 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -118,20 +118,22 @@ boolean execute(RemoteService service, String... data) { } public void getState() { - serviceExecuting.ifPresentOrElse(service -> { - if (counter >= GIVEUP_COUNTER) { - logger.warn("Giving up updating state for {} after {} times", service, GIVEUP_COUNTER); - reset(); - // immediately refresh data - handler.getData(); - } - counter++; - final MultiMap dataMap = new MultiMap(); - dataMap.add(SERVICE_TYPE, serviceExecuting.get()); - proxy.get(serviceExecutionStateAPI, dataMap, this); - }, () -> { - logger.warn("No Service executed to get state"); - }); + synchronized (this) { + serviceExecuting.ifPresentOrElse(service -> { + if (counter >= GIVEUP_COUNTER) { + logger.warn("Giving up updating state for {} after {} times", service, GIVEUP_COUNTER); + reset(); + // immediately refresh data + handler.getData(); + } + counter++; + final MultiMap dataMap = new MultiMap(); + dataMap.add(SERVICE_TYPE, service); + proxy.get(serviceExecutionStateAPI, dataMap, this); + }, () -> { + logger.warn("No Service executed to get state"); + }); + } } @Override @@ -141,13 +143,16 @@ public void onResponse(@Nullable String result) { ExecutionStatusContainer esc = Converter.getGson().fromJson(result, ExecutionStatusContainer.class); if (esc != null && esc.executionStatus != null) { String status = esc.executionStatus.status; - handler.updateRemoteExecutionStatus(serviceExecuting.get(), status); - if (ExecutionState.EXECUTED.name().equals(status)) { - // refresh loop ends - update of status handled in the normal refreshInterval. Earlier update - // doesn't - // show better results! - reset(); - return; + synchronized (this) { + handler.updateRemoteExecutionStatus(serviceExecuting.orElse(null), status); + if (ExecutionState.EXECUTED.name().equals(status)) { + // refresh loop ends - update of status handled in the normal refreshInterval. Earlier + // update + // doesn't + // show better results! + reset(); + return; + } } } } catch (JsonSyntaxException jse) { @@ -160,15 +165,15 @@ public void onResponse(@Nullable String result) { @Override public void onError(NetworkError error) { - handler.updateRemoteExecutionStatus(serviceExecuting.get(), - ExecutionState.ERROR.name() + Constants.SPACE + Integer.toString(error.status)); - reset(); + synchronized (this) { + handler.updateRemoteExecutionStatus(serviceExecuting.orElse(null), + ExecutionState.ERROR.name() + Constants.SPACE + Integer.toString(error.status)); + reset(); + } } private void reset() { - synchronized (this) { - serviceExecuting = Optional.empty(); - counter = 0; - } + serviceExecuting = Optional.empty(); + counter = 0; } } From 1d0ad87933789bcefbc30ca6aa8238f48f32bae2 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Tue, 23 Feb 2021 12:19:36 +0100 Subject: [PATCH 130/176] fix redundant refresh of GROUP_LASTTRIP, include GROUP_DESTINATION into refresh Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../internal/handler/ConnectedDriveProxy.java | 1 - .../bmwconnecteddrive/internal/handler/VehicleHandler.java | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index 1a5654318429f..e3829142a4d2b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -129,7 +129,6 @@ private synchronized void call(final String url, final boolean post, final @Null if (encoded != null) { req.content(new StringContentProvider(CONTENT_TYPE_URL_ENCODED, encoded, Charset.defaultCharset())); } - ; } else { completeUrl = encoded == null ? url : url + Constants.QUESTION + encoded; req = httpClient.newRequest(completeUrl); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 0e50127915335..798caa61ec88b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -109,10 +109,8 @@ public void handleCommand(ChannelUID channelUID, Command command) { lastTripCache.ifPresent(lastTrip -> lastTripCallback.onResponse(lastTrip)); } else if (CHANNEL_GROUP_LIFETIME.equals(group)) { allTripsCache.ifPresent(allTrips -> allTripsCallback.onResponse(allTrips)); - } else if (CHANNEL_GROUP_LAST_TRIP.equals(group)) { - lastTripCache.ifPresent(lastTrip -> lastTripCallback.onResponse(lastTrip)); - } else if (CHANNEL_GROUP_LAST_TRIP.equals(group)) { - lastTripCache.ifPresent(lastTrip -> lastTripCallback.onResponse(lastTrip)); + } else if (CHANNEL_GROUP_DESTINATION.equals(group)) { + destinationCache.ifPresent(destination -> destinationCallback.onResponse(destination)); } else if (CHANNEL_GROUP_STATUS.equals(group)) { vehicleStatusCache.ifPresent(vehicleStatus -> vehicleStatusCallback.onResponse(vehicleStatus)); } else if (CHANNEL_GROUP_CHARGE.equals(group)) { From f0f0b207be188cd414143036542cb7d7a56fb4e5 Mon Sep 17 00:00:00 2001 From: Bernd Date: Fri, 5 Mar 2021 01:04:36 +0100 Subject: [PATCH 131/176] solve remaining checkstyle issues Signed-off-by: Bernd --- .../internal/ConnectedDriveConfiguration.java | 2 +- .../internal/ConnectedDriveConstants.java | 2 +- .../ConnectedDriveHandlerFactory.java | 2 +- .../internal/VehicleConfiguration.java | 2 +- .../internal/action/ChargeProfileActions.java | 2 +- .../internal/discovery/VehicleDiscovery.java | 2 +- .../internal/dto/Destination.java | 2 +- .../internal/dto/DestinationContainer.java | 2 +- .../internal/dto/NetworkError.java | 2 +- .../internal/dto/auth/AuthResponse.java | 2 +- .../internal/dto/charge/ChargeProfile.java | 2 +- .../internal/dto/charge/ChargingWindow.java | 2 +- .../internal/dto/charge/Timer.java | 2 +- .../internal/dto/charge/WeeklyPlanner.java | 2 +- .../internal/dto/compat/CBSMessageCompat.java | 2 +- .../internal/dto/compat/CCMMessageCompat.java | 2 +- .../dto/compat/VehicleAttributes.java | 2 +- .../compat/VehicleAttributesContainer.java | 2 +- .../internal/dto/compat/VehicleMessages.java | 2 +- .../internal/dto/discovery/Dealer.java | 2 +- .../internal/dto/discovery/Vehicle.java | 2 +- .../dto/discovery/VehiclesContainer.java | 2 +- .../internal/dto/remote/ExecutionStatus.java | 2 +- .../dto/remote/ExecutionStatusContainer.java | 2 +- .../internal/dto/statistics/AllTrips.java | 2 +- .../dto/statistics/AllTripsContainer.java | 2 +- .../statistics/CommunityChargeCycleEntry.java | 2 +- .../CommunityEletricDistanceEntry.java | 2 +- .../dto/statistics/CommunityPowerEntry.java | 2 +- .../internal/dto/statistics/LastTrip.java | 2 +- .../dto/statistics/LastTripContainer.java | 2 +- .../internal/dto/status/CBSMessage.java | 2 +- .../internal/dto/status/CCMMessage.java | 2 +- .../internal/dto/status/Doors.java | 2 +- .../internal/dto/status/Position.java | 2 +- .../internal/dto/status/VehicleStatus.java | 2 +- .../dto/status/VehicleStatusContainer.java | 2 +- .../internal/dto/status/Windows.java | 2 +- .../BMWConnectedDriveOptionProvider.java | 2 +- .../handler/ByteResponseCallback.java | 2 +- .../handler/ConnectedDriveBridgeHandler.java | 2 +- .../internal/handler/ConnectedDriveProxy.java | 2 +- .../handler/RemoteServiceHandler.java | 2 +- .../internal/handler/ResponseCallback.java | 2 +- .../handler/StringResponseCallback.java | 2 +- .../internal/handler/Token.java | 2 +- .../handler/VehicleChannelHandler.java | 2 +- .../internal/handler/VehicleHandler.java | 3 +- .../internal/handler/simulation/Injector.java | 2 +- .../internal/utils/BimmerConstants.java | 2 +- .../internal/utils/ChargeProfileUtils.java | 28 +++++++++---------- .../internal/utils/ChargeProfileWrapper.java | 9 ++---- .../internal/utils/Constants.java | 2 +- .../internal/utils/Converter.java | 2 +- .../internal/utils/HTTPConstants.java | 2 +- .../internal/utils/ImageProperties.java | 2 +- .../internal/utils/VehicleStatusUtils.java | 2 +- .../internal/discovery/DiscoveryTest.java | 2 +- .../internal/dto/ChargeProfileTest.java | 2 +- .../internal/dto/ConnectedDriveTest.java | 2 +- .../internal/dto/DestinationTest.java | 2 +- .../internal/dto/LastTripTest.java | 2 +- .../internal/dto/LifetimeWrapper.java | 2 +- .../internal/dto/RemoteStatusTest.java | 2 +- .../internal/dto/StatusWrapper.java | 2 +- .../internal/dto/TripWrapper.java | 2 +- .../internal/dto/VehicleStatusTest.java | 2 +- .../internal/handler/AllTripTests.java | 2 +- .../internal/handler/AuthTest.java | 2 +- .../internal/handler/ChargeProfileTest.java | 2 +- .../internal/handler/ErrorResponseTest.java | 2 +- .../internal/handler/FingerprintTest.java | 2 +- .../internal/handler/LastTripTests.java | 2 +- .../internal/handler/SimulationTest.java | 2 +- .../internal/handler/VehicleTests.java | 2 +- .../internal/util/FileReader.java | 2 +- .../internal/util/LocaleTest.java | 2 +- 77 files changed, 92 insertions(+), 96 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConfiguration.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConfiguration.java index cf2dfb98baef0..c082bff346edb 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConfiguration.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConfiguration.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 503e646cbb5f3..1de00765eb3d7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java index c93fd972f74c5..d57fead76fbc9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/VehicleConfiguration.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/VehicleConfiguration.java index 70d18cbf438a6..2e31313256291 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/VehicleConfiguration.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/VehicleConfiguration.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java index cd558bfde7787..e51fcfbdec2d7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java index 3c0c13bddc6ec..def54d6d7df3c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java index eb6f29705e71c..2637f79b64183 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DestinationContainer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DestinationContainer.java index ea13ef7a05b46..882d7c0d2a454 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DestinationContainer.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DestinationContainer.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/NetworkError.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/NetworkError.java index 51b6d41699927..d751a73c66543 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/NetworkError.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/NetworkError.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/auth/AuthResponse.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/auth/AuthResponse.java index ef3cbcf49d0fc..7363d49890583 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/auth/AuthResponse.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/auth/AuthResponse.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargeProfile.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargeProfile.java index 34856a6b2ec0c..40da7f895265f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargeProfile.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargeProfile.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargingWindow.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargingWindow.java index cfa4ad82be67d..b303ddd247c70 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargingWindow.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/ChargingWindow.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java index 6cab9edd67a08..65a3f23c8fdcc 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/Timer.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/WeeklyPlanner.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/WeeklyPlanner.java index f364274803c37..c169e1a289f0f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/WeeklyPlanner.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/charge/WeeklyPlanner.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/CBSMessageCompat.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/CBSMessageCompat.java index 6c2fa7214bbba..39677a381e002 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/CBSMessageCompat.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/CBSMessageCompat.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/CCMMessageCompat.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/CCMMessageCompat.java index 8271fe1094dcd..5e0aafc73a162 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/CCMMessageCompat.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/CCMMessageCompat.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributes.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributes.java index 75c4af8530afc..72cdde1e7bc1e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributes.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributes.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java index 54e22a528bc8e..02f6b2446be54 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleMessages.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleMessages.java index 4c70469a45a5a..7b76135000ddb 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleMessages.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleMessages.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Dealer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Dealer.java index a6c3c788bc174..1b1392baef5c9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Dealer.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Dealer.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Vehicle.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Vehicle.java index 6d453767618e9..f963b7d7f1b52 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Vehicle.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/Vehicle.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/VehiclesContainer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/VehiclesContainer.java index 3ebe21dd79fbc..9c7a1a78da37e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/VehiclesContainer.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/discovery/VehiclesContainer.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatus.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatus.java index 40247857a9521..71ff06627a225 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatus.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatus.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatusContainer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatusContainer.java index 8f44924e1913d..eca56f1dd8adf 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatusContainer.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatusContainer.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/AllTrips.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/AllTrips.java index 3cb1ed332d909..c2417e5a0d566 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/AllTrips.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/AllTrips.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/AllTripsContainer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/AllTripsContainer.java index 0df724542e3a1..607b79ba1146a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/AllTripsContainer.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/AllTripsContainer.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityChargeCycleEntry.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityChargeCycleEntry.java index c5e2473e5b9a3..a2e4b6aa1c595 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityChargeCycleEntry.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityChargeCycleEntry.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityEletricDistanceEntry.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityEletricDistanceEntry.java index 754e1050e13b1..6c525fdadba0c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityEletricDistanceEntry.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityEletricDistanceEntry.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityPowerEntry.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityPowerEntry.java index 0c35ab55cc4e0..2e4f57e12fbc7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityPowerEntry.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/CommunityPowerEntry.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTrip.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTrip.java index 23f8a58158d33..69f7106c38c49 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTrip.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTrip.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripContainer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripContainer.java index c17f774fb42d3..86e46c9377b73 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripContainer.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/statistics/LastTripContainer.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java index 5ef08fdb45604..e95eeea807284 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CCMMessage.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CCMMessage.java index 67f596384ff3f..d9b8bb78bc6f7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CCMMessage.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CCMMessage.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Doors.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Doors.java index bf452fc0265e1..afab4e2c6ec0a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Doors.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Doors.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java index 83e4d44930d07..43b89f7b749dd 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java index 7f6beeb5fb45b..57119de591d23 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatus.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusContainer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusContainer.java index 26d943d48aaab..673930bf6c6ab 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusContainer.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/VehicleStatusContainer.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Windows.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Windows.java index 2d4f386ffdfae..a530f31ead6a6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Windows.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Windows.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BMWConnectedDriveOptionProvider.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BMWConnectedDriveOptionProvider.java index 50eed64c107b1..82690ea677c32 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BMWConnectedDriveOptionProvider.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/BMWConnectedDriveOptionProvider.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ByteResponseCallback.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ByteResponseCallback.java index 88af1c866fd52..7aafc76dbce78 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ByteResponseCallback.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ByteResponseCallback.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java index 38f9030d0286e..9e7b57f194a15 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index e3829142a4d2b..2830331b7084e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java index 2fc1839165ec4..5c0ba684e53ba 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ResponseCallback.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ResponseCallback.java index 798cccbc083ea..5785cb2454d2f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ResponseCallback.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ResponseCallback.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/StringResponseCallback.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/StringResponseCallback.java index ba7157212cd9e..45b50913a9465 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/StringResponseCallback.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/StringResponseCallback.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java index 309d0e006eed8..22e42170410d0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/Token.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 640cb334ac7d8..e914b6ed1807e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 798caa61ec88b..fd59ffa452935 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. @@ -715,7 +715,6 @@ public void onError(NetworkError error) { } private void handleChargeProfileCommand(ChannelUID channelUID, Command command) { - if (chargeProfileEdit.isEmpty()) { chargeProfileEdit = getChargeProfileWrapper(); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/simulation/Injector.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/simulation/Injector.java index d736d4dbef898..fdc7208210fc3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/simulation/Injector.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/simulation/Injector.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java index 34461c123d94a..5c0ed6438faef 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/BimmerConstants.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java index e4e1b69a14422..a6b3c50c17085 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. @@ -46,7 +46,7 @@ public static class TimedChannel { } @SuppressWarnings("serial") - private static final Map timedChannels = new HashMap<>() { + private static final Map TIMED_CHANNELS = new HashMap<>() { { put(ProfileKey.WINDOWSTART, new TimedChannel(CHARGE_WINDOW_START, null, false)); put(ProfileKey.WINDOWEND, new TimedChannel(CHARGE_WINDOW_END, null, false)); @@ -58,7 +58,7 @@ public static class TimedChannel { }; @SuppressWarnings("serial") - private static final Map dayChannels = new HashMap<>() { + private static final Map DAY_CHANNELS = new HashMap<>() { { put(DayOfWeek.MONDAY, CHARGE_DAY_MON); put(DayOfWeek.TUESDAY, CHARGE_DAY_TUE); @@ -91,9 +91,9 @@ public static class ChargeKeyDay { } @SuppressWarnings("serial") - private static final Map chargeEnableChannelKeys = new HashMap<>() { + private static final Map CHARGE_ENABLED_CHANNEL_KEYS = new HashMap<>() { { - timedChannels.forEach((key, channel) -> { + TIMED_CHANNELS.forEach((key, channel) -> { put(channel.timer + CHARGE_ENABLED, key); }); put(CHARGE_PROFILE_CLIMATE, ProfileKey.CLIMATE); @@ -101,9 +101,9 @@ public static class ChargeKeyDay { }; @SuppressWarnings("serial") - private static final Map chargeTimeChannelKeys = new HashMap<>() { + private static final Map CHARGE_TIME_CHANNEL_KEYS = new HashMap<>() { { - timedChannels.forEach((key, channel) -> { + TIMED_CHANNELS.forEach((key, channel) -> { put(channel.time + CHARGE_HOUR, new ChargeKeyHour(key, true)); put(channel.time + CHARGE_MINUTE, new ChargeKeyHour(key, false)); }); @@ -111,9 +111,9 @@ public static class ChargeKeyDay { }; @SuppressWarnings("serial") - private static final Map chargeDayChannelKeys = new HashMap<>() { + private static final Map CHARGE_DAYS_CHANNEL_KEYS = new HashMap<>() { { - dayChannels.forEach((dayOfWeek, dayChannel) -> { + DAY_CHANNELS.forEach((dayOfWeek, dayChannel) -> { put(CHARGE_TIMER1 + dayChannel, new ChargeKeyDay(ProfileKey.TIMER1, dayOfWeek)); put(CHARGE_TIMER2 + dayChannel, new ChargeKeyDay(ProfileKey.TIMER2, dayOfWeek)); put(CHARGE_TIMER3 + dayChannel, new ChargeKeyDay(ProfileKey.TIMER3, dayOfWeek)); @@ -122,23 +122,23 @@ public static class ChargeKeyDay { }; public static @Nullable TimedChannel getTimedChannel(ProfileKey key) { - return timedChannels.get(key); + return TIMED_CHANNELS.get(key); } public static @Nullable String getDaysChannel(DayOfWeek day) { - return dayChannels.get(day); + return DAY_CHANNELS.get(day); } public static @Nullable ProfileKey getEnableKey(final String id) { - return chargeEnableChannelKeys.get(id); + return CHARGE_ENABLED_CHANNEL_KEYS.get(id); } public static @Nullable ChargeKeyDay getKeyDay(final String id) { - return chargeDayChannelKeys.get(id); + return CHARGE_DAYS_CHANNEL_KEYS.get(id); } public static @Nullable ChargeKeyHour getKeyHour(final String id) { - return chargeTimeChannelKeys.get(id); + return CHARGE_TIME_CHANNEL_KEYS.get(id); } public static String formatDays(final Set weekdays) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java index 28d20cc38f4a3..4b67645a4c92c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. @@ -12,10 +12,8 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.utils; -import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; import static org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileWrapper.ProfileKey.*; -import static org.openhab.binding.bmwconnecteddrive.internal.utils.Constants.NULL_LOCAL_TIME; -import static org.openhab.binding.bmwconnecteddrive.internal.utils.Constants.TIME_FORMATER; +import static org.openhab.binding.bmwconnecteddrive.internal.utils.Constants.*; import java.time.DayOfWeek; import java.time.LocalTime; @@ -68,7 +66,7 @@ public enum ProfileKey { WINDOWEND } - final protected ProfileType type; + protected final ProfileType type; private Optional mode = Optional.empty(); private Optional preference = Optional.empty(); @@ -89,7 +87,6 @@ public static Optional fromJson(final String content) { } private ChargeProfileWrapper(final ChargeProfile profile) { - final WeeklyPlanner planner; if (profile.weeklyPlanner != null) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java index 8286b3b178c80..b084a00ca8448 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java index 0fe90229558c2..0351c28db0e7e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/HTTPConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/HTTPConstants.java index 1d2062b757ed3..62f878691a238 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/HTTPConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/HTTPConstants.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ImageProperties.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ImageProperties.java index 7fc44f7fc7c18..6b943a2fd2998 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ImageProperties.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ImageProperties.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/VehicleStatusUtils.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/VehicleStatusUtils.java index f537c71386c0b..03f1b4e314c17 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/VehicleStatusUtils.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/VehicleStatusUtils.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java index 2e3c72bf31318..dacf3224ef64d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ChargeProfileTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ChargeProfileTest.java index ed8dc244e6847..7fdca008eb436 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ChargeProfileTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ChargeProfileTest.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java index 5ec73610835fa..03dd102e8f15a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/ConnectedDriveTest.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DestinationTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DestinationTest.java index 9bcf8cbe54004..0f9c0f82b0189 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DestinationTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/DestinationTest.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LastTripTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LastTripTest.java index a8fa35fbd96bb..0ac8bcf08505b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LastTripTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LastTripTest.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java index 7d0abe62c9cbe..4a74867410a72 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/RemoteStatusTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/RemoteStatusTest.java index b0c07c3a236d0..3127b0494891e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/RemoteStatusTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/RemoteStatusTest.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index 5764079858694..b9c1e25a3e5ab 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java index 1a8feed605df3..b60bae9c451b7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleStatusTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleStatusTest.java index 06f546b0b2bc1..b801415607dec 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleStatusTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/VehicleStatusTest.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AllTripTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AllTripTests.java index af681833280fe..98289e029dda6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AllTripTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AllTripTests.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java index 5ab85e786b62c..3b34f58610c05 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/AuthTest.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java index 4b0841e6dcd50..e85f1cd051c9f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ErrorResponseTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ErrorResponseTest.java index 56d32c9e19fd6..0fecdcd922544 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ErrorResponseTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ErrorResponseTest.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/FingerprintTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/FingerprintTest.java index 6b3f088ae07bb..564bb43c5294e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/FingerprintTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/FingerprintTest.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/LastTripTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/LastTripTests.java index 5b5fe1d70aee5..d9fee9778d5cd 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/LastTripTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/LastTripTests.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/SimulationTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/SimulationTest.java index 485c557224dc8..897a5248b0885 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/SimulationTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/SimulationTest.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java index b70a1dd16cbe3..bef3e321bf004 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/FileReader.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/FileReader.java index 9ccceda764fe2..2758042ca2c2f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/FileReader.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/FileReader.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java index ee024bd364c14..a4256c55c0bfc 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/util/LocaleTest.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. From 1a206dfef877ca6d8533e03fdada97db373f9785 Mon Sep 17 00:00:00 2001 From: Bernd Date: Fri, 5 Mar 2021 12:23:16 +0100 Subject: [PATCH 132/176] adapt readme, added service and checkcontrol details Signed-off-by: Bernd --- .../README.md | 110 ++++++++++++------ .../internal/ConnectedDriveConstants.java | 1 + .../compat/VehicleAttributesContainer.java | 3 + .../internal/dto/status/CBSMessage.java | 11 ++ .../internal/dto/status/CCMMessage.java | 4 +- .../handler/VehicleChannelHandler.java | 10 ++ .../thing/check-control-channel-types.xml | 4 + .../OH-INF/thing/check-control-group.xml | 1 + .../resources/OH-INF/thing/service-group.xml | 1 + .../internal/dto/StatusWrapper.java | 23 ++++ .../internal/handler/VehicleTests.java | 8 +- 11 files changed, 136 insertions(+), 40 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index c5e56d959bc61..84f9e6aa19701 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -194,6 +194,7 @@ If more than one service is scheduled in the future the channel _name_ contains | Channel Label | Channel ID | Type | Access | |--------------------------------|---------------------|----------------|------------| | Service Name | name | String | Read/Write | +| Service Details | details | String | Read | | Service Date | date | Number | Read | | Mileage till Service | mileage | Number:Length | Read | @@ -209,6 +210,7 @@ If more than one message is active the channel _name_ contains all active messag | Channel Label | Channel ID | Type | Access | |---------------------------------|---------------------|----------------|------------| | CheckControl Description | name | String | Read/Write | +| CheckControl Details | details | String | Read | | Mileage Occurrence | mileage | Number:Length | Read | #### Doors Details @@ -272,7 +274,8 @@ Charging options with date and time for preferred time windows and charging mode * Channel Group ID is **charge** * Available for electric and hybrid vehicles -* Read-only values +* Read/Write access for UI. Use (Charge Profile Actions)[#charge_profile_ction] in rules +* There are 3 Timers available. Replace _X_ with number 1,2 or 3 to target the correct timer | Channel Label | Channel Group ID | Channel ID | Type | |---------------------------------------|------------------|---------------------------|----------| @@ -285,39 +288,17 @@ Charging options with date and time for preferred time windows and charging mode | Charging Window End Time Hour | charge | window-end-hour | Number | | Charging Window End Time Minute | charge | window-end-minute | Number | | Air Conditioning at Departure Time | charge | profile-climate | Switch | -| Timer 1: Enabled | charge | timer1-enabled | Switch | -| Timer 1: Departure Time | charge | timer1-departure | DateTime | -| Timer 1: Departure Time Hour | charge | timer1-departure-hour | Number | -| Timer 1: Departure Time Minute | charge | timer1-departure-minute | Number | -| Timer 1: Monday | charge | timer1-day-mon | Switch | -| Timer 1: Tuesday | charge | timer1-day-tue | Switch | -| Timer 1: Wednesday | charge | timer1-day-wed | Switch | -| Timer 1: Thursday | charge | timer1-day-thu | Switch | -| Timer 1: Friday | charge | timer1-day-fri | Switch | -| Timer 1: Saturday | charge | timer1-day-sat | Switch | -| Timer 1: Sunday | charge | timer1-day-sun | Switch | -| Timer 2: Enabled | charge | timer2-enabled | Switch | -| Timer 2: Departure Time | charge | timer2-departure | DateTime | -| Timer 2: Departure Time Hour | charge | timer2-departure-hour | Number | -| Timer 2: Departure Time Minute | charge | timer2-departure-minute | Number | -| Timer 2: Monday | charge | timer2-day-mon | Switch | -| Timer 2: Tuesday | charge | timer2-day-tue | Switch | -| Timer 2: Wednesday | charge | timer2-day-wed | Switch | -| Timer 2: Thursday | charge | timer2-day-thu | Switch | -| Timer 2: Friday | charge | timer2-day-fri | Switch | -| Timer 2: Saturday | charge | timer2-day-sat | Switch | -| Timer 2: Sunday | charge | timer2-day-sun | Switch | -| Timer 3: Enabled | charge | timer3-enabled | Switch | -| Timer 3: Departure Time | charge | timer3-departure | DateTime | -| Timer 3: Departure Time Hour | charge | timer3-departure-hour | Number | -| Timer 3: Departure Time Minute | charge | timer3-departure-minute | Number | -| Timer 3: Monday | charge | timer3-day-mon | Switch | -| Timer 3: Tuesday | charge | timer3-day-tue | Switch | -| Timer 3: Wednesday | charge | timer3-day-wed | Switch | -| Timer 3: Thursday | charge | timer3-day-thu | Switch | -| Timer 3: Friday | charge | timer3-day-fri | Switch | -| Timer 3: Saturday | charge | timer3-day-sat | Switch | -| Timer 3: Sunday | charge | timer3-day-sun | Switch | +| Timer _X_: Enabled | charge | timer_X_-enabled | Switch | +| Timer _X_: Departure Time | charge | timer_X_-departure | DateTime | +| Timer _X_: Departure Time Hour | charge | timer_X_-departure-hour | Number | +| Timer _X_: Departure Time Minute | charge | timer_X_-departure-minute | Number | +| Timer _X_: Monday | charge | timer_X_-day-mon | Switch | +| Timer _X_: Tuesday | charge | timer_X_-day-tue | Switch | +| Timer _X_: Wednesday | charge | timer_X_-day-wed | Switch | +| Timer _X_: Thursday | charge | timer_X_-day-thu | Switch | +| Timer _X_: Friday | charge | timer_X_-day-fri | Switch | +| Timer _X_: Saturday | charge | timer_X_-day-sat | Switch | +| Timer _X_: Sunday | charge | timer_X_-day-sun | Switch | | Override Timer: Enabled | charge | override-enabled | Switch | | Override Timer: Departure Time | charge | override-departure | DateTime | | Override Timer: Departure Time Hour | charge | override-departure-hour | Number | @@ -441,6 +422,49 @@ The possible values are the same mentioned in [Thing Configuration](#thing-confi | Image Viewport | view | String | Write | | Image Picture Size | size | Number | Write | +## Rule Actions + +## Charge Profile Action + +The Charge Profile is accessible and modifyable in rules via action. +Get the corresponding action from your car using the Thing ID + +* bmwconnecteddrive - don't change +* bev_rex - (Thing UID)[#things] of your car +* user - Thing ID of the (Bridge)[#bridge] +* i3 - Thing ID of your Car + +``` + val profile = getActions("chargeprofile", "bmwconnecteddrive:bev_rex:user:i3") +``` + +Like in the Charge Profile Channels 3 Timers are provided. Replace _X_ with 1, 2 or 3 to address the right timer. + +| Function | Parameters | Returns | Description | +|---------------------------------------|------------------|---------------------------|------------------------------------------------------------| +| getClimatizationEnabled | void | Boolean | Returns the enabled state of climatization | +| setClimatizationEnabled | Boolean | void | Sets the enabled state of climatization | +| getChargingMode | void | String | Gets the charging-mode | +| setChargingMode | String | void | Sets the charging-mode | +| getPreferredWindowStart | void | LocalTime | Returns the preferred charging-window start time | +| setPreferredWindowStart | LocalTime | void | Sets the preferred charging-window start time | +| getPreferredWindowEnd | void | LocalTime | Returns the preferred charging-window end time | +| setPreferredWindowEnd | LocalTime | void | Sets the preferred charging-window end time | +| getTimer_X_Enabled | void | Boolean | Returns the enabled state of timer_X_ | +| setTimer_X_Enabled | Boolean | void | Returns the enabled state of timer_X_ | +| getTimer_X_Departure | void | LocalTime | Returns the departure time of timer_X_ | +| setTimer_X_Departure | LocalTime | void | Sets the timer_X_ departure time | +| getTimer_X_Days | void | Set | Returns the days of week timer_X_ is enabled for | +| setTimer_X_Days | Set | void | sets the days of week timer_X_ is enabled for | +| getOverrideTimerEnabled | void | Boolean | Returns the enabled state of override timer | +| setOverrideTimerEnabled | Boolean | void | Sets the enabled state of override timer | +| getOverrideTimerDeparture | void | LocalTime | Returns the departure time of override timer | +| setOverrideTimerDeparture | LocalTime | void | Sets the override timer departure time | +| getOverrideTimerDays | void | Set | Returns the days of week the overrideTimer is enabled for | +| setOverrideTimerDays | Set | void | Sets the days of week the overrideTimer is enabled for | +| cancel | void | void | Sends the charging profile to the vehicle | +| send | void | void | Cancel current edit of charging profile | + ## Further Descriptions @@ -586,10 +610,12 @@ String i3RearWindow "Rear Window [%s]" String i3Sunroof "Sunroof [%s]" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:doors#sunroof" } String i3ServiceName "Service Name [%s]" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:service#name" } +String i3ServiceDetails "Service Details [%s]" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:service#details" } Number:Length i3ServiceMileage "Service Mileage [%d %unit%]" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:service#mileage" } DateTime i3ServiceDate "Service Date [%1$tb %1$tY]" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:service#date" } String i3CCName "CheckControl Name [%s]" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:check#name" } +String i3CCDetails "CheckControl Details [%s]" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:check#details" } Number:Length i3CCMileage "CheckControl Mileage [%d %unit%]" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:check#mileage" } String i3DestName "Destination [%s]" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:destination#name" } @@ -785,6 +811,22 @@ sitemap BMW label="BMW" { } ``` +### Action example + +``` + val profile = getActions("chargeprofile", "bmwconnecteddrive:bev_rex:user:i3") + val now = ZonedDateTime.now.toLocalTime + profile.setChargingMode("DELAYED_CHARGING") + profile.setTimer1Departure(now.minusHours(2)) + profile.setTimer1Days(java.util.Set()) + profile.setTimer1Enabled(true) + profile.setTimer2Enabled(false) + profile.setTimer3Enabled(false) + profile.setPreferredWindowStart(now.minusHours(6)) + profile.setPreferredWindowEnd(now.minusHours(2)) + profile.send() +``` + ## Credits This work is based on the project of [Bimmer Connected](https://github.com/bimmerconnected/bimmer_connected). diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 1de00765eb3d7..0aa3aa8237c70 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -104,6 +104,7 @@ public enum ChargingPreference { // Generic Constants for several groups public static final String NAME = "name"; + public static final String DETAILS = "details"; public static final String DATE = "date"; public static final String MILEAGE = "mileage"; public static final String GPS = "gps"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java index 02f6b2446be54..405863121df33 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java @@ -20,6 +20,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Position; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; /** @@ -78,6 +79,7 @@ public String transform() { vehicleMessages.ccmMessages.forEach(entry -> { CCMMessage ccmM = new CCMMessage(); ccmM.ccmDescriptionShort = entry.text; + ccmM.ccmDescriptionLong = Constants.HYPHEN; ccmM.ccmMileage = entry.unitOfLengthRemaining; ccml.add(ccmM); }); @@ -91,6 +93,7 @@ public String transform() { vehicleMessages.cbsMessages.forEach(entry -> { CBSMessage cbsm = new CBSMessage(); cbsm.cbsType = entry.text; + cbsm.cbsDescription = entry.description; cbsm.cbsDueDate = entry.date; cbsm.cbsRemainingMileage = entry.unitOfLengthRemaining; cbsl.add(cbsm); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java index e95eeea807284..19789c0729e0d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java @@ -48,6 +48,17 @@ public String getType() { return cbsTypeConverted; } + public String getDescription() { + if (cbsTypeConverted == null) { + if (cbsType == null) { + cbsTypeConverted = Constants.INVALID; + } else { + cbsTypeConverted = cbsDescription; + } + } + return cbsTypeConverted; + } + @Override public String toString() { return new StringBuilder(cbsDueDate).append(Constants.HYPHEN).append(cbsRemainingMileage) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CCMMessage.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CCMMessage.java index d9b8bb78bc6f7..4d9a43d3b26be 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CCMMessage.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CCMMessage.java @@ -20,11 +20,11 @@ * @author Bernd Weymann - Initial contribution */ public class CCMMessage { - public String ccmDescriptionLong = Constants.INVALID;// ": "You can continue driving. Check tyre pressure when tyres - // are cold and adjust // if necessary. Perform reset after adjustment. See Owner's Handbook for further // information.", public String ccmDescriptionShort = Constants.INVALID;// ": "Tyre pressure notification", + public String ccmDescriptionLong = Constants.INVALID;// ": "You can continue driving. Check tyre pressure when tyres + // are cold and adjust public int ccmId = -1;// ": 955, public int ccmMileage = -1;// ": 41544 } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index e914b6ed1807e..943e1f1b6e152 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -27,6 +27,7 @@ import javax.measure.quantity.Length; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; import org.openhab.binding.bmwconnecteddrive.internal.dto.Destination; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTrips; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTrip; @@ -139,11 +140,13 @@ protected void updateCheckControls(List ccl) { // add all elements to options checkControlList = ccl; List ccmDescriptionOptions = new ArrayList<>(); + List ccmDetailsOptions = new ArrayList<>(); List ccmMileageOptions = new ArrayList<>(); boolean isSelectedElementIn = false; int index = 0; for (CCMMessage ccEntry : checkControlList) { ccmDescriptionOptions.add(new StateOption(Integer.toString(index), ccEntry.ccmDescriptionShort)); + ccmDetailsOptions.add(new StateOption(Integer.toString(index), ccEntry.ccmDescriptionLong)); ccmMileageOptions.add(new StateOption(Integer.toString(index), Integer.toString(ccEntry.ccmMileage))); if (selectedCC.equals(ccEntry.ccmDescriptionShort)) { isSelectedElementIn = true; @@ -151,6 +154,7 @@ protected void updateCheckControls(List ccl) { index++; } setOptions(CHANNEL_GROUP_CHECK_CONTROL, NAME, ccmDescriptionOptions); + setOptions(CHANNEL_GROUP_CHECK_CONTROL, DETAILS, ccmDetailsOptions); setOptions(CHANNEL_GROUP_CHECK_CONTROL, MILEAGE, ccmMileageOptions); // if current selected item isn't anymore in the list select first entry @@ -164,6 +168,7 @@ protected void selectCheckControl(int index) { CCMMessage ccEntry = checkControlList.get(index); selectedCC = ccEntry.ccmDescriptionShort; updateChannel(CHANNEL_GROUP_CHECK_CONTROL, NAME, StringType.valueOf(ccEntry.ccmDescriptionShort)); + updateChannel(CHANNEL_GROUP_CHECK_CONTROL, DETAILS, StringType.valueOf(ccEntry.ccmDescriptionLong)); updateChannel(CHANNEL_GROUP_CHECK_CONTROL, MILEAGE, QuantityType.valueOf(Converter.round(ccEntry.ccmMileage), imperial ? ImperialUnits.MILE : MetricPrefix.KILO(SIUnits.METRE))); @@ -181,6 +186,7 @@ protected void updateServices(List sl) { // add all elements to options serviceList = sl; List serviceNameOptions = new ArrayList<>(); + List serviceDetailsOptions = new ArrayList<>(); List serviceDateOptions = new ArrayList<>(); List serviceMileageOptions = new ArrayList<>(); boolean isSelectedElementIn = false; @@ -188,6 +194,7 @@ protected void updateServices(List sl) { for (CBSMessage serviceEntry : serviceList) { // create StateOption with "value = list index" and "label = human readable string" serviceNameOptions.add(new StateOption(Integer.toString(index), serviceEntry.getType())); + serviceDetailsOptions.add(new StateOption(Integer.toString(index), serviceEntry.getDescription())); serviceDateOptions.add(new StateOption(Integer.toString(index), serviceEntry.getDueDate())); serviceMileageOptions .add(new StateOption(Integer.toString(index), Integer.toString(serviceEntry.cbsRemainingMileage))); @@ -197,6 +204,7 @@ protected void updateServices(List sl) { index++; } setOptions(CHANNEL_GROUP_SERVICE, NAME, serviceNameOptions); + setOptions(CHANNEL_GROUP_SERVICE, DETAILS, serviceDetailsOptions); setOptions(CHANNEL_GROUP_SERVICE, DATE, serviceDateOptions); setOptions(CHANNEL_GROUP_SERVICE, MILEAGE, serviceMileageOptions); @@ -212,6 +220,8 @@ protected void selectService(int index) { selectedService = serviceEntry.cbsType; updateChannel(CHANNEL_GROUP_SERVICE, NAME, StringType.valueOf(Converter.toTitleCase(serviceEntry.getType()))); + updateChannel(CHANNEL_GROUP_SERVICE, DETAILS, + StringType.valueOf(Converter.toTitleCase(serviceEntry.getDescription()))); updateChannel(CHANNEL_GROUP_SERVICE, DATE, DateTimeType.valueOf(Converter.getLocalDateTime(serviceEntry.getDueDate()))); updateChannel(CHANNEL_GROUP_SERVICE, MILEAGE, diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-channel-types.xml index ee5683acfcc44..9d4de838b7d0b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-channel-types.xml @@ -7,6 +7,10 @@ String + + String + + Number:Length diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-group.xml index 0b554f6b98a06..443c1a13d0496 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-group.xml @@ -8,6 +8,7 @@ Show the current active CheckControl Messages + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-group.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-group.xml index 30ddcb6c3d2ee..668fd6318a975 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-group.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-group.xml @@ -8,6 +8,7 @@ All future Service schedules + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index b9c1e25a3e5ab..114789290e87f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -468,6 +468,29 @@ private void checkResult(ChannelUID channelUID, State state) { break; } break; + case DETAILS: + assertTrue(state instanceof StringType); + st = (StringType) state; + switch (gUid) { + case CHANNEL_GROUP_SERVICE: + wanted = StringType.valueOf(Converter.toTitleCase(Constants.NO_ENTRIES)); + if (!vStatus.cbsData.isEmpty()) { + wanted = StringType.valueOf(Converter.toTitleCase(vStatus.cbsData.get(0).getDescription())); + } + assertEquals(wanted.toString(), st.toString(), "Service Name"); + break; + case CHANNEL_GROUP_CHECK_CONTROL: + wanted = StringType.valueOf(Constants.NO_ENTRIES); + if (!vStatus.checkControlMessages.isEmpty()) { + wanted = StringType.valueOf(vStatus.checkControlMessages.get(0).ccmDescriptionLong); + } + assertEquals(wanted.toString(), st.toString(), "CheckControl Name"); + break; + default: + assertFalse(true, "Channel " + channelUID + " " + state + " not found"); + break; + } + break; case DATE: assertTrue(state instanceof DateTimeType); dtt = (DateTimeType) state; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java index bef3e321bf004..6b5cc6f2715d5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java @@ -57,10 +57,10 @@ public class VehicleTests { private static final int RANGE_CONV = 4; private static final int RANGE_ELECTRIC = 4; private static final int DOORS = 12; - private static final int CHECK_EMPTY = 2; - private static final int CHECK_AVAILABLE = 2; - private static final int SERVICE_AVAILABLE = 3; - private static final int SERVICE_EMPTY = 3; + private static final int CHECK_EMPTY = 3; + private static final int CHECK_AVAILABLE = 3; + private static final int SERVICE_AVAILABLE = 4; + private static final int SERVICE_EMPTY = 4; private static final int POSITION = 2; @Nullable From 5ad27cf59869a63d8fd8c3054a703ff2969d1e3b Mon Sep 17 00:00:00 2001 From: Bernd Date: Fri, 5 Mar 2021 12:45:59 +0100 Subject: [PATCH 133/176] missing translations added Signed-off-by: Bernd --- .../README.md | 15 ++++++ .../i18n/bmwconnecteddrive_de.properties | 46 +++++++++++++++++-- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 84f9e6aa19701..31681feb45967 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -304,6 +304,16 @@ Charging options with date and time for preferred time windows and charging mode | Override Timer: Departure Time Hour | charge | override-departure-hour | Number | | Override Timer: Departure Time Minute | charge | override-departure-minute | Number | +The channel _profile_mode_ supports + +* **IMMEDIATE_CHARGING** +* **DELAYED_CHARGING** + +The channel _profile-prefs supports + +* **NO_PRESELECTION** +* **CHARGING_WINDOW** + #### Location GPS location and heading of the vehicle. @@ -465,6 +475,11 @@ Like in the Charge Profile Channels 3 Timers are provided. Replace _X_ with 1, 2 | cancel | void | void | Sends the charging profile to the vehicle | | send | void | void | Cancel current edit of charging profile | +Values for valid charging mode get/set + +* **IMMEDIATE_CHARGING** +* **DELAYED_CHARGING** + ## Further Descriptions diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties index 6919ef9a699ff..27678277abb68 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties @@ -169,25 +169,63 @@ channel-type.bmwconnecteddrive.range-radius-fuel-channel.label = Verbrenner Rei channel-type.bmwconnecteddrive.range-radius-hybrid-channel.label = Hybrider Reichweiten-Radius channel-type.bmwconnecteddrive.service-name-channel.label = Service +channel-type.bmwconnecteddrive.service-details-channel.label = Service Details channel-type.bmwconnecteddrive.service-date-channel.label = Service Termin channel-type.bmwconnecteddrive.service-mileage-channel.label = Service in Kilometern channel-type.bmwconnecteddrive.checkcontrol-name-channel.label = Warnung +channel-type.bmwconnecteddrive.checkcontrol-details-channel.label = Warnung Details channel-type.bmwconnecteddrive.checkcontrol-mileage-channel.label = Warnung bei Kilometer channel-type.bmwconnecteddrive.profile-climate-channel.label = Klimatisierung bei Abfahrt -channel-type.bmwconnecteddrive.profile-mode-channel.label = Ladeprofil Einstellung +channel-type.bmwconnecteddrive.profile-mode-channel.label = Ladeprofil Methode +channel-type.bmwconnecteddrive.profile-prefs-channel.label = Ladeprofil Präferenz channel-type.bmwconnecteddrive.window-start-channel.label = Startzeit Ladefenster +channel-type.bmwconnecteddrive.window-start-hour-channel.label = Startzeit Ladefenster Stunde +channel-type.bmwconnecteddrive.window-start-minute-channel.label = Startzeit Ladefenster Minute channel-type.bmwconnecteddrive.window-end-channel.label = Endzeit Ladefenster +channel-type.bmwconnecteddrive.window-end-hour-channel.label = Endzeit Ladefenster Stunde +channel-type.bmwconnecteddrive.window-end-minute-channel.label = Endzeit Ladefenster Minute +channel-type.bmwconnecteddrive.timer1-enabled-channel.label = Zeitprofil 1 - Aktiviert channel-type.bmwconnecteddrive.timer1-departure-channel.label = Zeitprofil 1 - Abfahrtszeit +channel-type.bmwconnecteddrive.timer1-departure-hour-channel.label = Zeitprofil 1 - Abfahrtszeit Stunde +channel-type.bmwconnecteddrive.timer1-departure-minute-channel.label = Zeitprofil 1 - Abfahrtszeit Minute channel-type.bmwconnecteddrive.timer1-days-channel.label = Zeitprofil 1 - Tage -channel-type.bmwconnecteddrive.timer1-enabled-channel.label = Zeitprofil 1 - Aktiviert +channel-type.bmwconnecteddrive.timer1-day-mon-channel.label = Zeitprofil 1 - Montag +channel-type.bmwconnecteddrive.timer1-day-tue-channel.label = Zeitprofil 1 - Dienstag +channel-type.bmwconnecteddrive.timer1-day-wed-channel.label = Zeitprofil 1 - Mittwoch +channel-type.bmwconnecteddrive.timer1-day-thu-channel.label = Zeitprofil 1 - Donnerstag +channel-type.bmwconnecteddrive.timer1-day-fri-channel.label = Zeitprofil 1 - Freitag +channel-type.bmwconnecteddrive.timer1-day-sat-channel.label = Zeitprofil 1 - Samstag +channel-type.bmwconnecteddrive.timer1-day-sun-channel.label = Zeitprofil 1 - Sonntag +channel-type.bmwconnecteddrive.timer2-enabled-channel.label = Zeitprofil 2 - Aktiviert channel-type.bmwconnecteddrive.timer2-departure-channel.label = Zeitprofil 2 - Abfahrtszeit +channel-type.bmwconnecteddrive.timer2-departure-hour-channel.label = Zeitprofil 2 - Abfahrtszeit Stunde +channel-type.bmwconnecteddrive.timer2-departure-minute-channel.label = Zeitprofil 2 - Abfahrtszeit Minute channel-type.bmwconnecteddrive.timer2-days-channel.label = Zeitprofil 2 - Tage -channel-type.bmwconnecteddrive.timer2-enabled-channel.label = Zeitprofil 2 - Aktiviert +channel-type.bmwconnecteddrive.timer2-day-mon-channel.label = Zeitprofil 2 - Montag +channel-type.bmwconnecteddrive.timer2-day-tue-channel.label = Zeitprofil 2 - Dienstag +channel-type.bmwconnecteddrive.timer2-day-wed-channel.label = Zeitprofil 2 - Mittwoch +channel-type.bmwconnecteddrive.timer2-day-thu-channel.label = Zeitprofil 2 - Donnerstag +channel-type.bmwconnecteddrive.timer2-day-fri-channel.label = Zeitprofil 2 - Freitag +channel-type.bmwconnecteddrive.timer2-day-sat-channel.label = Zeitprofil 2 - Samstag +channel-type.bmwconnecteddrive.timer2-day-sun-channel.label = Zeitprofil 2 - Sonnatg +channel-type.bmwconnecteddrive.timer3-enabled-channel.label = Zeitprofil 3 - Aktiviert channel-type.bmwconnecteddrive.timer3-departure-channel.label = Zeitprofil 3 - Abfahrtszeit +channel-type.bmwconnecteddrive.timer3-departure-hour-channel.label = Zeitprofil 3 - Abfahrtszeit Stunde +channel-type.bmwconnecteddrive.timer3-departure-minute-channel.label = Zeitprofil 3 - Abfahrtszeit Minute channel-type.bmwconnecteddrive.timer3-days-channel.label = Zeitprofil 3 - Tage -channel-type.bmwconnecteddrive.timer3-enabled-channel.label = Zeitprofil 3 - Aktiviert +channel-type.bmwconnecteddrive.timer3-day-mon-channel.label = Zeitprofil 3 - Montag +channel-type.bmwconnecteddrive.timer3-day-tue-channel.label = Zeitprofil 3 - Dienstag +channel-type.bmwconnecteddrive.timer3-day-wed-channel.label = Zeitprofil 3 - Mittwoch +channel-type.bmwconnecteddrive.timer3-day-thu-channel.label = Zeitprofil 3 - Donnerstag +channel-type.bmwconnecteddrive.timer3-day-fri-channel.label = Zeitprofil 3 - Freitag +channel-type.bmwconnecteddrive.timer3-day-sat-channel.label = Zeitprofil 3 - Samstag +channel-type.bmwconnecteddrive.timer3-day-sun-channel.label = Zeitprofil 3 - Sonntag +channel-type.bmwconnecteddrive.override-departure-channel.label = Einmaliges Zeitprofil - Abfahrtszeit +channel-type.bmwconnecteddrive.override-departure-hour-channel.label = Einmaliges Zeitprofil - Abfahrtszeit Stunde +channel-type.bmwconnecteddrive.override-departure-minute-channel.label = Einmaliges Zeitprofil - Abfahrtszeit Minute +channel-type.bmwconnecteddrive.override-enabled-channel.label = Einmaliges Zeitprofil - Aktiviert channel-type.bmwconnecteddrive.destination-name-channel.label = Zieladresse channel-type.bmwconnecteddrive.destination-gps-channel.label = Ziel Koordinaten From 838de39fa56608effe399070296e89d60ac071e8 Mon Sep 17 00:00:00 2001 From: Bernd Date: Fri, 5 Mar 2021 14:42:01 +0100 Subject: [PATCH 134/176] Bugfix Service Details Signed-off-by: Bernd --- .../internal/dto/status/CBSMessage.java | 11 ++++++----- .../internal/handler/VehicleChannelHandler.java | 1 + .../resources/OH-INF/thing/service-channel-types.xml | 4 ++++ .../bmwconnecteddrive/internal/dto/StatusWrapper.java | 4 ++-- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java index 19789c0729e0d..14e127ae30a94 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/CBSMessage.java @@ -28,6 +28,7 @@ public class CBSMessage { public int cbsRemainingMileage = -1; // 46000 public String cbsTypeConverted = null; + public String cbsDescriptionConverted = null; public String getDueDate() { if (cbsDueDate == null) { @@ -49,14 +50,14 @@ public String getType() { } public String getDescription() { - if (cbsTypeConverted == null) { - if (cbsType == null) { - cbsTypeConverted = Constants.INVALID; + if (cbsDescriptionConverted == null) { + if (cbsDescription == null) { + cbsDescriptionConverted = Constants.INVALID; } else { - cbsTypeConverted = cbsDescription; + cbsDescriptionConverted = cbsDescription; } } - return cbsTypeConverted; + return cbsDescriptionConverted; } @Override diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 943e1f1b6e152..91ae05fe5d20c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -180,6 +180,7 @@ protected void updateServices(List sl) { if (sl.size() == 0) { CBSMessage cbsm = new CBSMessage(); cbsm.cbsType = Constants.NO_ENTRIES; + cbsm.cbsDescription = Constants.NO_ENTRIES; sl.add(cbsm); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-channel-types.xml index a2a7c074c84de..1fbefc9306f3d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-channel-types.xml @@ -7,6 +7,10 @@ String + + String + + DateTime diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index 114789290e87f..4b5db90c66d54 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -477,14 +477,14 @@ private void checkResult(ChannelUID channelUID, State state) { if (!vStatus.cbsData.isEmpty()) { wanted = StringType.valueOf(Converter.toTitleCase(vStatus.cbsData.get(0).getDescription())); } - assertEquals(wanted.toString(), st.toString(), "Service Name"); + assertEquals(wanted.toString(), st.toString(), "Service Details"); break; case CHANNEL_GROUP_CHECK_CONTROL: wanted = StringType.valueOf(Constants.NO_ENTRIES); if (!vStatus.checkControlMessages.isEmpty()) { wanted = StringType.valueOf(vStatus.checkControlMessages.get(0).ccmDescriptionLong); } - assertEquals(wanted.toString(), st.toString(), "CheckControl Name"); + assertEquals(wanted.toString(), st.toString(), "CheckControl Details"); break; default: assertFalse(true, "Channel " + channelUID + " " + state + " not found"); From 91e8264177256316e60ed3dca7124752b106a8b8 Mon Sep 17 00:00:00 2001 From: Bernd Date: Sat, 6 Mar 2021 13:29:53 +0100 Subject: [PATCH 135/176] reduce info logging Signed-off-by: Bernd --- .../internal/handler/VehicleHandler.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index fd59ffa452935..7d97415ae9ff9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -806,11 +806,11 @@ public Collection> getServices() { public Optional getChargeProfileWrapper() { return chargeProfileCache.flatMap(cache -> { return ChargeProfileWrapper.fromJson(cache).map(wrapper -> { - logger.info("Charge Profile editing - start"); - logger.info("{}", wrapper.getJson()); + logger.debug("Charge Profile editing - start"); + logger.debug("{}", wrapper.getJson()); return wrapper; }).or(() -> { - logger.info("cannot parse charging profile: {}", cache); + logger.debug("cannot parse charging profile: {}", cache); return Optional.empty(); }); }).or(() -> { @@ -821,7 +821,7 @@ public Optional getChargeProfileWrapper() { public void sendChargeProfile(Optional profile) { profile.map(profil -> profil.getJson()).ifPresent(json -> { - logger.info("sending charging profile: {}", json); + logger.debug("sending charging profile: {}", json); chargeProfileSent = Optional.of(json); remote.ifPresent(rem -> rem.execute(RemoteService.CHARGING_CONTROL, json)); }); From 0a35f611038c2b63175bc5039010e51f9f55fb98 Mon Sep 17 00:00:00 2001 From: Bernd Date: Sat, 6 Mar 2021 14:06:43 +0100 Subject: [PATCH 136/176] readme adaptions Signed-off-by: Bernd --- .../README.md | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 31681feb45967..1bede6b3c5df7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -274,8 +274,8 @@ Charging options with date and time for preferred time windows and charging mode * Channel Group ID is **charge** * Available for electric and hybrid vehicles -* Read/Write access for UI. Use (Charge Profile Actions)[#charge_profile_ction] in rules -* There are 3 Timers available. Replace _X_ with number 1,2 or 3 to target the correct timer +* Read/Write access for UI. Use [Charge Profile Actions](#charge-profile-action) in rules +* There are 3 timers available. Replace *X* with number 1,2 or 3 to target the correct timer | Channel Label | Channel Group ID | Channel ID | Type | |---------------------------------------|------------------|---------------------------|----------| @@ -288,31 +288,31 @@ Charging options with date and time for preferred time windows and charging mode | Charging Window End Time Hour | charge | window-end-hour | Number | | Charging Window End Time Minute | charge | window-end-minute | Number | | Air Conditioning at Departure Time | charge | profile-climate | Switch | -| Timer _X_: Enabled | charge | timer_X_-enabled | Switch | -| Timer _X_: Departure Time | charge | timer_X_-departure | DateTime | -| Timer _X_: Departure Time Hour | charge | timer_X_-departure-hour | Number | -| Timer _X_: Departure Time Minute | charge | timer_X_-departure-minute | Number | -| Timer _X_: Monday | charge | timer_X_-day-mon | Switch | -| Timer _X_: Tuesday | charge | timer_X_-day-tue | Switch | -| Timer _X_: Wednesday | charge | timer_X_-day-wed | Switch | -| Timer _X_: Thursday | charge | timer_X_-day-thu | Switch | -| Timer _X_: Friday | charge | timer_X_-day-fri | Switch | -| Timer _X_: Saturday | charge | timer_X_-day-sat | Switch | -| Timer _X_: Sunday | charge | timer_X_-day-sun | Switch | +| Timer *X*: Enabled | charge | timer*X*-enabled | Switch | +| Timer *X*: Departure Time | charge | timer*X*-departure | DateTime | +| Timer *X*: Departure Time Hour | charge | timer*X*-departure-hour | Number | +| Timer *X*: Departure Time Minute | charge | timer*X*-departure-minute | Number | +| Timer *X*: Monday | charge | timer*X*-day-mon | Switch | +| Timer *X*: Tuesday | charge | timer*X*-day-tue | Switch | +| Timer *X*: Wednesday | charge | timer*X*-day-wed | Switch | +| Timer *X*: Thursday | charge | timer*X*-day-thu | Switch | +| Timer *X*: Friday | charge | timer*X*-day-fri | Switch | +| Timer *X*: Saturday | charge | timer*X*-day-sat | Switch | +| Timer *X*: Sunday | charge | timer*X*-day-sun | Switch | | Override Timer: Enabled | charge | override-enabled | Switch | | Override Timer: Departure Time | charge | override-departure | DateTime | | Override Timer: Departure Time Hour | charge | override-departure-hour | Number | | Override Timer: Departure Time Minute | charge | override-departure-minute | Number | -The channel _profile_mode_ supports +The channel _profile-mode_ supports -* **IMMEDIATE_CHARGING** -* **DELAYED_CHARGING** +* *IMMEDIATE_CHARGING* +* *DELAYED_CHARGING* -The channel _profile-prefs supports +The channel _profile-prefs_ supports -* **NO_PRESELECTION** -* **CHARGING_WINDOW** +* *NO_PRESELECTION* +* *CHARGING_WINDOW* #### Location @@ -436,36 +436,36 @@ The possible values are the same mentioned in [Thing Configuration](#thing-confi ## Charge Profile Action -The Charge Profile is accessible and modifyable in rules via action. +The Charge Profile is accessible and modifiable in rules via action. Get the corresponding action from your car using the Thing ID -* bmwconnecteddrive - don't change -* bev_rex - (Thing UID)[#things] of your car -* user - Thing ID of the (Bridge)[#bridge] -* i3 - Thing ID of your Car +* bmwconnecteddrive - Binding ID, don't change! +* bev_rex - [Thing UID](#things) of your car +* user - Thing ID of the [Bridge](#bridge) +* i3 - Thing ID of your car ``` val profile = getActions("chargeprofile", "bmwconnecteddrive:bev_rex:user:i3") ``` -Like in the Charge Profile Channels 3 Timers are provided. Replace _X_ with 1, 2 or 3 to address the right timer. +Like in the Charge Profile Channels 3 Timers are provided. Replace *X* with 1, 2 or 3 to address the right timer. | Function | Parameters | Returns | Description | |---------------------------------------|------------------|---------------------------|------------------------------------------------------------| | getClimatizationEnabled | void | Boolean | Returns the enabled state of climatization | | setClimatizationEnabled | Boolean | void | Sets the enabled state of climatization | -| getChargingMode | void | String | Gets the charging-mode | -| setChargingMode | String | void | Sets the charging-mode | +| getChargingMode | void | String | Gets the charging-mode, see valid options below | +| setChargingMode | String | void | Sets the charging-mode, see valid options below | | getPreferredWindowStart | void | LocalTime | Returns the preferred charging-window start time | | setPreferredWindowStart | LocalTime | void | Sets the preferred charging-window start time | | getPreferredWindowEnd | void | LocalTime | Returns the preferred charging-window end time | | setPreferredWindowEnd | LocalTime | void | Sets the preferred charging-window end time | -| getTimer_X_Enabled | void | Boolean | Returns the enabled state of timer_X_ | -| setTimer_X_Enabled | Boolean | void | Returns the enabled state of timer_X_ | -| getTimer_X_Departure | void | LocalTime | Returns the departure time of timer_X_ | -| setTimer_X_Departure | LocalTime | void | Sets the timer_X_ departure time | -| getTimer_X_Days | void | Set | Returns the days of week timer_X_ is enabled for | -| setTimer_X_Days | Set | void | sets the days of week timer_X_ is enabled for | +| getTimer*X*Enabled | void | Boolean | Returns the enabled state of timer*X* | +| setTimer*X*Enabled | Boolean | void | Returns the enabled state of timer*X* | +| getTimer*X*Departure | void | LocalTime | Returns the departure time of timer*X* | +| setTimer*X*Departure | LocalTime | void | Sets the timer*X* departure time | +| getTimer*X*Days | void | Set | Returns the days of week timer*X* is enabled for | +| setTimer*X*Days | Set | void | sets the days of week timer*X* is enabled for | | getOverrideTimerEnabled | void | Boolean | Returns the enabled state of override timer | | setOverrideTimerEnabled | Boolean | void | Sets the enabled state of override timer | | getOverrideTimerDeparture | void | LocalTime | Returns the departure time of override timer | @@ -477,8 +477,8 @@ Like in the Charge Profile Channels 3 Timers are provided. Replace _X_ with 1, 2 Values for valid charging mode get/set -* **IMMEDIATE_CHARGING** -* **DELAYED_CHARGING** +* *IMMEDIATE_CHARGING* +* *DELAYED_CHARGING* ## Further Descriptions From ef163d93767275c213eb73ed9382feb7bb088e7e Mon Sep 17 00:00:00 2001 From: Bernd Date: Sat, 6 Mar 2021 21:17:07 +0100 Subject: [PATCH 137/176] solve review comments Signed-off-by: Bernd --- .../internal/ConnectedDriveConstants.java | 2 + .../internal/discovery/VehicleDiscovery.java | 8 ++-- .../internal/dto/Destination.java | 41 ++++++++----------- .../compat/VehicleAttributesContainer.java | 10 ++++- .../internal/dto/status/Position.java | 2 +- .../handler/ConnectedDriveBridgeHandler.java | 16 +++++--- .../internal/handler/ConnectedDriveProxy.java | 2 +- .../handler/VehicleChannelHandler.java | 22 ++++++++-- .../internal/handler/VehicleHandler.java | 5 +++ .../internal/utils/Constants.java | 2 +- .../internal/handler/FingerprintTest.java | 6 +-- 11 files changed, 71 insertions(+), 45 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 0aa3aa8237c70..45e2f821c6493 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -34,6 +34,8 @@ public class ConnectedDriveConstants { public static final String UNITS_IMPERIAL = "IMPERIAL"; public static final String UNITS_METRIC = "METRIC"; + public static final String VIN = "vin"; + public static final int DEFAULT_IMAGE_SIZE = 1024; public static final int DEFAULT_REFRESH_INTERVAL = 5; public static final String DEFAULT_IMAGE_VIEWPORT = "FRONT"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java index def54d6d7df3c..277fdc31a924a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java @@ -108,8 +108,8 @@ public void onResponse(VehiclesContainer container) { final AtomicBoolean foundVehicle = new AtomicBoolean(false); bridge.getThing().getThings().forEach(vehicleThing -> { Configuration c = vehicleThing.getConfiguration(); - if (c.containsKey("vin")) { - String thingVIN = c.get("vin").toString(); + if (c.containsKey(ConnectedDriveConstants.VIN)) { + String thingVIN = c.get(ConnectedDriveConstants.VIN).toString(); if (vehicle.vin.equals(thingVIN)) { vehicleThing.setProperties(properties); foundVehicle.set(true); @@ -120,7 +120,7 @@ public void onResponse(VehiclesContainer container) { // Vehicle not found -> trigger discovery if (!foundVehicle.get()) { // Properties needed for functional THing - properties.put("vin", vehicle.vin); + properties.put(ConnectedDriveConstants.VIN, vehicle.vin); properties.put("refreshInterval", Integer.toString(ConnectedDriveConstants.DEFAULT_REFRESH_INTERVAL)); properties.put("units", ConnectedDriveConstants.UNITS_AUTODETECT); @@ -130,7 +130,7 @@ public void onResponse(VehiclesContainer container) { String vehicleLabel = vehicle.brand + " " + vehicle.model; Map convertedProperties = new HashMap(properties); thingDiscovered(DiscoveryResultBuilder.create(uid).withBridge(bridgeUID) - .withRepresentationProperty("vin").withLabel(vehicleLabel) + .withRepresentationProperty(ConnectedDriveConstants.VIN).withLabel(vehicleLabel) .withProperties(convertedProperties).build()); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java index 2637f79b64183..c365dfb2943d0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java @@ -32,38 +32,29 @@ public class Destination { public String type; public String createdAt; - private String address = null; - private String coordinates = null; - public String getAddress() { - if (address == null) { - StringBuilder buf = new StringBuilder(); - if (street != null) { - buf.append(street); - if (streetNumber != null) { - buf.append(SPACE).append(streetNumber); - } - } - if (city != null) { - if (buf.length() > 0) { - buf.append(COMMA).append(SPACE).append(city); - } else { - buf.append(city); - } + StringBuilder buf = new StringBuilder(); + if (street != null) { + buf.append(street); + if (streetNumber != null) { + buf.append(SPACE).append(streetNumber); } - if (buf.length() == 0) { - address = UNDEF; + } + if (city != null) { + if (buf.length() > 0) { + buf.append(COMMA).append(SPACE).append(city); } else { - address = Converter.toTitleCase(buf.toString()); + buf.append(city); } } - return address; + if (buf.length() == 0) { + return UNDEF; + } else { + return Converter.toTitleCase(buf.toString()); + } } public String getCoordinates() { - if (coordinates == null) { - coordinates = new StringBuilder().append(lat).append(Constants.COMMA).append(lon).toString(); - } - return coordinates; + return new StringBuilder().append(lat).append(Constants.COMMA).append(lon).toString(); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java index 405863121df33..b5786b675fcf2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java @@ -23,6 +23,8 @@ import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; +import com.google.gson.JsonSyntaxException; + /** * The {@link VehicleAttributesContainer} Data Transfer Object * @@ -101,7 +103,11 @@ public String transform() { } } vs.cbsData = cbsl; - - return Converter.getGson().toJson(vsc); + String returnVal = Constants.EMPTY_JSON; + try { + returnVal = Converter.getGson().toJson(vsc); + } catch (JsonSyntaxException jse) { + } + return returnVal; } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java index 43b89f7b749dd..ee46dd372ce43 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/status/Position.java @@ -31,6 +31,6 @@ public String getCoordinates() { @Override public String toString() { - return new StringBuilder(Float.toString(lat)).append(Constants.COMMA).append(Float.toString(lon)).toString(); + return getCoordinates(); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java index 9e7b57f194a15..81b7334885ff4 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java @@ -40,7 +40,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.gson.JsonSyntaxException; +import com.google.gson.JsonParseException; /** * The {@link ConnectedDriveBridgeHandler} is responsible for handling commands, which are @@ -93,11 +93,16 @@ public void requestVehicles() { public String getDiscoveryFingerprint() { return troubleshootFingerprint.map(fingerprint -> { - VehiclesContainer container = Converter.getGson().fromJson(fingerprint, VehiclesContainer.class); + VehiclesContainer container = null; + try { + container = Converter.getGson().fromJson(fingerprint, VehiclesContainer.class); + } catch (JsonParseException jpe) { + logger.info("Cannot parse fingerprint {}", jpe.getMessage()); + } if (container != null) { if (container.vehicles != null) { if (container.vehicles.isEmpty()) { - return Constants.EMPTY_VEHICLES; + return Constants.EMPTY_JSON; } else { container.vehicles.forEach(entry -> { entry.vin = ANONYMOUS; @@ -158,13 +163,14 @@ public void onResponse(@Nullable String response) { } return Converter.getGson().toJson(container); } - } catch (JsonSyntaxException jse) { + } catch (JsonParseException jpe) { + logger.debug("Fingerprint parse exception {}", jpe.getMessage()); } // Unparseable or not a VehiclesContainer: return response; }); } else { - troubleshootFingerprint = Optional.of(Constants.EMPTY_VEHICLES); + troubleshootFingerprint = Optional.of(Constants.EMPTY_JSON); } if (firstResponse) { logFingerPrint(); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index 2830331b7084e..2ff0992bdcf23 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -290,7 +290,7 @@ private synchronized void updateToken() { logger.debug("Authorization status {} reason {}", contentResponse.getStatus(), contentResponse.getReason()); } - } catch (InterruptedException | ExecutionException | TimeoutException e) { + } catch (InterruptedException | ExecutionException | TimeoutException | JsonSyntaxException e) { logger.debug("Authorization exception: {}", e.getMessage(), e); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 91ae05fe5d20c..59c8341772e0c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -64,6 +64,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.gson.JsonSyntaxException; + /** * The {@link VehicleChannelHandler} is responsible for handling commands, which are * sent to one of the channels. @@ -334,7 +336,11 @@ protected void updateLastTrip(LastTrip trip) { } protected void updateChargeProfileFromContent(String content) { - ChargeProfileWrapper.fromJson(content).ifPresent(this::updateChargeProfile); + try { + ChargeProfileWrapper.fromJson(content).ifPresent(this::updateChargeProfile); + } catch (JsonSyntaxException jse) { + logger.debug("Update charge profile parse exception {}", jse.getMessage()); + } } protected void updateChargeProfile(ChargeProfileWrapper wrapper) { @@ -430,12 +436,22 @@ protected void updateVehicleStatus(VehicleStatus vStatus) { updateChannel(CHANNEL_GROUP_STATUS, LAST_UPDATE, DateTimeType.valueOf(Converter.getLocalDateTime(VehicleStatusUtils.getUpdateTime(vStatus)))); - Doors doorState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Doors.class); - Windows windowState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Windows.class); + Doors doorState = null; + try { + doorState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Doors.class); + } catch (JsonSyntaxException jse) { + logger.debug("Doors parse exception {}", jse.getMessage()); + } if (doorState != null) { updateChannel(CHANNEL_GROUP_STATUS, DOORS, StringType.valueOf(VehicleStatusUtils.checkClosed(doorState))); updateDoors(doorState); } + Windows windowState = null; + try { + windowState = Converter.getGson().fromJson(Converter.getGson().toJson(vStatus), Windows.class); + } catch (JsonSyntaxException jse) { + logger.debug("Windows parse exception {}", jse.getMessage()); + } if (windowState != null) { updateChannel(CHANNEL_GROUP_STATUS, WINDOWS, StringType.valueOf(VehicleStatusUtils.checkClosed(windowState))); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 7d97415ae9ff9..72079bc6e4b4c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -516,6 +516,7 @@ public void onResponse(@Nullable String content) { updateDestinations(dc.destinations); } } catch (JsonSyntaxException jse) { + logger.debug("{}", jse.getMessage()); } } removeCallback(this); @@ -576,6 +577,7 @@ public void onResponse(@Nullable String content) { } } } catch (JsonSyntaxException jse) { + logger.debug("{}", jse.getMessage()); } } removeCallback(this); @@ -607,6 +609,7 @@ public void onResponse(@Nullable String content) { } } } catch (JsonSyntaxException jse) { + logger.debug("{}", jse.getMessage()); } } removeCallback(this); @@ -662,6 +665,7 @@ public void onResponse(@Nullable String content) { updatePosition(vStatus.position); } } catch (JsonSyntaxException jse) { + logger.debug("{}", jse.getMessage()); } } removeCallback(this); @@ -704,6 +708,7 @@ public void onResponse(@Nullable String content) { vehicleStatusCallback.onResponse(vac.transform()); } } catch (JsonSyntaxException jse) { + logger.debug("{}", jse.getMessage()); } } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java index b084a00ca8448..4cb62126a7de8 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -68,7 +68,7 @@ public class Constants { public static final String ANONYMOUS = "Anonymous"; public static final int MILES_TO_FEET_FACTOR = 5280; - public static final String EMPTY_VEHICLES = "{}"; + public static final String EMPTY_JSON = "{}"; // Time Constants for DateTime channels public static final LocalDate EPOCH_DAY = LocalDate.ofEpochDay(0); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/FingerprintTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/FingerprintTest.java index 564bb43c5294e..bb8f873bb7d29 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/FingerprintTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/FingerprintTest.java @@ -41,11 +41,11 @@ public void testDiscoveryFingerprint() { ConnectedDriveBridgeHandler bh = new ConnectedDriveBridgeHandler(b, hcf); // when(bh.getThing()).thenReturn(b); - bh.onResponse(Constants.EMPTY_VEHICLES); - assertEquals(Constants.EMPTY_VEHICLES, bh.getDiscoveryFingerprint(), "Empty Response"); + bh.onResponse(Constants.EMPTY_JSON); + assertEquals(Constants.EMPTY_JSON, bh.getDiscoveryFingerprint(), "Empty Response"); bh.onResponse(null); - assertEquals(Constants.EMPTY_VEHICLES, bh.getDiscoveryFingerprint(), "Empty Response"); + assertEquals(Constants.EMPTY_JSON, bh.getDiscoveryFingerprint(), "Empty Response"); String content = FileReader.readFileInString("src/test/resources/webapi/connected-drive-account-info.json"); bh.onResponse(content); From a0e5315eb991a8026be943d7b014ec4a9ba7c12c Mon Sep 17 00:00:00 2001 From: Bernd Date: Sun, 7 Mar 2021 16:06:19 +0100 Subject: [PATCH 138/176] correct pom.xml format Signed-off-by: Bernd --- bom/openhab-addons/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/openhab-addons/pom.xml b/bom/openhab-addons/pom.xml index 82ddfc208b217..9a8cf0dcc88b9 100644 --- a/bom/openhab-addons/pom.xml +++ b/bom/openhab-addons/pom.xml @@ -165,7 +165,7 @@ org.openhab.addons.bundles org.openhab.binding.bmwconnecteddrive ${project.version} - + org.openhab.addons.bundles org.openhab.binding.boschindego From ea0ddbe3e0eee3167cfb3629b03b3e200c41eb3b Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sat, 6 Mar 2021 22:43:22 +0100 Subject: [PATCH 139/176] dynamic RemoteService-command options Signed-off-by: Norbert Truchsess Signed-off-by: Bernd --- .../handler/RemoteServiceHandler.java | 43 +++++++++------- .../handler/VehicleChannelHandler.java | 3 ++ .../internal/handler/VehicleHandler.java | 18 ++----- .../internal/utils/RemoteServiceUtils.java | 51 +++++++++++++++++++ .../thing/remote-services-channel-types.xml | 12 ----- 5 files changed, 84 insertions(+), 43 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/RemoteServiceUtils.java diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java index 5c0ba684e53ba..5942e3fce58e7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -12,6 +12,8 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.handler; +import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; + import java.util.Optional; import java.util.concurrent.TimeUnit; @@ -58,24 +60,29 @@ public enum ExecutionState { } public enum RemoteService { - LIGHT_FLASH("LIGHT_FLASH"), - VEHICLE_FINDER("VEHICLE_FINDER"), - DOOR_LOCK("DOOR_LOCK"), - DOOR_UNLOCK("DOOR_UNLOCK"), - HORN("HORN_BLOW"), - AIR_CONDITIONING("CLIMATE_NOW"), - CHARGE_NOW("CHARGE_NOW"), - CHARGING_CONTROL("CHARGING_CONTROL"); - - private final String service; - - RemoteService(String s) { - service = s; + LIGHT_FLASH(REMOTE_SERVICE_LIGHT_FLASH, "Flash Lights"), + VEHICLE_FINDER(REMOTE_SERVICE_VEHICLE_FINDER, "Vehicle Finder"), + DOOR_LOCK(REMOTE_SERVICE_DOOR_LOCK, "Door Lock"), + DOOR_UNLOCK(REMOTE_SERVICE_DOOR_UNLOCK, "Door Unlock"), + HORN_BLOW(REMOTE_SERVICE_HORN, "Horn Blow"), + CLIMATE_NOW(REMOTE_SERVICE_AIR_CONDITIONING, "Climate Control"), + CHARGE_NOW(REMOTE_SERVICE_CHARGE_NOW, "Start Charging"), + CHARGING_CONTROL(REMOTE_SERVICE_CHARGING_CONTROL, "Send Charging Profile"); + + private final String command; + private final String label; + + RemoteService(final String command, final String label) { + this.command = command; + this.label = label; + } + + public String getCommand() { + return command; } - @Override - public String toString() { - return service; + public String getLabel() { + return label; } } @@ -106,10 +113,10 @@ boolean execute(RemoteService service, String... data) { // only one service executing return false; } - serviceExecuting = Optional.of(service.toString()); + serviceExecuting = Optional.of(service.name()); } final MultiMap dataMap = new MultiMap(); - dataMap.add(SERVICE_TYPE, service.toString()); + dataMap.add(SERVICE_TYPE, service.name()); if (data.length > 0) { dataMap.add(DATA, data[0]); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 59c8341772e0c..f6808d1ff2b53 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -43,6 +43,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileWrapper.ProfileKey; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; +import org.openhab.binding.bmwconnecteddrive.internal.utils.RemoteServiceUtils; import org.openhab.binding.bmwconnecteddrive.internal.utils.VehicleStatusUtils; import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DecimalType; @@ -110,6 +111,8 @@ public VehicleChannelHandler(Thing thing, BMWConnectedDriveOptionProvider op, St isElectric = type.equals(VehicleType.PLUGIN_HYBRID.toString()) || type.equals(VehicleType.ELECTRIC_REX.toString()) || type.equals(VehicleType.ELECTRIC.toString()); isHybrid = hasFuel && isElectric; + + setOptions(CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_COMMAND, RemoteServiceUtils.getOptions(isElectric)); } @Override diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 72079bc6e4b4c..1e699e91549b5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -46,6 +46,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.openhab.binding.bmwconnecteddrive.internal.utils.ImageProperties; +import org.openhab.binding.bmwconnecteddrive.internal.utils.RemoteServiceUtils; import org.openhab.core.io.net.http.HttpUtil; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; @@ -127,25 +128,16 @@ public void handleCommand(ChannelUID channelUID, Command command) { remote.ifPresent(remot -> { switch (serviceCommand) { case REMOTE_SERVICE_LIGHT_FLASH: - remot.execute(RemoteService.LIGHT_FLASH); - break; case REMOTE_SERVICE_AIR_CONDITIONING: - remot.execute(RemoteService.AIR_CONDITIONING); - break; case REMOTE_SERVICE_DOOR_LOCK: - remot.execute(RemoteService.DOOR_LOCK); - break; case REMOTE_SERVICE_DOOR_UNLOCK: - remot.execute(RemoteService.DOOR_UNLOCK); - break; case REMOTE_SERVICE_HORN: - remot.execute(RemoteService.HORN); - break; case REMOTE_SERVICE_VEHICLE_FINDER: - remot.execute(RemoteService.VEHICLE_FINDER); - break; case REMOTE_SERVICE_CHARGE_NOW: - remot.execute(RemoteService.CHARGE_NOW); + RemoteServiceUtils.getRemoteService(serviceCommand) + .ifPresentOrElse(service -> remot.execute(service), () -> { + logger.info("Remote service execution {} unknown", serviceCommand); + }); break; case REMOTE_SERVICE_CHARGING_CONTROL: sendChargeProfile(chargeProfileEdit); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/RemoteServiceUtils.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/RemoteServiceUtils.java new file mode 100644 index 0000000000000..2ab7d450373dd --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/RemoteServiceUtils.java @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2010-2021 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.bmwconnecteddrive.internal.utils; + +import java.util.EnumSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.bmwconnecteddrive.internal.handler.RemoteServiceHandler.RemoteService; +import org.openhab.core.types.StateOption; + +/** + * Helper class for Remote Service Commands + * + * @author Norbert Truchsess - edit & send of charge profile + */ +@NonNullByDefault +public class RemoteServiceUtils { + + private static final Map CommandService = Stream.of(RemoteService.values()) + .collect(Collectors.toUnmodifiableMap(RemoteService::getCommand, service -> service)); + + private static final Set ElectricServices = EnumSet.of(RemoteService.CHARGE_NOW, + RemoteService.CHARGING_CONTROL); + + public static Optional getRemoteService(final String command) { + return Optional.ofNullable(CommandService.get(command)); + } + + public static List getOptions(final boolean isElectric) { + return Stream.of(RemoteService.values()) + .filter(service -> isElectric ? true : !ElectricServices.contains(service)) + .map(service -> new StateOption(service.getCommand(), service.getLabel())) + .collect(Collectors.toUnmodifiableList()); + } +} diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-types.xml index 2af2e45b6ff6e..0bbc38ce79a75 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-types.xml @@ -6,18 +6,6 @@ String - - - - - - - - - - - - String From cb33d0be617b2ede6256e01ff9045c089124696a Mon Sep 17 00:00:00 2001 From: Bernd Date: Sun, 7 Mar 2021 17:52:31 +0100 Subject: [PATCH 140/176] review corrections Signed-off-by: Bernd --- .../internal/dto/compat/VehicleAttributesContainer.java | 9 +-------- .../internal/handler/ConnectedDriveProxy.java | 2 +- .../internal/handler/VehicleChannelHandler.java | 6 +----- 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java index b5786b675fcf2..3d24246d2733b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java @@ -23,8 +23,6 @@ import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; -import com.google.gson.JsonSyntaxException; - /** * The {@link VehicleAttributesContainer} Data Transfer Object * @@ -103,11 +101,6 @@ public String transform() { } } vs.cbsData = cbsl; - String returnVal = Constants.EMPTY_JSON; - try { - returnVal = Converter.getGson().toJson(vsc); - } catch (JsonSyntaxException jse) { - } - return returnVal; + return Converter.getGson().toJson(vsc); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index 2ff0992bdcf23..2830331b7084e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -290,7 +290,7 @@ private synchronized void updateToken() { logger.debug("Authorization status {} reason {}", contentResponse.getStatus(), contentResponse.getReason()); } - } catch (InterruptedException | ExecutionException | TimeoutException | JsonSyntaxException e) { + } catch (InterruptedException | ExecutionException | TimeoutException e) { logger.debug("Authorization exception: {}", e.getMessage(), e); } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index f6808d1ff2b53..b5ad52bd66ab9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -339,11 +339,7 @@ protected void updateLastTrip(LastTrip trip) { } protected void updateChargeProfileFromContent(String content) { - try { - ChargeProfileWrapper.fromJson(content).ifPresent(this::updateChargeProfile); - } catch (JsonSyntaxException jse) { - logger.debug("Update charge profile parse exception {}", jse.getMessage()); - } + ChargeProfileWrapper.fromJson(content).ifPresent(this::updateChargeProfile); } protected void updateChargeProfile(ChargeProfileWrapper wrapper) { From 262f0bc5faa91690c7fcbdf5ae92b8a653da8592 Mon Sep 17 00:00:00 2001 From: Bernd Date: Sun, 7 Mar 2021 22:38:28 +0100 Subject: [PATCH 141/176] solve checkstyle issues of RemoteServiceUtils Signed-off-by: Bernd --- .../internal/utils/RemoteServiceUtils.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/RemoteServiceUtils.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/RemoteServiceUtils.java index 2ab7d450373dd..a81f9c10cc39e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/RemoteServiceUtils.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/RemoteServiceUtils.java @@ -26,25 +26,25 @@ /** * Helper class for Remote Service Commands - * - * @author Norbert Truchsess - edit & send of charge profile + * + * @author Norbert Truchsess - Initial contribution */ @NonNullByDefault public class RemoteServiceUtils { - private static final Map CommandService = Stream.of(RemoteService.values()) + private static final Map COMMAND_SERVICES = Stream.of(RemoteService.values()) .collect(Collectors.toUnmodifiableMap(RemoteService::getCommand, service -> service)); - private static final Set ElectricServices = EnumSet.of(RemoteService.CHARGE_NOW, + private static final Set ELECTRIC_SERVICES = EnumSet.of(RemoteService.CHARGE_NOW, RemoteService.CHARGING_CONTROL); public static Optional getRemoteService(final String command) { - return Optional.ofNullable(CommandService.get(command)); + return Optional.ofNullable(COMMAND_SERVICES.get(command)); } public static List getOptions(final boolean isElectric) { return Stream.of(RemoteService.values()) - .filter(service -> isElectric ? true : !ElectricServices.contains(service)) + .filter(service -> isElectric ? true : !ELECTRIC_SERVICES.contains(service)) .map(service -> new StateOption(service.getCommand(), service.getLabel())) .collect(Collectors.toUnmodifiableList()); } From 48ace3af1f1f3da5e91e4f43262827dfc6ff8ea1 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sun, 21 Mar 2021 13:55:49 +0100 Subject: [PATCH 142/176] fixing handling of NonNull result of getConfigAs Signed-off-by: Norbert Truchsess --- .../handler/ConnectedDriveBridgeHandler.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java index 81b7334885ff4..94ae11f276bf6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java @@ -54,7 +54,6 @@ public class ConnectedDriveBridgeHandler extends BaseBridgeHandler implements St private HttpClientFactory httpClientFactory; private Optional discoveryService = Optional.empty(); private Optional proxy = Optional.empty(); - private Optional configuration = Optional.empty(); private Optional> initializerJob = Optional.empty(); private Optional troubleshootFingerprint = Optional.empty(); @@ -72,14 +71,9 @@ public void handleCommand(ChannelUID channelUID, Command command) { public void initialize() { troubleshootFingerprint = Optional.empty(); updateStatus(ThingStatus.UNKNOWN); - configuration = Optional.of(getConfigAs(ConnectedDriveConfiguration.class)); - configuration.ifPresentOrElse(config -> { - proxy = Optional.of(new ConnectedDriveProxy(httpClientFactory, config)); - // give the system some time to create all predefined Vehicles - initializerJob = Optional.of(scheduler.schedule(this::requestVehicles, 5, TimeUnit.SECONDS)); - }, () -> { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR); - }); + proxy = Optional.of(new ConnectedDriveProxy(httpClientFactory, getConfigAs(ConnectedDriveConfiguration.class))); + // give the system some time to create all predefined Vehicles + initializerJob = Optional.of(scheduler.schedule(this::requestVehicles, 5, TimeUnit.SECONDS)); } @Override From 59d6403be7ba6a8a6e993f165797ac11e56facb1 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sun, 21 Mar 2021 14:27:15 +0100 Subject: [PATCH 143/176] fix use of defaultCharset being platform-dependant Signed-off-by: Norbert Truchsess --- .../internal/handler/ConnectedDriveProxy.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index 2830331b7084e..95decb5eb758a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -14,7 +14,6 @@ import static org.openhab.binding.bmwconnecteddrive.internal.utils.HTTPConstants.*; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -120,14 +119,14 @@ private synchronized void call(final String url, final boolean post, final @Null } final Request req; final String encoded = params == null || params.isEmpty() ? null - : UrlEncoded.encode(params, Charset.defaultCharset(), false); + : UrlEncoded.encode(params, StandardCharsets.UTF_8, false); final String completeUrl; if (post) { completeUrl = url; req = httpClient.POST(url); if (encoded != null) { - req.content(new StringContentProvider(CONTENT_TYPE_URL_ENCODED, encoded, Charset.defaultCharset())); + req.content(new StringContentProvider(CONTENT_TYPE_URL_ENCODED, encoded, StandardCharsets.UTF_8)); } } else { completeUrl = encoded == null ? url : url + Constants.QUESTION + encoded; @@ -259,7 +258,7 @@ private synchronized void updateToken() { dataMap.add(USERNAME, configuration.userName); dataMap.add(PASSWORD, configuration.password); req.content(new StringContentProvider(CONTENT_TYPE_URL_ENCODED, - UrlEncoded.encode(dataMap, Charset.defaultCharset(), false), Charset.defaultCharset())); + UrlEncoded.encode(dataMap, StandardCharsets.UTF_8, false), StandardCharsets.UTF_8)); try { ContentResponse contentResponse = req.timeout(HTTP_TIMEOUT_SEC, TimeUnit.SECONDS).send(); // Status needs to be 302 - Response is stored in Header From ec67d8ef85c508a897adcdcef43fb71abffa3c2c Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sun, 21 Mar 2021 14:31:17 +0100 Subject: [PATCH 144/176] fix import Signed-off-by: Norbert Truchsess --- .../internal/handler/ConnectedDriveProxy.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index 95decb5eb758a..2834ad86dd2a6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -24,6 +24,7 @@ import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.client.api.Result; import org.eclipse.jetty.client.util.BufferingResponseListener; import org.eclipse.jetty.client.util.StringContentProvider; import org.eclipse.jetty.http.HttpField; @@ -138,7 +139,7 @@ private synchronized void call(final String url, final boolean post, final @Null req.timeout(HTTP_TIMEOUT_SEC, TimeUnit.SECONDS).send(new BufferingResponseListener() { @NonNullByDefault({}) @Override - public void onComplete(org.eclipse.jetty.client.api.Result result) { + public void onComplete(Result result) { if (result.getResponse().getStatus() != 200) { NetworkError error = new NetworkError(); error.url = completeUrl; From c7351f71289cb948047b771d110a59cf8c59dda9 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sun, 21 Mar 2021 14:34:04 +0100 Subject: [PATCH 145/176] fix log of stacktrace Signed-off-by: Norbert Truchsess --- .../bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index 2834ad86dd2a6..eafe55729bb7a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -291,7 +291,7 @@ private synchronized void updateToken() { contentResponse.getReason()); } } catch (InterruptedException | ExecutionException | TimeoutException e) { - logger.debug("Authorization exception: {}", e.getMessage(), e); + logger.debug("Authorization exception: {}", e.getMessage()); } } From 2203c9b464eb0c90be257ba10356d1ebb75f19dc Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sun, 21 Mar 2021 14:39:44 +0100 Subject: [PATCH 146/176] fix reponse-type handling Signed-off-by: Norbert Truchsess --- .../internal/handler/ConnectedDriveProxy.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index eafe55729bb7a..b1a5d6d341b17 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -155,8 +155,10 @@ public void onComplete(Result result) { } else { if (callback instanceof StringResponseCallback) { ((StringResponseCallback) callback).onResponse(getContentAsString()); - } else { + } else if (callback instanceof ByteResponseCallback) { ((ByteResponseCallback) callback).onResponse(getContent()); + } else { + logger.error("unexpected reponse type {}", callback.getClass().getName()); } } } From ecf35cf7b8492fc8067778ccc4dca250e2ce8a82 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sun, 21 Mar 2021 16:11:16 +0100 Subject: [PATCH 147/176] fix state-retrieval future not canceled on ThingHandler.dispose Signed-off-by: Norbert Truchsess --- .../handler/RemoteServiceHandler.java | 24 ++++++++++++++++++- .../internal/handler/VehicleHandler.java | 1 + 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java index 5942e3fce58e7..15fb8193ae5b5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -15,6 +15,7 @@ import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; import java.util.Optional; +import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -50,6 +51,8 @@ public class RemoteServiceHandler implements StringResponseCallback { private static final int STATE_UPDATE_SEC = HTTPConstants.HTTP_TIMEOUT_SEC + 1; // regular timeout + 1sec private int counter = 0; + private Optional> stateJob = Optional.empty(); + public enum ExecutionState { READY, INITIATED, @@ -140,6 +143,7 @@ public void getState() { }, () -> { logger.warn("No Service executed to get state"); }); + stateJob = Optional.empty(); } } @@ -167,7 +171,14 @@ public void onResponse(@Nullable String result) { } } // schedule even if no result is present until retries exceeded - handler.getScheduler().schedule(this::getState, STATE_UPDATE_SEC, TimeUnit.SECONDS); + synchronized (this) { + stateJob.ifPresent(job -> { + if (!job.isDone()) { + job.cancel(true); + } + }); + stateJob = Optional.of(handler.getScheduler().schedule(this::getState, STATE_UPDATE_SEC, TimeUnit.SECONDS)); + } } @Override @@ -183,4 +194,15 @@ private void reset() { serviceExecuting = Optional.empty(); counter = 0; } + + public void cancel() { + synchronized (this) { + stateJob.ifPresent(action -> { + if (!action.isDone()) { + action.cancel(true); + } + stateJob = Optional.empty(); + }); + } + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 1e699e91549b5..24d98416201ef 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -268,6 +268,7 @@ private void startSchedule(int interval) { @Override public void dispose() { refreshJob.ifPresent(job -> job.cancel(true)); + remote.ifPresent(RemoteServiceHandler::cancel); } public void getData() { From b91dbe05e136a5d29208dc79cf1f7109a334bde8 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sun, 21 Mar 2021 16:29:16 +0100 Subject: [PATCH 148/176] fix getConfigAs being not Nullable Signed-off-by: Norbert Truchsess --- .../internal/handler/VehicleHandler.java | 56 +++++++++---------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 1e699e91549b5..b0981f35e5d3c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -217,41 +217,37 @@ public void initialize() { callbackCounter = Optional.of(new ArrayList()); updateStatus(ThingStatus.UNKNOWN); final VehicleConfiguration config = getConfigAs(VehicleConfiguration.class); - if (config != null) { - configuration = Optional.of(config); - scheduler.execute(() -> { - Bridge bridge = getBridge(); - if (bridge != null) { - BridgeHandler handler = bridge.getHandler(); - if (handler != null) { - bridgeHandler = Optional.of(((ConnectedDriveBridgeHandler) handler)); - proxy = ((ConnectedDriveBridgeHandler) handler).getProxy(); - remote = proxy.map(prox -> prox.getRemoteServiceHandler(this)); - } else { - logger.debug("Bridge Handler null"); - } + configuration = Optional.of(config); + scheduler.execute(() -> { + Bridge bridge = getBridge(); + if (bridge != null) { + BridgeHandler handler = bridge.getHandler(); + if (handler != null) { + bridgeHandler = Optional.of(((ConnectedDriveBridgeHandler) handler)); + proxy = ((ConnectedDriveBridgeHandler) handler).getProxy(); + remote = proxy.map(prox -> prox.getRemoteServiceHandler(this)); } else { - logger.debug("Bridge null"); + logger.debug("Bridge Handler null"); } + } else { + logger.debug("Bridge null"); + } - // get Image after init with config values - synchronized (imageProperties) { - imageProperties = new ImageProperties(config.imageViewport, config.imageSize); - } - updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_VIEWPORT, StringType.valueOf((config.imageViewport))); - updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_SIZE, new DecimalType((config.imageSize))); + // get Image after init with config values + synchronized (imageProperties) { + imageProperties = new ImageProperties(config.imageViewport, config.imageSize); + } + updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_VIEWPORT, StringType.valueOf((config.imageViewport))); + updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_SIZE, new DecimalType((config.imageSize))); - // check imperial setting is different to AutoDetect - if (!UNITS_AUTODETECT.equals(config.units)) { - imperial = UNITS_IMPERIAL.equals(config.units); - } + // check imperial setting is different to AutoDetect + if (!UNITS_AUTODETECT.equals(config.units)) { + imperial = UNITS_IMPERIAL.equals(config.units); + } - // start update schedule - startSchedule(config.refreshInterval); - }); - } else { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR); - } + // start update schedule + startSchedule(config.refreshInterval); + }); } private void startSchedule(int interval) { From e51254aa3ca3995c1e80b84dd85f6e3bf8316593 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sun, 21 Mar 2021 16:49:11 +0100 Subject: [PATCH 149/176] fix editTimeout not being canceled in dispose Signed-off-by: Norbert Truchsess --- .../bmwconnecteddrive/internal/handler/VehicleHandler.java | 1 + 1 file changed, 1 insertion(+) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 24d98416201ef..917e691a40374 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -268,6 +268,7 @@ private void startSchedule(int interval) { @Override public void dispose() { refreshJob.ifPresent(job -> job.cancel(true)); + editTimeout.ifPresent(job -> job.cancel(true)); remote.ifPresent(RemoteServiceHandler::cancel); } From ca5afb04d9f3b710e145cbb564a87c93d8ab192d Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sun, 21 Mar 2021 16:33:29 +0100 Subject: [PATCH 150/176] fix obsolete if (..) return true else return false Signed-off-by: Norbert Truchsess --- .../bmwconnecteddrive/internal/handler/VehicleHandler.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index b0981f35e5d3c..d472fc62e82ca 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -418,11 +418,7 @@ private boolean isSupported(String service) { } } // if cache is empty give it a try one time to collected Troubleshoot data - if (lastTripCache.isEmpty() || allTripsCache.isEmpty() || destinationCache.isEmpty()) { - return true; - } else { - return false; - } + return lastTripCache.isEmpty() || allTripsCache.isEmpty() || destinationCache.isEmpty(); } public void updateRemoteExecutionStatus(@Nullable String service, @Nullable String status) { From 2f150afe4ccf6d745f22ebeaa7e9751256b47cd7 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sun, 21 Mar 2021 16:39:18 +0100 Subject: [PATCH 151/176] fix use of Constant.SPACE and StringBuilder Signed-off-by: Norbert Truchsess --- .../bmwconnecteddrive/internal/handler/VehicleHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index d472fc62e82ca..7f4c2df306617 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -426,8 +426,8 @@ public void updateRemoteExecutionStatus(@Nullable String service, @Nullable Stri && ExecutionState.EXECUTED.name().equals(status)) { saveChargeProfileSent(); } - updateChannel(CHANNEL_GROUP_REMOTE, REMOTE_STATE, StringType.valueOf(Converter.toTitleCase( - new StringBuilder(service == null ? "-" : service).append(" ").append(status).toString()))); + updateChannel(CHANNEL_GROUP_REMOTE, REMOTE_STATE, StringType + .valueOf(Converter.toTitleCase((service == null ? "-" : service) + Constants.SPACE + status))); } public Optional getConfiguration() { From 5ad8ba2218b6ca47c108f2783d6300fce2b3c4f9 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sun, 21 Mar 2021 16:53:30 +0100 Subject: [PATCH 152/176] fix syntactical sugar in lambdas Signed-off-by: Norbert Truchsess --- .../bmwconnecteddrive/internal/handler/VehicleHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 1e699e91549b5..2d85ea780de58 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -774,7 +774,7 @@ private void handleChargeProfileCommand(ChannelUID channelUID, Command command) editTimeout = Optional.of(scheduler.schedule(() -> { editTimeout = Optional.empty(); chargeProfileEdit = Optional.empty(); - chargeProfileCache.ifPresent(content -> updateChargeProfileFromContent(content)); + chargeProfileCache.ifPresent(this::updateChargeProfileFromContent); }, 5, TimeUnit.MINUTES)); } else { logger.info("unexpected command {} not processed", command.toFullString()); @@ -791,7 +791,7 @@ private void saveChargeProfileSent() { chargeProfileCache = Optional.of(sent); chargeProfileSent = Optional.empty(); chargeProfileEdit = Optional.empty(); - chargeProfileCache.ifPresent(content -> updateChargeProfileFromContent(content)); + chargeProfileCache.ifPresent(this::updateChargeProfileFromContent); }); } From d87929e50179aad20883d2e520b5ca399c15df69 Mon Sep 17 00:00:00 2001 From: Bernd Weymann Date: Sun, 21 Mar 2021 14:03:01 +0100 Subject: [PATCH 153/176] solve review comments Signed-off-by: Bernd Weymann --- .../internal/ConnectedDriveConstants.java | 4 +-- .../ConnectedDriveHandlerFactory.java | 16 ------------ .../internal/VehicleConfiguration.java | 4 +-- .../internal/action/ChargeProfileActions.java | 2 +- .../internal/discovery/VehicleDiscovery.java | 25 +++---------------- .../internal/dto/Destination.java | 2 +- 6 files changed, 9 insertions(+), 44 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 45e2f821c6493..4b9ec1267a037 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -36,8 +36,8 @@ public class ConnectedDriveConstants { public static final String VIN = "vin"; - public static final int DEFAULT_IMAGE_SIZE = 1024; - public static final int DEFAULT_REFRESH_INTERVAL = 5; + public static final int DEFAULT_IMAGE_SIZE_PX = 1024; + public static final int DEFAULT_REFRESH_INTERVAL_MINUTES = 5; public static final String DEFAULT_IMAGE_VIEWPORT = "FRONT"; // See constants from bimmer-connected diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java index d57fead76fbc9..11f2b01303ce1 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveHandlerFactory.java @@ -14,9 +14,6 @@ import static org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.*; -import java.util.ArrayList; -import java.util.List; - import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.bmwconnecteddrive.internal.handler.BMWConnectedDriveOptionProvider; @@ -48,7 +45,6 @@ public class ConnectedDriveHandlerFactory extends BaseThingHandlerFactory { private final HttpClientFactory httpClientFactory; private final BMWConnectedDriveOptionProvider optionProvider; - private static final List VEHICLE_HANDLER_REGISTRY = new ArrayList(); private boolean imperial = false; @Activate @@ -73,20 +69,8 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { return new ConnectedDriveBridgeHandler((Bridge) thing, httpClientFactory); } else if (SUPPORTED_THING_SET.contains(thingTypeUID)) { VehicleHandler vh = new VehicleHandler(thing, optionProvider, thingTypeUID.getId(), imperial); - VEHICLE_HANDLER_REGISTRY.add(vh); return vh; } return null; } - - @Override - protected void removeHandler(ThingHandler thingHandler) { - if (thingHandler instanceof VehicleHandler) { - VEHICLE_HANDLER_REGISTRY.remove(thingHandler); - } - } - - public static List getHandlerRegistry() { - return VEHICLE_HANDLER_REGISTRY; - } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/VehicleConfiguration.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/VehicleConfiguration.java index 2e31313256291..d0af7f79d4e20 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/VehicleConfiguration.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/VehicleConfiguration.java @@ -30,7 +30,7 @@ public class VehicleConfiguration { /** * Data refresh rate in minutes */ - public int refreshInterval = ConnectedDriveConstants.DEFAULT_REFRESH_INTERVAL; + public int refreshInterval = ConnectedDriveConstants.DEFAULT_REFRESH_INTERVAL_MINUTES; /** * Either Auto Detect Miles units (UK & US) or select Format directly @@ -43,7 +43,7 @@ public class VehicleConfiguration { /** * image size - width & length (square) */ - public int imageSize = ConnectedDriveConstants.DEFAULT_IMAGE_SIZE; + public int imageSize = ConnectedDriveConstants.DEFAULT_IMAGE_SIZE_PX; /** * image viewport defined as options in thing xml diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java index e51fcfbdec2d7..9a2965fd57c90 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java @@ -36,7 +36,7 @@ * * @author Norbert Truchsess - Initial contribution */ -@ThingActionsScope(name = "chargeprofile") +@ThingActionsScope(name = "bmwconnecteddrive") @NonNullByDefault public class ChargeProfileActions implements ThingActions { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java index 277fdc31a924a..5f02d2a6b7228 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java @@ -122,9 +122,10 @@ public void onResponse(VehiclesContainer container) { // Properties needed for functional THing properties.put(ConnectedDriveConstants.VIN, vehicle.vin); properties.put("refreshInterval", - Integer.toString(ConnectedDriveConstants.DEFAULT_REFRESH_INTERVAL)); + Integer.toString(ConnectedDriveConstants.DEFAULT_REFRESH_INTERVAL_MINUTES)); properties.put("units", ConnectedDriveConstants.UNITS_AUTODETECT); - properties.put("imageSize", Integer.toString(ConnectedDriveConstants.DEFAULT_IMAGE_SIZE)); + properties.put("imageSize", + Integer.toString(ConnectedDriveConstants.DEFAULT_IMAGE_SIZE_PX)); properties.put("imageViewport", ConnectedDriveConstants.DEFAULT_IMAGE_VIEWPORT); String vehicleLabel = vehicle.brand + " " + vehicle.model; @@ -175,31 +176,11 @@ public void setThingHandler(ThingHandler handler) { return bridgeHandler.orElse(null); } - @Override - public int getScanTimeout() { - return DISCOVERY_TIMEOUT; - } - - @Override - public boolean isBackgroundDiscoveryEnabled() { - return false; - } - @Override protected void startScan() { bridgeHandler.ifPresent(ConnectedDriveBridgeHandler::requestVehicles); } - @Override - public void abortScan() { - // nothing to abort - } - - @Override - public void activate() { - super.activate(null); - } - @Override public void deactivate() { super.deactivate(); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java index c365dfb2943d0..e9d653a8e2cc7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/Destination.java @@ -55,6 +55,6 @@ public String getAddress() { } public String getCoordinates() { - return new StringBuilder().append(lat).append(Constants.COMMA).append(lon).toString(); + return lat + Constants.COMMA + lon; } } From c794022caaca0870f223a993ca576f4618be01a6 Mon Sep 17 00:00:00 2001 From: Bernd Weymann Date: Mon, 22 Mar 2021 23:33:14 +0100 Subject: [PATCH 154/176] revert Action renaming until review comment is clarified Signed-off-by: Bernd Weymann --- .../bmwconnecteddrive/internal/action/ChargeProfileActions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java index 9a2965fd57c90..e51fcfbdec2d7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java @@ -36,7 +36,7 @@ * * @author Norbert Truchsess - Initial contribution */ -@ThingActionsScope(name = "bmwconnecteddrive") +@ThingActionsScope(name = "chargeprofile") @NonNullByDefault public class ChargeProfileActions implements ThingActions { From 95051e8e471f8279ab1c98fb66043e3bd24295b9 Mon Sep 17 00:00:00 2001 From: Bernd Weymann Date: Tue, 23 Mar 2021 01:30:14 +0100 Subject: [PATCH 155/176] solve further review findings Signed-off-by: Bernd Weymann --- .../internal/discovery/VehicleDiscovery.java | 35 +++----- .../compat/VehicleAttributesContainer.java | 83 ----------------- .../internal/dto/remote/ExecutionStatus.java | 4 - .../handler/ConnectedDriveBridgeHandler.java | 45 +++++----- .../internal/handler/ConnectedDriveProxy.java | 11 ++- .../handler/RemoteServiceHandler.java | 21 ++--- .../handler/VehicleChannelHandler.java | 11 +-- .../internal/handler/VehicleHandler.java | 12 ++- .../internal/utils/Converter.java | 88 +++++++++++++++++++ .../internal/handler/VehicleTests.java | 8 +- 10 files changed, 152 insertions(+), 166 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java index 5f02d2a6b7228..55c66b5b44afa 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/VehicleDiscovery.java @@ -18,7 +18,6 @@ import java.util.HashMap; import java.util.Map; import java.util.Optional; -import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -104,36 +103,30 @@ public void onResponse(VehiclesContainer container) { properties.put("vehicleChargeControl", Converter.toTitleCase(vehicle.model)); } - // Check now if a thing with the same VIN exists - final AtomicBoolean foundVehicle = new AtomicBoolean(false); + // Update Properties for already created Things bridge.getThing().getThings().forEach(vehicleThing -> { Configuration c = vehicleThing.getConfiguration(); if (c.containsKey(ConnectedDriveConstants.VIN)) { String thingVIN = c.get(ConnectedDriveConstants.VIN).toString(); if (vehicle.vin.equals(thingVIN)) { vehicleThing.setProperties(properties); - foundVehicle.set(true); } } }); - // Vehicle not found -> trigger discovery - if (!foundVehicle.get()) { - // Properties needed for functional THing - properties.put(ConnectedDriveConstants.VIN, vehicle.vin); - properties.put("refreshInterval", - Integer.toString(ConnectedDriveConstants.DEFAULT_REFRESH_INTERVAL_MINUTES)); - properties.put("units", ConnectedDriveConstants.UNITS_AUTODETECT); - properties.put("imageSize", - Integer.toString(ConnectedDriveConstants.DEFAULT_IMAGE_SIZE_PX)); - properties.put("imageViewport", ConnectedDriveConstants.DEFAULT_IMAGE_VIEWPORT); - - String vehicleLabel = vehicle.brand + " " + vehicle.model; - Map convertedProperties = new HashMap(properties); - thingDiscovered(DiscoveryResultBuilder.create(uid).withBridge(bridgeUID) - .withRepresentationProperty(ConnectedDriveConstants.VIN).withLabel(vehicleLabel) - .withProperties(convertedProperties).build()); - } + // Properties needed for functional THing + properties.put(ConnectedDriveConstants.VIN, vehicle.vin); + properties.put("refreshInterval", + Integer.toString(ConnectedDriveConstants.DEFAULT_REFRESH_INTERVAL_MINUTES)); + properties.put("units", ConnectedDriveConstants.UNITS_AUTODETECT); + properties.put("imageSize", Integer.toString(ConnectedDriveConstants.DEFAULT_IMAGE_SIZE_PX)); + properties.put("imageViewport", ConnectedDriveConstants.DEFAULT_IMAGE_VIEWPORT); + + String vehicleLabel = vehicle.brand + " " + vehicle.model; + Map convertedProperties = new HashMap(properties); + thingDiscovered(DiscoveryResultBuilder.create(uid).withBridge(bridgeUID) + .withRepresentationProperty(ConnectedDriveConstants.VIN).withLabel(vehicleLabel) + .withProperties(convertedProperties).build()); } }); }); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java index 3d24246d2733b..3e8087f6e2748 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/compat/VehicleAttributesContainer.java @@ -12,17 +12,6 @@ */ package org.openhab.binding.bmwconnecteddrive.internal.dto.compat; -import java.util.ArrayList; -import java.util.List; - -import org.openhab.binding.bmwconnecteddrive.internal.dto.status.CBSMessage; -import org.openhab.binding.bmwconnecteddrive.internal.dto.status.CCMMessage; -import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Position; -import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; -import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; -import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; -import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; - /** * The {@link VehicleAttributesContainer} Data Transfer Object * @@ -31,76 +20,4 @@ public class VehicleAttributesContainer { public VehicleAttributes attributesMap; public VehicleMessages vehicleMessages; - - public String transform() { - // create target objects - VehicleStatusContainer vsc = new VehicleStatusContainer(); - VehicleStatus vs = new VehicleStatus(); - vsc.vehicleStatus = vs; - - vs.mileage = attributesMap.mileage; - vs.doorLockState = attributesMap.doorLockState; - - vs.doorDriverFront = attributesMap.doorDriverFront; - vs.doorDriverRear = attributesMap.doorDriverRear; - vs.doorPassengerFront = attributesMap.doorPassengerFront; - vs.doorPassengerRear = attributesMap.doorPassengerRear; - vs.hood = attributesMap.hoodState; - vs.trunk = attributesMap.trunkState; - - vs.windowDriverFront = attributesMap.winDriverFront; - vs.windowDriverRear = attributesMap.winDriverRear; - vs.windowPassengerFront = attributesMap.winPassengerFront; - vs.windowPassengerRear = attributesMap.winPassengerRear; - vs.sunroof = attributesMap.sunroofState; - - vs.remainingFuel = attributesMap.remainingFuel; - vs.remainingRangeElectric = attributesMap.beRemainingRangeElectricKm; - vs.remainingRangeElectricMls = attributesMap.beRemainingRangeElectricMile; - vs.remainingRangeFuel = attributesMap.beRemainingRangeFuelKm; - vs.remainingRangeFuelMls = attributesMap.beRemainingRangeFuelMile; - vs.remainingFuel = attributesMap.remainingFuel; - vs.chargingLevelHv = attributesMap.chargingLevelHv; - vs.chargingStatus = attributesMap.chargingHVStatus; - vs.lastChargingEndReason = attributesMap.lastChargingEndReason; - - vs.updateTime = attributesMap.updateTimeConverted; - // vs.internalDataTimeUTC = attributesMap.updateTime; - - Position p = new Position(); - p.lat = attributesMap.gpsLat; - p.lon = attributesMap.gpsLon; - p.heading = attributesMap.heading; - vs.position = p; - - final List ccml = new ArrayList(); - if (vehicleMessages != null) { - if (vehicleMessages.ccmMessages != null) { - vehicleMessages.ccmMessages.forEach(entry -> { - CCMMessage ccmM = new CCMMessage(); - ccmM.ccmDescriptionShort = entry.text; - ccmM.ccmDescriptionLong = Constants.HYPHEN; - ccmM.ccmMileage = entry.unitOfLengthRemaining; - ccml.add(ccmM); - }); - } - } - vs.checkControlMessages = ccml; - - final List cbsl = new ArrayList(); - if (vehicleMessages != null) { - if (vehicleMessages.cbsMessages != null) { - vehicleMessages.cbsMessages.forEach(entry -> { - CBSMessage cbsm = new CBSMessage(); - cbsm.cbsType = entry.text; - cbsm.cbsDescription = entry.description; - cbsm.cbsDueDate = entry.date; - cbsm.cbsRemainingMileage = entry.unitOfLengthRemaining; - cbsl.add(cbsm); - }); - } - } - vs.cbsData = cbsl; - return Converter.getGson().toJson(vsc); - } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatus.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatus.java index 71ff06627a225..4f80ac78df07e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatus.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/dto/remote/ExecutionStatus.java @@ -21,8 +21,4 @@ public class ExecutionStatus { public String serviceType;// ": "DOOR_UNLOCK", public String status;// ": "EXECUTED", public String eventId;// ": "5639303536333926DA7B9400@bmw.de", - // public String extendedStatus;// ": { - // public String newDoorStatus;// ": "INVALID", - // public String oldDoorStatus;// ": "INVALID", - // public String result;// ": "STATUS_NOT_CHANGED" } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java index 94ae11f276bf6..63177f9c6d617 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java @@ -73,6 +73,7 @@ public void initialize() { updateStatus(ThingStatus.UNKNOWN); proxy = Optional.of(new ConnectedDriveProxy(httpClientFactory, getConfigAs(ConnectedDriveConfiguration.class))); // give the system some time to create all predefined Vehicles + // check with API call if bridge is online initializerJob = Optional.of(scheduler.schedule(this::requestVehicles, 5, TimeUnit.SECONDS)); } @@ -90,30 +91,30 @@ public String getDiscoveryFingerprint() { VehiclesContainer container = null; try { container = Converter.getGson().fromJson(fingerprint, VehiclesContainer.class); - } catch (JsonParseException jpe) { - logger.info("Cannot parse fingerprint {}", jpe.getMessage()); - } - if (container != null) { - if (container.vehicles != null) { - if (container.vehicles.isEmpty()) { - return Constants.EMPTY_JSON; - } else { - container.vehicles.forEach(entry -> { - entry.vin = ANONYMOUS; - entry.breakdownNumber = ANONYMOUS; - if (entry.dealer != null) { - Dealer d = entry.dealer; - d.city = ANONYMOUS; - d.country = ANONYMOUS; - d.name = ANONYMOUS; - d.phone = ANONYMOUS; - d.postalCode = ANONYMOUS; - d.street = ANONYMOUS; - } - }); - return Converter.getGson().toJson(container); + if (container != null) { + if (container.vehicles != null) { + if (container.vehicles.isEmpty()) { + return Constants.EMPTY_JSON; + } else { + container.vehicles.forEach(entry -> { + entry.vin = ANONYMOUS; + entry.breakdownNumber = ANONYMOUS; + if (entry.dealer != null) { + Dealer d = entry.dealer; + d.city = ANONYMOUS; + d.country = ANONYMOUS; + d.name = ANONYMOUS; + d.phone = ANONYMOUS; + d.postalCode = ANONYMOUS; + d.street = ANONYMOUS; + } + }); + return Converter.getGson().toJson(container); + } } } + } catch (JsonParseException jpe) { + logger.debug("Cannot parse fingerprint {}", jpe.getMessage()); } // Not a VehiclesContainer or Vehicles is empty so deliver fingerprint as it is return fingerprint; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index b1a5d6d341b17..3e749c6587f50 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -114,7 +114,7 @@ private synchronized void call(final String url, final boolean post, final @Null } else if (url.endsWith(vehicleStatusAPI)) { ((StringResponseCallback) callback).onResponse(Injector.getStatus()); } else { - logger.info("Simulation of {} not supported", url); + logger.debug("Simulation of {} not supported", url); } return; } @@ -221,6 +221,11 @@ private String getRegionServer() { return retVal == null ? Constants.INVALID : retVal; } + private String getAuthorizationValue() { + final String retVal = BimmerConstants.AUTHORIZATION_VALUE_MAP.get(configuration.region); + return retVal == null ? Constants.INVALID : retVal; + } + RemoteServiceHandler getRemoteServiceHandler(VehicleHandler vehicleHandler) { return new RemoteServiceHandler(vehicleHandler, this); } @@ -250,8 +255,8 @@ private synchronized void updateToken() { final Request req = authHttpClient.POST(legacyAuthUri); req.header(HttpHeader.CONNECTION, KEEP_ALIVE); - req.header(HttpHeader.HOST, BimmerConstants.SERVER_MAP.get(configuration.region)); - req.header(HttpHeader.AUTHORIZATION, BimmerConstants.AUTHORIZATION_VALUE_MAP.get(configuration.region)); + req.header(HttpHeader.HOST, getRegionServer()); + req.header(HttpHeader.AUTHORIZATION, getAuthorizationValue()); req.header(CREDENTIALS, BimmerConstants.CREDENTIAL_VALUES); req.header(HttpHeader.REFERER, BimmerConstants.REFERER_URL); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java index 15fb8193ae5b5..353ba1acb0bdf 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -44,14 +44,20 @@ public class RemoteServiceHandler implements StringResponseCallback { private final Logger logger = LoggerFactory.getLogger(RemoteServiceHandler.class); - // after 60 retries the state update will give up private static final String SERVICE_TYPE = "serviceType"; private static final String DATA = "data"; + // after 6 retries the state update will give up private static final int GIVEUP_COUNTER = 6; private static final int STATE_UPDATE_SEC = HTTPConstants.HTTP_TIMEOUT_SEC + 1; // regular timeout + 1sec - private int counter = 0; + private final ConnectedDriveProxy proxy; + private final VehicleHandler handler; + private final String serviceExecutionAPI; + private final String serviceExecutionStateAPI; + + private int counter = 0; private Optional> stateJob = Optional.empty(); + private Optional serviceExecuting = Optional.empty(); public enum ExecutionState { READY, @@ -89,13 +95,6 @@ public String getLabel() { } } - private final ConnectedDriveProxy proxy; - private final VehicleHandler handler; - private Optional serviceExecuting = Optional.empty(); - - private final String serviceExecutionAPI; - private final String serviceExecutionStateAPI; - public RemoteServiceHandler(VehicleHandler vehicleHandler, ConnectedDriveProxy connectedDriveProxy) { handler = vehicleHandler; proxy = connectedDriveProxy; @@ -158,9 +157,7 @@ public void onResponse(@Nullable String result) { handler.updateRemoteExecutionStatus(serviceExecuting.orElse(null), status); if (ExecutionState.EXECUTED.name().equals(status)) { // refresh loop ends - update of status handled in the normal refreshInterval. Earlier - // update - // doesn't - // show better results! + // update doesn't show better results! reset(); return; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index b5ad52bd66ab9..20f4519c1c95e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -58,7 +58,6 @@ import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.Thing; import org.openhab.core.thing.binding.BaseThingHandler; -import org.openhab.core.types.Command; import org.openhab.core.types.State; import org.openhab.core.types.StateOption; import org.openhab.core.types.UnDefType; @@ -75,7 +74,7 @@ * @author Norbert Truchsess - edit & send of charge profile */ @NonNullByDefault -public class VehicleChannelHandler extends BaseThingHandler { +public abstract class VehicleChannelHandler extends BaseThingHandler { protected final Logger logger = LoggerFactory.getLogger(VehicleChannelHandler.class); protected boolean imperial = false; protected boolean hasFuel = false; @@ -115,14 +114,6 @@ public VehicleChannelHandler(Thing thing, BMWConnectedDriveOptionProvider op, St setOptions(CHANNEL_GROUP_REMOTE, REMOTE_SERVICE_COMMAND, RemoteServiceUtils.getOptions(isElectric)); } - @Override - public void handleCommand(ChannelUID channelUID, Command command) { - } - - @Override - public void initialize() { - } - private void setOptions(final String group, final String id, List options) { optionProvider.setStateOptions(new ChannelUID(thing.getUID(), group, id), options); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 6d3fc7a877973..3d8b5156ea20b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -136,14 +136,14 @@ public void handleCommand(ChannelUID channelUID, Command command) { case REMOTE_SERVICE_CHARGE_NOW: RemoteServiceUtils.getRemoteService(serviceCommand) .ifPresentOrElse(service -> remot.execute(service), () -> { - logger.info("Remote service execution {} unknown", serviceCommand); + logger.debug("Remote service execution {} unknown", serviceCommand); }); break; case REMOTE_SERVICE_CHARGING_CONTROL: sendChargeProfile(chargeProfileEdit); break; default: - logger.info("Remote service execution {} unknown", serviceCommand); + logger.debug("Remote service execution {} unknown", serviceCommand); break; } }); @@ -690,9 +690,7 @@ public void onResponse(@Nullable String content) { try { VehicleAttributesContainer vac = Converter.getGson().fromJson(content, VehicleAttributesContainer.class); - if (vac != null) { - vehicleStatusCallback.onResponse(vac.transform()); - } + vehicleStatusCallback.onResponse(Converter.transformLegacyStatus(vac)); } catch (JsonSyntaxException jse) { logger.debug("{}", jse.getMessage()); } @@ -771,7 +769,7 @@ private void handleChargeProfileCommand(ChannelUID channelUID, Command command) chargeProfileCache.ifPresent(this::updateChargeProfileFromContent); }, 5, TimeUnit.MINUTES)); } else { - logger.info("unexpected command {} not processed", command.toFullString()); + logger.debug("unexpected command {} not processed", command.toFullString()); } }); } @@ -805,7 +803,7 @@ public Optional getChargeProfileWrapper() { return Optional.empty(); }); }).or(() -> { - logger.info("No ChargeProfile recieved so far - cannot start editing"); + logger.debug("No ChargeProfile recieved so far - cannot start editing"); return Optional.empty(); }); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java index 0351c28db0e7e..8698ec8be68a9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java @@ -17,12 +17,22 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; import javax.measure.quantity.Length; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.bmwconnecteddrive.internal.dto.compat.VehicleAttributes; +import org.openhab.binding.bmwconnecteddrive.internal.dto.compat.VehicleAttributesContainer; +import org.openhab.binding.bmwconnecteddrive.internal.dto.compat.VehicleMessages; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.CBSMessage; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.CCMMessage; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.Position; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatus; +import org.openhab.binding.bmwconnecteddrive.internal.dto.status.VehicleStatusContainer; import org.openhab.core.i18n.TimeZoneProvider; import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.unit.ImperialUnits; @@ -201,4 +211,82 @@ public static int getIndex(String fullString) { } return index; } + + public static String transformLegacyStatus(@Nullable VehicleAttributesContainer vac) { + if (vac != null) { + if (vac.attributesMap != null && vac.vehicleMessages != null) { + VehicleAttributes attributesMap = vac.attributesMap; + VehicleMessages vehicleMessages = vac.vehicleMessages; + // create target objects + VehicleStatusContainer vsc = new VehicleStatusContainer(); + VehicleStatus vs = new VehicleStatus(); + vsc.vehicleStatus = vs; + + vs.mileage = attributesMap.mileage; + vs.doorLockState = attributesMap.doorLockState; + + vs.doorDriverFront = attributesMap.doorDriverFront; + vs.doorDriverRear = attributesMap.doorDriverRear; + vs.doorPassengerFront = attributesMap.doorPassengerFront; + vs.doorPassengerRear = attributesMap.doorPassengerRear; + vs.hood = attributesMap.hoodState; + vs.trunk = attributesMap.trunkState; + + vs.windowDriverFront = attributesMap.winDriverFront; + vs.windowDriverRear = attributesMap.winDriverRear; + vs.windowPassengerFront = attributesMap.winPassengerFront; + vs.windowPassengerRear = attributesMap.winPassengerRear; + vs.sunroof = attributesMap.sunroofState; + + vs.remainingFuel = attributesMap.remainingFuel; + vs.remainingRangeElectric = attributesMap.beRemainingRangeElectricKm; + vs.remainingRangeElectricMls = attributesMap.beRemainingRangeElectricMile; + vs.remainingRangeFuel = attributesMap.beRemainingRangeFuelKm; + vs.remainingRangeFuelMls = attributesMap.beRemainingRangeFuelMile; + vs.remainingFuel = attributesMap.remainingFuel; + vs.chargingLevelHv = attributesMap.chargingLevelHv; + vs.chargingStatus = attributesMap.chargingHVStatus; + vs.lastChargingEndReason = attributesMap.lastChargingEndReason; + + vs.updateTime = attributesMap.updateTimeConverted; + + Position p = new Position(); + p.lat = attributesMap.gpsLat; + p.lon = attributesMap.gpsLon; + p.heading = attributesMap.heading; + vs.position = p; + + final List ccml = new ArrayList(); + if (vehicleMessages != null) { + if (vehicleMessages.ccmMessages != null) { + vehicleMessages.ccmMessages.forEach(entry -> { + CCMMessage ccmM = new CCMMessage(); + ccmM.ccmDescriptionShort = entry.text; + ccmM.ccmDescriptionLong = Constants.HYPHEN; + ccmM.ccmMileage = entry.unitOfLengthRemaining; + ccml.add(ccmM); + }); + } + } + vs.checkControlMessages = ccml; + + final List cbsl = new ArrayList(); + if (vehicleMessages != null) { + if (vehicleMessages.cbsMessages != null) { + vehicleMessages.cbsMessages.forEach(entry -> { + CBSMessage cbsm = new CBSMessage(); + cbsm.cbsType = entry.text; + cbsm.cbsDescription = entry.description; + cbsm.cbsDueDate = entry.date; + cbsm.cbsRemainingMileage = entry.unitOfLengthRemaining; + cbsl.add(cbsm); + }); + } + } + vs.cbsData = cbsl; + return Converter.getGson().toJson(vsc); + } + } + return Constants.EMPTY_JSON; + } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java index 6b5cc6f2715d5..91221b930d572 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleTests.java @@ -380,7 +380,7 @@ public void testI01RexCompat() { setup(VehicleType.ELECTRIC_REX.toString(), false); String content = FileReader.readFileInString("src/test/resources/api/vehicle/vehicle-ccm.json"); VehicleAttributesContainer vac = Converter.getGson().fromJson(content, VehicleAttributesContainer.class); - assertTrue(testVehicle(vac.transform(), + assertTrue(testVehicle(Converter.transformLegacyStatus(vac), STATUS_ELECTRIC + DOORS + RANGE_HYBRID + SERVICE_AVAILABLE + CHECK_AVAILABLE + POSITION, Optional.empty())); } @@ -391,7 +391,7 @@ public void testI01RexMilesCompat() { setup(VehicleType.ELECTRIC_REX.toString(), true); String content = FileReader.readFileInString("src/test/resources/api/vehicle/vehicle-ccm.json"); VehicleAttributesContainer vac = Converter.getGson().fromJson(content, VehicleAttributesContainer.class); - assertTrue(testVehicle(vac.transform(), + assertTrue(testVehicle(Converter.transformLegacyStatus(vac), STATUS_ELECTRIC + DOORS + RANGE_HYBRID + SERVICE_AVAILABLE + CHECK_AVAILABLE + POSITION, Optional.empty())); } @@ -402,7 +402,7 @@ public void testF11Compat() { setup(VehicleType.CONVENTIONAL.toString(), false); String content = FileReader.readFileInString("src/test/resources/responses/F11/vehicle-status.json"); VehicleAttributesContainer vac = Converter.getGson().fromJson(content, VehicleAttributesContainer.class); - assertTrue(testVehicle(vac.transform(), + assertTrue(testVehicle(Converter.transformLegacyStatus(vac), STATUS_CONV + DOORS + RANGE_CONV + SERVICE_AVAILABLE + CHECK_EMPTY + POSITION, Optional.empty())); } @@ -412,7 +412,7 @@ public void testF11MilesCompat() { setup(VehicleType.CONVENTIONAL.toString(), true); String content = FileReader.readFileInString("src/test/resources/responses/F11/vehicle-status.json"); VehicleAttributesContainer vac = Converter.getGson().fromJson(content, VehicleAttributesContainer.class); - assertTrue(testVehicle(vac.transform(), + assertTrue(testVehicle(Converter.transformLegacyStatus(vac), STATUS_CONV + DOORS + RANGE_CONV + SERVICE_AVAILABLE + CHECK_EMPTY + POSITION, Optional.empty())); } } From 24eb066979237f49b1225618f6acba4c4e7ea0ec Mon Sep 17 00:00:00 2001 From: Bernd Weymann Date: Wed, 24 Mar 2021 02:05:21 +0100 Subject: [PATCH 156/176] solve further review comments Signed-off-by: Bernd Weymann --- .../README.md | 4 +- .../handler/ConnectedDriveBridgeHandler.java | 4 +- .../handler/VehicleChannelHandler.java | 39 +++++++++---------- .../internal/handler/VehicleHandler.java | 28 ++----------- .../internal/utils/Constants.java | 6 +++ .../i18n/bmwconnecteddrive_de.properties | 4 +- ...l-types.xml => location-channel-types.xml} | 0 .../OH-INF/thing/service-channel-types.xml | 2 +- .../main/resources/OH-INF/thing/thing-bev.xml | 2 + .../resources/OH-INF/thing/thing-bev_rex.xml | 2 + .../resources/OH-INF/thing/thing-conv.xml | 2 + .../resources/OH-INF/thing/thing-phev.xml | 2 + .../internal/dto/LifetimeWrapper.java | 10 ++--- .../internal/dto/StatusWrapper.java | 4 +- .../internal/dto/TripWrapper.java | 6 +-- 15 files changed, 49 insertions(+), 66 deletions(-) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/{loction-channel-types.xml => location-channel-types.xml} (100%) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 1bede6b3c5df7..ccf6aceb8468f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -63,7 +63,7 @@ Basically 3 types of information are registered as properties In the right picture can see in *Services Activated* e.g. the *DoorLock* and *DoorUnlock* services are mentioned. This ensures channel group [Remote Services](#remote-services) is supporting door lock and unlock remote control. -In *Services Supported* the entry *LastDestination* is mentioned. +In *Services Supported* the entry *LastDestination* is mentioned. So it's valid to connect channel group [Last Destinations](#destinations) in order to display and select the last navigation destinations. | Property Key | Property Value | Supported Channel Groups | @@ -531,7 +531,7 @@ are anonymized. You'll find the fingerprint in the logs with the command ``` -grep "BMW ConnectedDrive Binding" openhab.log +grep "Troubleshoot Fingerprint Data" openhab.log ``` After the corresponding fingerprint is generated please [follow the instructions to raise an issue](https://community.openhab.org/t/how-to-file-an-issue/68464) and attach the fingerprint data! diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java index 63177f9c6d617..7230b34c559d3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java @@ -122,10 +122,10 @@ public String getDiscoveryFingerprint() { } private void logFingerPrint() { - logger.debug("###### BMW ConnectedDrive Binding - Discovery Troubleshoot Fingerprint Data - BEGIN ######"); + logger.debug("###### Discovery Troubleshoot Fingerprint Data - BEGIN ######"); logger.debug("### Discovery Result ###"); logger.debug("{}", getDiscoveryFingerprint()); - logger.debug("###### BMW ConnectedDrive Binding - Discovery Troubleshoot Fingerprint Data - END ######"); + logger.debug("###### Discovery Troubleshoot Fingerprint Data - END ######"); } /** diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 20f4519c1c95e..393a1daebd959 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -52,8 +52,6 @@ import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.StringType; import org.openhab.core.library.unit.ImperialUnits; -import org.openhab.core.library.unit.MetricPrefix; -import org.openhab.core.library.unit.SIUnits; import org.openhab.core.library.unit.Units; import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.Thing; @@ -165,9 +163,8 @@ protected void selectCheckControl(int index) { selectedCC = ccEntry.ccmDescriptionShort; updateChannel(CHANNEL_GROUP_CHECK_CONTROL, NAME, StringType.valueOf(ccEntry.ccmDescriptionShort)); updateChannel(CHANNEL_GROUP_CHECK_CONTROL, DETAILS, StringType.valueOf(ccEntry.ccmDescriptionLong)); - updateChannel(CHANNEL_GROUP_CHECK_CONTROL, MILEAGE, - QuantityType.valueOf(Converter.round(ccEntry.ccmMileage), - imperial ? ImperialUnits.MILE : MetricPrefix.KILO(SIUnits.METRE))); + updateChannel(CHANNEL_GROUP_CHECK_CONTROL, MILEAGE, QuantityType.valueOf( + Converter.round(ccEntry.ccmMileage), imperial ? ImperialUnits.MILE : Constants.KILOMETRE_UNIT)); } } @@ -223,7 +220,7 @@ protected void selectService(int index) { DateTimeType.valueOf(Converter.getLocalDateTime(serviceEntry.getDueDate()))); updateChannel(CHANNEL_GROUP_SERVICE, MILEAGE, QuantityType.valueOf(Converter.round(serviceEntry.cbsRemainingMileage), - imperial ? ImperialUnits.MILE : MetricPrefix.KILO(SIUnits.METRE))); + imperial ? ImperialUnits.MILE : Constants.KILOMETRE_UNIT)); } } @@ -273,11 +270,11 @@ protected void selectDestination(int index) { protected void updateAllTrips(AllTrips allTrips) { QuantityType qtTotalElectric = QuantityType - .valueOf(Converter.round(allTrips.totalElectricDistance.userTotal), MetricPrefix.KILO(SIUnits.METRE)); + .valueOf(Converter.round(allTrips.totalElectricDistance.userTotal), Constants.KILOMETRE_UNIT); QuantityType qtLongestElectricRange = QuantityType - .valueOf(Converter.round(allTrips.chargecycleRange.userHigh), MetricPrefix.KILO(SIUnits.METRE)); - QuantityType qtDistanceSinceCharge = QuantityType.valueOf( - Converter.round(allTrips.chargecycleRange.userCurrentChargeCycle), MetricPrefix.KILO(SIUnits.METRE)); + .valueOf(Converter.round(allTrips.chargecycleRange.userHigh), Constants.KILOMETRE_UNIT); + QuantityType qtDistanceSinceCharge = QuantityType + .valueOf(Converter.round(allTrips.chargecycleRange.userCurrentChargeCycle), Constants.KILOMETRE_UNIT); updateChannel(CHANNEL_GROUP_LIFETIME, TOTAL_DRIVEN_DISTANCE, imperial ? Converter.getMiles(qtTotalElectric) : qtTotalElectric); @@ -310,7 +307,7 @@ protected void updateLastTrip(LastTrip trip) { updateChannel(CHANNEL_GROUP_LAST_TRIP, DURATION, QuantityType.valueOf(trip.duration, Units.MINUTE)); QuantityType qtTotalDistance = QuantityType.valueOf(Converter.round(trip.totalDistance), - MetricPrefix.KILO(SIUnits.METRE)); + Constants.KILOMETRE_UNIT); updateChannel(CHANNEL_GROUP_LAST_TRIP, DISTANCE, imperial ? Converter.getMiles(qtTotalDistance) : qtTotalDistance); @@ -418,7 +415,7 @@ protected void updateVehicleStatus(VehicleStatus vStatus) { updateChannel(CHANNEL_GROUP_STATUS, SERVICE_MILEAGE, QuantityType.valueOf(Converter.round(VehicleStatusUtils.getNextServiceMileage(vStatus)), - imperial ? ImperialUnits.MILE : MetricPrefix.KILO(SIUnits.METRE))); + imperial ? ImperialUnits.MILE : Constants.KILOMETRE_UNIT)); // CheckControl Active? updateChannel(CHANNEL_GROUP_STATUS, CHECK_CONTROL, StringType.valueOf(Converter.toTitleCase(VehicleStatusUtils.checkControlActive(vStatus)))); @@ -454,9 +451,9 @@ protected void updateVehicleStatus(VehicleStatus vStatus) { if (isElectric) { totalRange += vStatus.remainingRangeElectric; QuantityType qtElectricRange = QuantityType.valueOf(vStatus.remainingRangeElectric, - MetricPrefix.KILO(SIUnits.METRE)); - QuantityType qtElectricRadius = QuantityType.valueOf( - Converter.guessRangeRadius(vStatus.remainingRangeElectric), MetricPrefix.KILO(SIUnits.METRE)); + Constants.KILOMETRE_UNIT); + QuantityType qtElectricRadius = QuantityType + .valueOf(Converter.guessRangeRadius(vStatus.remainingRangeElectric), Constants.KILOMETRE_UNIT); updateChannel(CHANNEL_GROUP_RANGE, RANGE_ELECTRIC, imperial ? Converter.getMiles(qtElectricRange) : qtElectricRange); @@ -466,26 +463,26 @@ protected void updateVehicleStatus(VehicleStatus vStatus) { if (hasFuel) { totalRange += vStatus.remainingRangeFuel; QuantityType qtFuelRange = QuantityType.valueOf(vStatus.remainingRangeFuel, - MetricPrefix.KILO(SIUnits.METRE)); + Constants.KILOMETRE_UNIT); QuantityType qtFuelRadius = QuantityType - .valueOf(Converter.guessRangeRadius(vStatus.remainingRangeFuel), MetricPrefix.KILO(SIUnits.METRE)); + .valueOf(Converter.guessRangeRadius(vStatus.remainingRangeFuel), Constants.KILOMETRE_UNIT); updateChannel(CHANNEL_GROUP_RANGE, RANGE_FUEL, imperial ? Converter.getMiles(qtFuelRange) : qtFuelRange); updateChannel(CHANNEL_GROUP_RANGE, RANGE_RADIUS_FUEL, imperial ? Converter.getMiles(qtFuelRadius) : qtFuelRadius); } if (isHybrid) { - QuantityType qtHybridRange = QuantityType.valueOf(totalRange, MetricPrefix.KILO(SIUnits.METRE)); + QuantityType qtHybridRange = QuantityType.valueOf(totalRange, Constants.KILOMETRE_UNIT); QuantityType qtHybridRadius = QuantityType.valueOf(Converter.guessRangeRadius(totalRange), - MetricPrefix.KILO(SIUnits.METRE)); + Constants.KILOMETRE_UNIT); updateChannel(CHANNEL_GROUP_RANGE, RANGE_HYBRID, imperial ? Converter.getMiles(qtHybridRange) : qtHybridRange); updateChannel(CHANNEL_GROUP_RANGE, RANGE_RADIUS_HYBRID, imperial ? Converter.getMiles(qtHybridRadius) : qtHybridRadius); } - updateChannel(CHANNEL_GROUP_RANGE, MILEAGE, QuantityType.valueOf(vStatus.mileage, - imperial ? ImperialUnits.MILE : MetricPrefix.KILO(SIUnits.METRE))); + updateChannel(CHANNEL_GROUP_RANGE, MILEAGE, + QuantityType.valueOf(vStatus.mileage, imperial ? ImperialUnits.MILE : Constants.KILOMETRE_UNIT)); if (isElectric) { updateChannel(CHANNEL_GROUP_RANGE, SOC, QuantityType.valueOf(vStatus.chargingLevelHv, Units.PERCENT)); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 3d8b5156ea20b..bb21c396786a3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -322,7 +322,7 @@ private synchronized void removeCallback(ResponseCallback rc) { private void logFingerPrint() { final String vin = configuration.map(config -> config.vin).orElse(""); - logger.debug("###### BMW ConnectedDrive Binding - Vehicle Troubleshoot Fingerprint Data - BEGIN ######"); + logger.debug("###### Vehicle Troubleshoot Fingerprint Data - BEGIN ######"); logger.debug("### Discovery Result ###"); bridgeHandler.ifPresent(handler -> { logger.debug("{}", handler.getDiscoveryFingerprint()); @@ -403,7 +403,7 @@ private void logFingerPrint() { }, () -> { logger.debug("### Range Map Empty ###"); }); - logger.debug("###### BMW ConnectedDrive Binding - Vehicle Troubleshoot Fingerprint Data - END ######"); + logger.debug("###### Vehicle Troubleshoot Fingerprint Data - END ######"); } /** @@ -446,7 +446,6 @@ public ScheduledExecutorService getScheduler() { * @author Bernd Weymann * */ - @NonNullByDefault({}) public class ChargeProfilesCallback implements StringResponseCallback { @Override public void onResponse(@Nullable String content) { @@ -470,7 +469,6 @@ public void onError(NetworkError error) { } } - @NonNullByDefault({}) public class RangeMapCallback implements StringResponseCallback { @Override public void onResponse(@Nullable String content) { @@ -489,7 +487,6 @@ public void onError(NetworkError error) { } } - @NonNullByDefault({}) public class DestinationsCallback implements StringResponseCallback { @Override @@ -519,7 +516,6 @@ public void onError(NetworkError error) { } } - @NonNullByDefault({}) public class ImageCallback implements ByteResponseCallback { @Override public void onResponse(byte[] content) { @@ -548,7 +544,6 @@ public void onError(NetworkError error) { } } - @NonNullByDefault({}) public class AllTripsCallback implements StringResponseCallback { @Override public void onResponse(@Nullable String content) { @@ -580,7 +575,6 @@ public void onError(NetworkError error) { } } - @NonNullByDefault({}) public class LastTripCallback implements StringResponseCallback { @Override public void onResponse(@Nullable String content) { @@ -615,28 +609,13 @@ public void onError(NetworkError error) { /** * The VehicleStatus is supported by all Vehicle Types so it's used to reflect the Thing Status */ - @NonNullByDefault({}) public class VehicleStatusCallback implements StringResponseCallback { private ThingStatus thingStatus = ThingStatus.UNKNOWN; - /** - * Vehicle Status is supported by all Vehicles so callback result is used to report Thing Status. - * If valid content is delivered in onResponse Thing goes online while onError Thing goes offline - * - * @param status - * @param detail - * @param reason - */ - private void setThingStatus(ThingStatus status, ThingStatusDetail detail, String reason) { - if (thingStatus != status) { - updateStatus(status, detail, reason); - } - } - @Override public void onResponse(@Nullable String content) { if (content != null) { - setThingStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE, Constants.EMPTY); + updateStatus(ThingStatus.ONLINE); vehicleStatusCache = Optional.of(content); try { VehicleStatusContainer status = Converter.getGson().fromJson(content, VehicleStatusContainer.class); @@ -682,7 +661,6 @@ public void onError(NetworkError error) { * I figured out that only one API was working for this Vehicle. So this backward compatible Callback is introduced. * The delivered data is converted into the origin dto object so no changes in previous functional code needed */ - @NonNullByDefault({}) public class LegacyVehicleStatusCallback implements StringResponseCallback { @Override public void onResponse(@Nullable String content) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java index 4cb62126a7de8..e5be2ebfde48a 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Constants.java @@ -19,7 +19,12 @@ import java.util.HashMap; import java.util.Map; +import javax.measure.Unit; +import javax.measure.quantity.Length; + import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.core.library.unit.MetricPrefix; +import org.openhab.core.library.unit.SIUnits; import org.openhab.core.types.UnDefType; /** @@ -44,6 +49,7 @@ public class Constants { public static final String NULL_DATE = "1900-01-01T00:00:00"; public static final String NULL_TIME = "00:00"; public static final int INT_UNDEF = -1; + public static final Unit KILOMETRE_UNIT = MetricPrefix.KILO(SIUnits.METRE); // Services to query public static final String SERVICES_SUPPORTED = "servicesSupported"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties index 27678277abb68..338b5eee64d47 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties @@ -129,7 +129,7 @@ channel-group-type.bmwconnecteddrive.ev-vehicle-status.description = Zustand des channel-group-type.bmwconnecteddrive.location-values.label = Fahrzeug Standort channel-group-type.bmwconnecteddrive.location-values.description = Koordinaten und Ausrichtung des Fahrzeugs channel-group-type.bmwconnecteddrive.destination-values.label = Ziele -channel-group-type.bmwconnecteddrive.destination-values.description = Zeigt die gepseicherten Ziele des Fahrzeugs +channel-group-type.bmwconnecteddrive.destination-values.description = Zeigt die gespeicherten Ziele des Fahrzeugs channel-group-type.bmwconnecteddrive.troubleshoot-control.label = Fehlerbehebung channel-group-type.bmwconnecteddrive.troubleshoot-control.description = Generiert Daten zur Fehlerbehebung eines Problems channel-group-type.bmwconnecteddrive.door-values.label = Details aller Türen @@ -228,7 +228,7 @@ channel-type.bmwconnecteddrive.override-departure-minute-channel.label = Einmali channel-type.bmwconnecteddrive.override-enabled-channel.label = Einmaliges Zeitprofil - Aktiviert channel-type.bmwconnecteddrive.destination-name-channel.label = Zieladresse -channel-type.bmwconnecteddrive.destination-gps-channel.label = Ziel Koordinaten +channel-type.bmwconnecteddrive.destination-gps-channel.label = Zielkoordinaten channel-type.bmwconnecteddrive.gps-channel.label = Koordinaten channel-type.bmwconnecteddrive.heading-channel.label = Ausrichtung diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/loction-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/location-channel-types.xml similarity index 100% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/loction-channel-types.xml rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/location-channel-types.xml diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-channel-types.xml index 1fbefc9306f3d..ad54e90480ead 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-channel-types.xml @@ -13,7 +13,7 @@ DateTime - + Number:Length diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml index a32ddc1fee9d3..879443e8453e7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml @@ -27,6 +27,8 @@ + vin + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml index 19a6d6a0298d6..ddfb71969a7f6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml @@ -27,6 +27,8 @@ + vin + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml index 51ee215a7f819..33fb4751f7e66 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml @@ -24,6 +24,8 @@ + vin + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml index d1416e74095be..0e323c5f7d870 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml @@ -27,6 +27,8 @@ + vin + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java index 4a74867410a72..88861ba1d4275 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/LifetimeWrapper.java @@ -27,11 +27,10 @@ import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTrips; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.AllTripsContainer; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.unit.ImperialUnits; -import org.openhab.core.library.unit.MetricPrefix; -import org.openhab.core.library.unit.SIUnits; import org.openhab.core.library.unit.Units; import org.openhab.core.thing.ChannelUID; import org.openhab.core.types.State; @@ -48,7 +47,6 @@ public class LifetimeWrapper { private static final Gson GSON = new Gson(); private static final Unit MILES = ImperialUnits.MILE; - private static final Unit KILOMETRE = MetricPrefix.KILO(SIUnits.METRE); private AllTrips allTrips; private boolean imperial; @@ -112,7 +110,7 @@ private void checkResult(ChannelUID channelUID, State state) { assertEquals(allTrips.chargecycleRange.userCurrentChargeCycle / Converter.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, "Distance since charging"); } else { - assertEquals(KILOMETRE, qt.getUnit(), "KM"); + assertEquals(Constants.KILOMETRE_UNIT, qt.getUnit(), "KM"); assertEquals(allTrips.chargecycleRange.userCurrentChargeCycle, qt.floatValue(), 0.1, "Distance since charging"); } @@ -125,7 +123,7 @@ private void checkResult(ChannelUID channelUID, State state) { assertEquals(allTrips.chargecycleRange.userHigh / Converter.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, "Longest Distance"); } else { - assertEquals(KILOMETRE, qt.getUnit(), "KM"); + assertEquals(Constants.KILOMETRE_UNIT, qt.getUnit(), "KM"); assertEquals(allTrips.chargecycleRange.userHigh, qt.floatValue(), 0.1, "Longest Distance"); } break; @@ -137,7 +135,7 @@ private void checkResult(ChannelUID channelUID, State state) { assertEquals(allTrips.totalElectricDistance.userTotal / Converter.MILES_TO_KM_RATIO, qt.floatValue(), 0.1, "Total Electric Distance"); } else { - assertEquals(KILOMETRE, qt.getUnit(), "KM"); + assertEquals(Constants.KILOMETRE_UNIT, qt.getUnit(), "KM"); assertEquals(allTrips.totalElectricDistance.userTotal, qt.floatValue(), 0.1, "Total Electric Distance"); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index 4b5db90c66d54..d778d053470e5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -38,8 +38,6 @@ import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.StringType; import org.openhab.core.library.unit.ImperialUnits; -import org.openhab.core.library.unit.MetricPrefix; -import org.openhab.core.library.unit.SIUnits; import org.openhab.core.library.unit.Units; import org.openhab.core.thing.ChannelUID; import org.openhab.core.types.State; @@ -56,7 +54,7 @@ @SuppressWarnings("null") public class StatusWrapper { private static final Gson GSON = new Gson(); - private static final Unit KILOMETRE = MetricPrefix.KILO(SIUnits.METRE); + private static final Unit KILOMETRE = Constants.KILOMETRE_UNIT; private static final double ALLOWED_MILE_CONVERSION_DEVIATION = 1.5; private static final double ALLOWED_KM_ROUND_DEVIATION = 0.1; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java index b60bae9c451b7..9a386ae5d76db 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/TripWrapper.java @@ -27,12 +27,11 @@ import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants.VehicleType; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTrip; import org.openhab.binding.bmwconnecteddrive.internal.dto.statistics.LastTripContainer; +import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.unit.ImperialUnits; -import org.openhab.core.library.unit.MetricPrefix; -import org.openhab.core.library.unit.SIUnits; import org.openhab.core.library.unit.Units; import org.openhab.core.thing.ChannelUID; import org.openhab.core.types.State; @@ -49,7 +48,6 @@ public class TripWrapper { private static final Gson GSON = new Gson(); private static final Unit MILES = ImperialUnits.MILE; - private static final Unit KILOMETRE = MetricPrefix.KILO(SIUnits.METRE); private LastTrip lastTrip; private boolean imperial; @@ -127,7 +125,7 @@ private void checkResult(ChannelUID channelUID, State state) { "Distance"); } else { - assertEquals(KILOMETRE, qt.getUnit(), "KM"); + assertEquals(Constants.KILOMETRE_UNIT, qt.getUnit(), "KM"); assertEquals(lastTrip.totalDistance, qt.floatValue(), 0.1, "Distance"); } break; From f83b0ada9f5cd12620a5c247af257d94f8921910 Mon Sep 17 00:00:00 2001 From: Bernd Weymann Date: Thu, 25 Mar 2021 17:35:29 +0100 Subject: [PATCH 157/176] Bugfix: legacy mode Signed-off-by: Bernd Weymann --- .../internal/handler/VehicleHandler.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index bb21c396786a3..500cec4cd43fa 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -639,13 +639,12 @@ public void onResponse(@Nullable String content) { @Override public void onError(NetworkError error) { logger.debug("{}", error.toString()); - if (error.status == 404) { - legacyMode = true; - logger.debug("VehicleStatus not found - switch to legacy API"); + if (error.status != 200) { + logger.debug("VehicleStatus not found - try legacy API"); proxy.get().requestLegacyVehcileStatus(configuration.get(), oldVehicleStatusCallback); } vehicleStatusCache = Optional.of(Converter.getGson().toJson(error)); - setThingStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, error.reason); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, error.reason); removeCallback(this); } } @@ -669,6 +668,8 @@ public void onResponse(@Nullable String content) { VehicleAttributesContainer vac = Converter.getGson().fromJson(content, VehicleAttributesContainer.class); vehicleStatusCallback.onResponse(Converter.transformLegacyStatus(vac)); + legacyMode = true; + logger.debug("VehicleStatus switched to legacy mode"); } catch (JsonSyntaxException jse) { logger.debug("{}", jse.getMessage()); } @@ -677,6 +678,7 @@ public void onResponse(@Nullable String content) { @Override public void onError(NetworkError error) { + logger.debug("{}", error.toString()); vehicleStatusCallback.onError(error); } } From a3234a7929752fbd679e01dbe0553825a65d8b6f Mon Sep 17 00:00:00 2001 From: Bernd Weymann Date: Sat, 27 Mar 2021 23:29:45 +0100 Subject: [PATCH 158/176] improve error handling Signed-off-by: Bernd Weymann --- .../handler/ConnectedDriveBridgeHandler.java | 28 +++++++++-- .../internal/handler/ConnectedDriveProxy.java | 15 +++--- .../handler/RemoteServiceHandler.java | 12 ++--- .../internal/handler/VehicleHandler.java | 50 +++++++++---------- .../internal/handler/ConfigurationTest.java | 47 +++++++++++++++++ 5 files changed, 106 insertions(+), 46 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConfigurationTest.java diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java index 7230b34c559d3..03439485758f3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java @@ -27,6 +27,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; import org.openhab.binding.bmwconnecteddrive.internal.dto.discovery.Dealer; import org.openhab.binding.bmwconnecteddrive.internal.dto.discovery.VehiclesContainer; +import org.openhab.binding.bmwconnecteddrive.internal.utils.BimmerConstants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; import org.openhab.binding.bmwconnecteddrive.internal.utils.Converter; import org.openhab.core.io.net.http.HttpClientFactory; @@ -71,10 +72,29 @@ public void handleCommand(ChannelUID channelUID, Command command) { public void initialize() { troubleshootFingerprint = Optional.empty(); updateStatus(ThingStatus.UNKNOWN); - proxy = Optional.of(new ConnectedDriveProxy(httpClientFactory, getConfigAs(ConnectedDriveConfiguration.class))); - // give the system some time to create all predefined Vehicles - // check with API call if bridge is online - initializerJob = Optional.of(scheduler.schedule(this::requestVehicles, 5, TimeUnit.SECONDS)); + ConnectedDriveConfiguration config = getConfigAs(ConnectedDriveConfiguration.class); + if (checkConfiguration(config) == false) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR); + } else { + proxy = Optional.of(new ConnectedDriveProxy(httpClientFactory, config)); + // give the system some time to create all predefined Vehicles + // check with API call if bridge is online + initializerJob = Optional.of(scheduler.schedule(this::requestVehicles, 5, TimeUnit.SECONDS)); + } + } + + public static boolean checkConfiguration(ConnectedDriveConfiguration config) { + if (Constants.EMPTY.equals(config.userName)) { + return false; + } + if (Constants.EMPTY.equals(config.password)) { + return false; + } + if (BimmerConstants.AUTH_SERVER_MAP.containsKey(config.region)) { + return true; + } else { + return false; + } } @Override diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java index 3e749c6587f50..af2164bf87b05 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveProxy.java @@ -87,11 +87,6 @@ public ConnectedDriveProxy(HttpClientFactory httpClientFactory, ConnectedDriveCo httpClient = httpClientFactory.getCommonHttpClient(); authHttpClient = httpClientFactory.createHttpClient(AUTH_HTTP_CLIENT_NAME); authHttpClient.setFollowRedirects(false); - try { - authHttpClient.start(); - } catch (Exception e) { - logger.warn("Auth Http Client cannot be started"); - } configuration = config; final StringBuilder legacyAuth = new StringBuilder(); @@ -252,8 +247,16 @@ public Token getToken() { * @return */ private synchronized void updateToken() { - final Request req = authHttpClient.POST(legacyAuthUri); + if (!authHttpClient.isStarted()) { + try { + authHttpClient.start(); + } catch (Exception e) { + logger.warn("Auth Http Client cannot be started {}", e.getMessage()); + return; + } + } + final Request req = authHttpClient.POST(legacyAuthUri); req.header(HttpHeader.CONNECTION, KEEP_ALIVE); req.header(HttpHeader.HOST, getRegionServer()); req.header(HttpHeader.AUTHORIZATION, getAuthorizationValue()); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java index 353ba1acb0bdf..fc1999d46aac0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/RemoteServiceHandler.java @@ -98,15 +98,9 @@ public String getLabel() { public RemoteServiceHandler(VehicleHandler vehicleHandler, ConnectedDriveProxy connectedDriveProxy) { handler = vehicleHandler; proxy = connectedDriveProxy; - if (handler.getConfiguration().isPresent()) { - final VehicleConfiguration config = handler.getConfiguration().get(); - serviceExecutionAPI = proxy.baseUrl + config.vin + proxy.serviceExecutionAPI; - serviceExecutionStateAPI = proxy.baseUrl + config.vin + proxy.serviceExecutionStateAPI; - } else { - serviceExecutionAPI = Constants.INVALID; - serviceExecutionStateAPI = Constants.INVALID; - logger.warn("No configuration for VehicleHandler available"); - } + final VehicleConfiguration config = handler.getConfiguration().get(); + serviceExecutionAPI = proxy.baseUrl + config.vin + proxy.serviceExecutionAPI; + serviceExecutionStateAPI = proxy.baseUrl + config.vin + proxy.serviceExecutionStateAPI; } boolean execute(RemoteService service, String... data) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 500cec4cd43fa..eac983e3e0907 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -218,36 +218,34 @@ public void initialize() { updateStatus(ThingStatus.UNKNOWN); final VehicleConfiguration config = getConfigAs(VehicleConfiguration.class); configuration = Optional.of(config); - scheduler.execute(() -> { - Bridge bridge = getBridge(); - if (bridge != null) { - BridgeHandler handler = bridge.getHandler(); - if (handler != null) { - bridgeHandler = Optional.of(((ConnectedDriveBridgeHandler) handler)); - proxy = ((ConnectedDriveBridgeHandler) handler).getProxy(); - remote = proxy.map(prox -> prox.getRemoteServiceHandler(this)); - } else { - logger.debug("Bridge Handler null"); - } + Bridge bridge = getBridge(); + if (bridge != null) { + BridgeHandler handler = bridge.getHandler(); + if (handler != null) { + bridgeHandler = Optional.of(((ConnectedDriveBridgeHandler) handler)); + proxy = ((ConnectedDriveBridgeHandler) handler).getProxy(); + remote = proxy.map(prox -> prox.getRemoteServiceHandler(this)); } else { - logger.debug("Bridge null"); + logger.debug("Bridge Handler null"); } + } else { + logger.debug("Bridge null"); + } - // get Image after init with config values - synchronized (imageProperties) { - imageProperties = new ImageProperties(config.imageViewport, config.imageSize); - } - updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_VIEWPORT, StringType.valueOf((config.imageViewport))); - updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_SIZE, new DecimalType((config.imageSize))); + // get Image after init with config values + synchronized (imageProperties) { + imageProperties = new ImageProperties(config.imageViewport, config.imageSize); + } + updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_VIEWPORT, StringType.valueOf((config.imageViewport))); + updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_SIZE, new DecimalType((config.imageSize))); - // check imperial setting is different to AutoDetect - if (!UNITS_AUTODETECT.equals(config.units)) { - imperial = UNITS_IMPERIAL.equals(config.units); - } + // check imperial setting is different to AutoDetect + if (!UNITS_AUTODETECT.equals(config.units)) { + imperial = UNITS_IMPERIAL.equals(config.units); + } - // start update schedule - startSchedule(config.refreshInterval); - }); + // start update schedule + startSchedule(config.refreshInterval); } private void startSchedule(int interval) { @@ -610,8 +608,6 @@ public void onError(NetworkError error) { * The VehicleStatus is supported by all Vehicle Types so it's used to reflect the Thing Status */ public class VehicleStatusCallback implements StringResponseCallback { - private ThingStatus thingStatus = ThingStatus.UNKNOWN; - @Override public void onResponse(@Nullable String content) { if (content != null) { diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConfigurationTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConfigurationTest.java new file mode 100644 index 0000000000000..4f5ab1caf16df --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConfigurationTest.java @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2010-2021 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.bmwconnecteddrive.internal.handler; + +import static org.junit.jupiter.api.Assertions.*; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.junit.jupiter.api.Test; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConfiguration; +import org.openhab.binding.bmwconnecteddrive.internal.utils.BimmerConstants; + +/** + * The {@link ConfigurationTest} test different configurations + * + * @author Bernd Weymann - Initial contribution + */ +@NonNullByDefault +public class ConfigurationTest { + + @Test + public void testAuthServerMap() { + ConnectedDriveConfiguration cdc = new ConnectedDriveConfiguration(); + assertFalse(ConnectedDriveBridgeHandler.checkConfiguration(cdc)); + cdc.userName = "a"; + assertFalse(ConnectedDriveBridgeHandler.checkConfiguration(cdc)); + cdc.password = "b"; + assertFalse(ConnectedDriveBridgeHandler.checkConfiguration(cdc)); + cdc.region = "c"; + assertFalse(ConnectedDriveBridgeHandler.checkConfiguration(cdc)); + cdc.region = BimmerConstants.REGION_NORTH_AMERICA; + assertTrue(ConnectedDriveBridgeHandler.checkConfiguration(cdc)); + cdc.region = BimmerConstants.REGION_ROW; + assertTrue(ConnectedDriveBridgeHandler.checkConfiguration(cdc)); + cdc.region = BimmerConstants.REGION_CHINA; + assertTrue(ConnectedDriveBridgeHandler.checkConfiguration(cdc)); + } +} From 570b80b817a52aad914f324996e58f694c868e29 Mon Sep 17 00:00:00 2001 From: Bernd Weymann Date: Sun, 28 Mar 2021 00:22:33 +0100 Subject: [PATCH 159/176] review findings error logging Signed-off-by: Bernd Weymann --- .../handler/ConnectedDriveBridgeHandler.java | 10 +++------- .../internal/handler/VehicleHandler.java | 2 -- .../internal/utils/ChargeProfileUtils.java | 20 +++++++++---------- .../internal/utils/ChargeProfileWrapper.java | 12 +++++------ 4 files changed, 19 insertions(+), 25 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java index 03439485758f3..5c7ac485d5bfe 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ConnectedDriveBridgeHandler.java @@ -73,7 +73,7 @@ public void initialize() { troubleshootFingerprint = Optional.empty(); updateStatus(ThingStatus.UNKNOWN); ConnectedDriveConfiguration config = getConfigAs(ConnectedDriveConfiguration.class); - if (checkConfiguration(config) == false) { + if (!checkConfiguration(config)) { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR); } else { proxy = Optional.of(new ConnectedDriveProxy(httpClientFactory, config)); @@ -84,13 +84,9 @@ public void initialize() { } public static boolean checkConfiguration(ConnectedDriveConfiguration config) { - if (Constants.EMPTY.equals(config.userName)) { + if (Constants.EMPTY.equals(config.userName) || Constants.EMPTY.equals(config.password)) { return false; - } - if (Constants.EMPTY.equals(config.password)) { - return false; - } - if (BimmerConstants.AUTH_SERVER_MAP.containsKey(config.region)) { + } else if (BimmerConstants.AUTH_SERVER_MAP.containsKey(config.region)) { return true; } else { return false; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index eac983e3e0907..7db63980b93a1 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -771,8 +771,6 @@ public Collection> getServices() { public Optional getChargeProfileWrapper() { return chargeProfileCache.flatMap(cache -> { return ChargeProfileWrapper.fromJson(cache).map(wrapper -> { - logger.debug("Charge Profile editing - start"); - logger.debug("{}", wrapper.getJson()); return wrapper; }).or(() -> { logger.debug("cannot parse charging profile: {}", cache); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java index a6b3c50c17085..4a8e865c3f5e3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java @@ -34,15 +34,15 @@ public class ChargeProfileUtils { // Charging public static class TimedChannel { + public final String time; + public final @Nullable String timer; + public final boolean hasDays; + TimedChannel(final String time, @Nullable final String timer, final boolean hasDays) { this.time = time; this.timer = timer; this.hasDays = hasDays; } - - public final String time; - public final @Nullable String timer; - public final boolean hasDays; } @SuppressWarnings("serial") @@ -71,23 +71,23 @@ public static class TimedChannel { }; public static class ChargeKeyHour { + public final ProfileKey key; + public final boolean isHour; + ChargeKeyHour(final ProfileKey key, final boolean isHour) { this.key = key; this.isHour = isHour; } - - public final ProfileKey key; - public final boolean isHour; } public static class ChargeKeyDay { + public final ProfileKey key; + public final DayOfWeek day; + ChargeKeyDay(final ProfileKey key, final DayOfWeek day) { this.key = key; this.day = day; } - - public final ProfileKey key; - public final DayOfWeek day; } @SuppressWarnings("serial") diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java index 4b67645a4c92c..adec905cec6bb 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java @@ -46,8 +46,7 @@ */ @NonNullByDefault public class ChargeProfileWrapper { - - private final Logger logger = LoggerFactory.getLogger(ChargeProfileWrapper.class); + private static final Logger LOGGER = LoggerFactory.getLogger(ChargeProfileWrapper.class); public enum ProfileType { WEEKLY, @@ -82,6 +81,7 @@ public static Optional fromJson(final String content) { return Optional.of(new ChargeProfileWrapper(cp)); } } catch (JsonSyntaxException jse) { + LOGGER.debug("ChargeProfile unparsable: {}", content); } return Optional.empty(); } @@ -149,7 +149,7 @@ public void setMode(final @Nullable String mode) { this.mode = Optional.of(ChargingMode.valueOf(mode)); return; } catch (IllegalArgumentException iae) { - logger.warn("unexpected value for chargingMode: {}", mode); + LOGGER.warn("unexpected value for chargingMode: {}", mode); } } this.mode = Optional.empty(); @@ -165,7 +165,7 @@ public void setPreference(final @Nullable String preference) { this.preference = Optional.of(ChargingPreference.valueOf(preference)); return; } catch (IllegalArgumentException iae) { - logger.warn("unexpected value for chargingPreference: {}", preference); + LOGGER.warn("unexpected value for chargingPreference: {}", preference); } } this.preference = Optional.empty(); @@ -258,7 +258,7 @@ private void addTime(final ProfileKey key, @Nullable final String time) { try { times.put(key, time == null ? NULL_LOCAL_TIME : LocalTime.parse(time, TIME_FORMATER)); } catch (DateTimeParseException dtpe) { - logger.warn("unexpected value for {} time: {}", key.name(), time); + LOGGER.warn("unexpected value for {} time: {}", key.name(), time); } } @@ -279,7 +279,7 @@ private void addTimer(final ProfileKey key, @Nullable final Timer timer) { try { daySet.add(DayOfWeek.valueOf(day)); } catch (IllegalArgumentException iae) { - logger.warn("unexpected value for {} day: {}", key.name(), day); + LOGGER.warn("unexpected value for {} day: {}", key.name(), day); } } } From d9aefdb20b4153e727f208daca9ad374739fac6b Mon Sep 17 00:00:00 2001 From: Bernd Weymann Date: Sun, 28 Mar 2021 01:07:52 +0100 Subject: [PATCH 160/176] correct undef handling Signed-off-by: Bernd Weymann --- .../internal/utils/Converter.java | 14 ++++++++---- .../internal/utils/VehicleStatusUtils.java | 2 -- .../internal/discovery/DiscoveryTest.java | 1 - .../internal/dto/StatusWrapper.java | 22 ++++++++++--------- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java index 8698ec8be68a9..bc6e3fc75bef6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/Converter.java @@ -36,6 +36,10 @@ import org.openhab.core.i18n.TimeZoneProvider; import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.unit.ImperialUnits; +import org.openhab.core.types.State; +import org.openhab.core.types.UnDefType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.gson.Gson; @@ -46,6 +50,8 @@ */ @NonNullByDefault public class Converter { + public static final Logger LOGGER = LoggerFactory.getLogger(Converter.class); + public static final DateTimeFormatter SERVICE_DATE_INPUT_PATTERN = DateTimeFormatter.ofPattern("yyyy-MM-dd"); public static final DateTimeFormatter SERVICE_DATE_OUTPUT_PATTERN = DateTimeFormatter.ofPattern("MMM yyyy"); @@ -65,7 +71,6 @@ public class Converter { private static final Gson GSON = new Gson(); private static final double SCALE = 10; public static final double MILES_TO_KM_RATIO = 1.60934; - private static final QuantityType UNDEF_MILES = QuantityType.valueOf(-1, ImperialUnits.MILE); private static final String SPLIT_HYPHEN = "-"; private static final String SPLIT_BRACKET = "\\("; @@ -191,15 +196,16 @@ public static double guessRangeRadius(double range) { return range * 0.8; } - public static QuantityType getMiles(QuantityType qtLength) { + public static State getMiles(QuantityType qtLength) { if (qtLength.intValue() == -1) { - return UNDEF_MILES; + return UnDefType.UNDEF; } QuantityType qt = qtLength.toUnit(ImperialUnits.MILE); if (qt != null) { return qt; } else { - return QuantityType.valueOf(qtLength.doubleValue() / MILES_TO_KM_RATIO, ImperialUnits.MILE); + LOGGER.debug("Cannot convert {} to miles", qt); + return UnDefType.UNDEF; } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/VehicleStatusUtils.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/VehicleStatusUtils.java index 03f1b4e314c17..1a11ee69643b3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/VehicleStatusUtils.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/VehicleStatusUtils.java @@ -42,8 +42,6 @@ public static String getNextServiceDate(VehicleStatus vStatus) { CBSMessage entry = vStatus.cbsData.get(i); if (entry.cbsDueDate != null) { LocalDateTime d = LocalDateTime.parse(entry.cbsDueDate + Constants.UTC_APPENDIX); - // LocalDate d = LocalDate.parse(entry.cbsDueDate + APPENDIX_DAY, - // Converter.SERVICE_DATE_INPUT_PATTERN); if (d.isBefore(serviceDate)) { serviceDate = d; } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java index dacf3224ef64d..612b990cfb60f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/discovery/DiscoveryTest.java @@ -39,7 +39,6 @@ * @author Bernd Weymann - Initial contribution */ @NonNullByDefault -@SuppressWarnings("null") public class DiscoveryTest { private final Logger logger = LoggerFactory.getLogger(DiscoveryTest.class); private static final Gson GSON = new Gson(); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java index d778d053470e5..acd54c5478fb5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/dto/StatusWrapper.java @@ -166,16 +166,18 @@ private void checkResult(ChannelUID channelUID, State state) { break; case RANGE_FUEL: assertTrue(hasFuel, "Has Fuel"); - assertTrue(state instanceof QuantityType); - qt = ((QuantityType) state); - if (imperial) { - assertEquals(ImperialUnits.MILE, qt.getUnit(), "Miles"); - assertEquals(Converter.round(qt.floatValue()), Converter.round(vStatus.remainingRangeFuelMls), - ALLOWED_MILE_CONVERSION_DEVIATION, "Mileage"); - } else { - assertEquals(KILOMETRE, qt.getUnit(), "KM"); - assertEquals(Converter.round(qt.floatValue()), Converter.round(vStatus.remainingRangeFuel), - ALLOWED_KM_ROUND_DEVIATION, "Mileage"); + if (!(state instanceof UnDefType)) { + assertTrue(state instanceof QuantityType); + qt = ((QuantityType) state); + if (imperial) { + assertEquals(ImperialUnits.MILE, qt.getUnit(), "Miles"); + assertEquals(Converter.round(qt.floatValue()), Converter.round(vStatus.remainingRangeFuelMls), + ALLOWED_MILE_CONVERSION_DEVIATION, "Mileage"); + } else { + assertEquals(KILOMETRE, qt.getUnit(), "KM"); + assertEquals(Converter.round(qt.floatValue()), Converter.round(vStatus.remainingRangeFuel), + ALLOWED_KM_ROUND_DEVIATION, "Mileage"); + } } break; case RANGE_HYBRID: From a1a1650bc1870894fa4ba4d8f67eda5f132022a2 Mon Sep 17 00:00:00 2001 From: Bernd Weymann Date: Sun, 28 Mar 2021 01:22:51 +0100 Subject: [PATCH 161/176] fix translations Signed-off-by: Bernd Weymann --- .../resources/OH-INF/i18n/bmwconnecteddrive_de.properties | 6 +++++- .../main/resources/OH-INF/thing/charge-channel-types.xml | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties index 338b5eee64d47..9b0721266095e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties @@ -133,7 +133,7 @@ channel-group-type.bmwconnecteddrive.destination-values.description = Zeigt die channel-group-type.bmwconnecteddrive.troubleshoot-control.label = Fehlerbehebung channel-group-type.bmwconnecteddrive.troubleshoot-control.description = Generiert Daten zur Fehlerbehebung eines Problems channel-group-type.bmwconnecteddrive.door-values.label = Details aller Türen -channel-group-type.bmwconnecteddrive.door-values.description = Zeigt die Dezails der Türen und Fenster des Fahrzeugs +channel-group-type.bmwconnecteddrive.door-values.description = Zeigt die Details der Türen und Fenster des Fahrzeugs # Channel Types channel-type.bmwconnecteddrive.doors-channel.label = Gesamtzustand der Türen @@ -179,7 +179,11 @@ channel-type.bmwconnecteddrive.checkcontrol-mileage-channel.label = Warnung bei channel-type.bmwconnecteddrive.profile-climate-channel.label = Klimatisierung bei Abfahrt channel-type.bmwconnecteddrive.profile-mode-channel.label = Ladeprofil Methode +channel-type.bmwconnecteddrive.profile-mode-channel.option.IMMEDIATE_CHARGING = Sofortiges Laden +channel-type.bmwconnecteddrive.profile-mode-channel.option.DELAYED_CHARGING = Laden im Zeitfenster channel-type.bmwconnecteddrive.profile-prefs-channel.label = Ladeprofil Präferenz +channel-type.bmwconnecteddrive.profile-prefs-channel.option.NO_PRESELECTION = Keine Präferenz +channel-type.bmwconnecteddrive.profile-prefs-channel.option.Charging Window = Zeitfenster channel-type.bmwconnecteddrive.window-start-channel.label = Startzeit Ladefenster channel-type.bmwconnecteddrive.window-start-hour-channel.label = Startzeit Ladefenster Stunde channel-type.bmwconnecteddrive.window-start-minute-channel.label = Startzeit Ladefenster Minute diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml index 722be1cbf9d14..32201aa6d4a49 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml @@ -22,8 +22,8 @@ - - + + From 91f7f261d40d626028ef8daf7027a76198424a40 Mon Sep 17 00:00:00 2001 From: Bernd Weymann Date: Sun, 28 Mar 2021 03:19:40 +0200 Subject: [PATCH 162/176] xml review finding corrections Signed-off-by: Bernd Weymann --- bundles/org.openhab.binding.bmwconnecteddrive/README.md | 2 +- .../resources/OH-INF/i18n/bmwconnecteddrive_de.properties | 2 +- .../src/main/resources/OH-INF/thing/charge-channel-types.xml | 4 ++-- .../src/main/resources/OH-INF/thing/range-channel-types.xml | 4 ++-- .../src/main/resources/OH-INF/thing/thing-bev.xml | 4 ++-- .../src/main/resources/OH-INF/thing/thing-bev_rex.xml | 4 ++-- .../src/main/resources/OH-INF/thing/thing-conv.xml | 4 ++-- .../src/main/resources/OH-INF/thing/thing-phev.xml | 4 ++-- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index ccf6aceb8468f..375f98df5fb23 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -31,7 +31,7 @@ The bridge establishes the connection between BMW's ConnectedDrive Portal and op | Name | Bridge Type ID | Description | |----------------------------|----------------|------------------------------------------------------------| -| BMW ConnectedDrive Account | account | Access to BMW ConnectedDrive Portal for a specific user | +| BMW ConnectedDrive Account | `account` | Access to BMW ConnectedDrive Portal for a specific user | ### Things diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties index 9b0721266095e..f7796b26ce2e8 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties @@ -178,7 +178,7 @@ channel-type.bmwconnecteddrive.checkcontrol-details-channel.label = Warnung Deta channel-type.bmwconnecteddrive.checkcontrol-mileage-channel.label = Warnung bei Kilometer channel-type.bmwconnecteddrive.profile-climate-channel.label = Klimatisierung bei Abfahrt -channel-type.bmwconnecteddrive.profile-mode-channel.label = Ladeprofil Methode +channel-type.bmwconnecteddrive.profile-mode-channel.label = Ladeprofil channel-type.bmwconnecteddrive.profile-mode-channel.option.IMMEDIATE_CHARGING = Sofortiges Laden channel-type.bmwconnecteddrive.profile-mode-channel.option.DELAYED_CHARGING = Laden im Zeitfenster channel-type.bmwconnecteddrive.profile-prefs-channel.label = Ladeprofil Präferenz diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml index 32201aa6d4a49..fbe966aa021dc 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml @@ -9,7 +9,7 @@ String - + @@ -19,7 +19,7 @@ String - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/range-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/range-channel-types.xml index dede3c66e1630..d0e286ed696ae 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/range-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/range-channel-types.xml @@ -25,11 +25,11 @@ Number:Volume - + Number:Length - + Number:Length diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml index 879443e8453e7..20d7e32d4ade2 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml @@ -35,8 +35,8 @@ Unique VIN given by BMW - - Data Refresh Rate for your Vehicle data + + Data Refresh Rate for your Vehicle data 5 diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml index ddfb71969a7f6..0a09485fce080 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml @@ -35,8 +35,8 @@ Unique VIN given by BMW - - Data Refresh Rate for your Vehicle data + + Data Refresh Rate for your Vehicle data 5 diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml index 33fb4751f7e66..13bc34c8f3f66 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml @@ -32,8 +32,8 @@ Unique VIN given by BMW - - Data Refresh Rate for your Vehicle data + + Data Refresh Rate for your Vehicle data 5 diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml index 0e323c5f7d870..69704924ad8c9 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml @@ -35,8 +35,8 @@ Unique VIN given by BMW - - Data Refresh Rate for your Vehicle data + + Data Refresh Rate for your Vehicle data 5 From bf1df0754bc0f53107886ef3f4e1945a251dd841 Mon Sep 17 00:00:00 2001 From: Bernd Weymann Date: Mon, 29 Mar 2021 00:22:55 +0200 Subject: [PATCH 163/176] move config declaration into separate files Signed-off-by: Bernd Weymann --- .../README.md | 8 ++-- .../resources/OH-INF/config/bridge-config.xml | 28 ++++++++++++ .../resources/OH-INF/config/thing-config.xml | 45 +++++++++++++++++++ .../OH-INF/thing/bridge-connected-drive.xml | 24 +--------- .../main/resources/OH-INF/thing/thing-bev.xml | 39 +--------------- .../resources/OH-INF/thing/thing-bev_rex.xml | 39 +--------------- .../resources/OH-INF/thing/thing-conv.xml | 39 +--------------- .../resources/OH-INF/thing/thing-phev.xml | 39 +--------------- 8 files changed, 82 insertions(+), 179 deletions(-) create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/config/bridge-config.xml create mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/config/thing-config.xml diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 375f98df5fb23..f081e31857314 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -43,10 +43,10 @@ For hybrid vehicles in addition to _Fuel and Electric Range_ the _Hybrid Range_ | Name | Thing Type ID | Supported Channel Groups | |-------------------------------------|---------------|--------------------------------------------------------| -| BMW Electric Vehicle | bev | status, range, location, service, check, charge, image | -| BMW Electric Vehicle with REX | bev_rex | status, range, location, service, check, charge, image | -| BMW Plug-In-Hybrid Electric Vehicle | phev | status, range, location, service, check, charge, image | -| BMW Conventional Vehicle | conv | status, range, location, service, check, image | +| BMW Electric Vehicle | `bev` | status, range, location, service, check, charge, image | +| BMW Electric Vehicle with REX | `bev_rex` | status, range, location, service, check, charge, image | +| BMW Plug-In-Hybrid Electric Vehicle | `phev` | status, range, location, service, check, charge, image | +| BMW Conventional Vehicle | `conv` | status, range, location, service, check, image | #### Properties diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/config/bridge-config.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/config/bridge-config.xml new file mode 100644 index 0000000000000..66abc977fe925 --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/config/bridge-config.xml @@ -0,0 +1,28 @@ + + + + + + + BMW Connected Drive Username + + + + BMW Connected Drive Password + password + + + + Select Region in order to connect to the appropriate BMW Server + + + + + + ROW + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/config/thing-config.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/config/thing-config.xml new file mode 100644 index 0000000000000..051be06625a0c --- /dev/null +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/config/thing-config.xml @@ -0,0 +1,45 @@ + + + + + + + Unique VIN given by BMW + + + + Data Refresh Rate for your Vehicle data + 5 + + + + Units are selected via auto-detection but you can overrule + + + + + + AUTODETECT + + + + Vehicle Image size for width and length + 1024 + + + + Viewport for Vehicle Image + + + + + + + + FRONT + + + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/bridge-connected-drive.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/bridge-connected-drive.xml index 956431e8a0688..0d67101868051 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/bridge-connected-drive.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/bridge-connected-drive.xml @@ -4,31 +4,9 @@ xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0" xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - Access to BMW ConnectedDrive Portal for a specific user - - - - - BMW Connected Drive Username - - - password - - BMW Connected Drive Password - - - - Select Region in order to connect to the appropriate BMW Server - - - - - - ROW - - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml index 20d7e32d4ade2..7ba95f2516397 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml @@ -29,43 +29,6 @@ vin - - - - Unique VIN given by BMW - - - - Data Refresh Rate for your Vehicle data - 5 - - - - Units are selected via auto-detection but you can overrule - - - - - - AUTODETECT - - - - Vehicle Image size for width and length - 1024 - - - - Viewport for Vehicle Image - - - - - - - - FRONT - - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml index 0a09485fce080..00396b53479df 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml @@ -29,43 +29,6 @@ vin - - - - Unique VIN given by BMW - - - - Data Refresh Rate for your Vehicle data - 5 - - - - Units are selected via auto-detection but you can overrule - - - - - - AUTODETECT - - - - Vehicle Image size for width and length - 1024 - - - - Viewport for Vehicle Image - - - - - - - - FRONT - - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml index 13bc34c8f3f66..730cf57c8e2b3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml @@ -26,43 +26,6 @@ vin - - - - Unique VIN given by BMW - - - - Data Refresh Rate for your Vehicle data - 5 - - - - Units are selected via auto-detection but you can overrule - - - - - - AUTODETECT - - - - Vehicle Image size for width and length - 1024 - - - - Viewport for Vehicle Image - - - - - - - - FRONT - - + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml index 69704924ad8c9..21cebda1c3dc6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml @@ -29,43 +29,6 @@ vin - - - - Unique VIN given by BMW - - - - Data Refresh Rate for your Vehicle data - 5 - - - - Units are selected via auto-detection but you can overrule - - - - - - AUTODETECT - - - - Vehicle Image size for width and length - 1024 - - - - Viewport for Vehicle Image - - - - - - - - FRONT - - + From 275dc932fbda0e22f8225bab466f2515edc1e3be Mon Sep 17 00:00:00 2001 From: Bernd Weymann Date: Mon, 29 Mar 2021 02:00:29 +0200 Subject: [PATCH 164/176] shorten labels for things and channels Signed-off-by: Bernd Weymann --- .../README.md | 58 +++---- .../i18n/bmwconnecteddrive_de.properties | 10 +- .../OH-INF/thing/charge-channel-types.xml | 142 ++++++++++++------ .../main/resources/OH-INF/thing/thing-bev.xml | 2 +- .../resources/OH-INF/thing/thing-bev_rex.xml | 2 +- .../resources/OH-INF/thing/thing-conv.xml | 2 +- .../resources/OH-INF/thing/thing-phev.xml | 2 +- 7 files changed, 134 insertions(+), 84 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index f081e31857314..d39e5b85bd027 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -275,34 +275,36 @@ Charging options with date and time for preferred time windows and charging mode * Channel Group ID is **charge** * Available for electric and hybrid vehicles * Read/Write access for UI. Use [Charge Profile Actions](#charge-profile-action) in rules -* There are 3 timers available. Replace *X* with number 1,2 or 3 to target the correct timer - -| Channel Label | Channel Group ID | Channel ID | Type | -|---------------------------------------|------------------|---------------------------|----------| -| Charging Mode for Profile | charge | profile-mode | String | -| Charging Preferences for Profile | charge | profile-prefs | String | -| Charging Window Start Time | charge | window-start | DateTime | -| Charging Window Start Time Hour | charge | window-start-hour | Number | -| Charging Window Start Time Minute | charge | window-start-minute | Number | -| Charging Window End Time | charge | window-end | DateTime | -| Charging Window End Time Hour | charge | window-end-hour | Number | -| Charging Window End Time Minute | charge | window-end-minute | Number | -| Air Conditioning at Departure Time | charge | profile-climate | Switch | -| Timer *X*: Enabled | charge | timer*X*-enabled | Switch | -| Timer *X*: Departure Time | charge | timer*X*-departure | DateTime | -| Timer *X*: Departure Time Hour | charge | timer*X*-departure-hour | Number | -| Timer *X*: Departure Time Minute | charge | timer*X*-departure-minute | Number | -| Timer *X*: Monday | charge | timer*X*-day-mon | Switch | -| Timer *X*: Tuesday | charge | timer*X*-day-tue | Switch | -| Timer *X*: Wednesday | charge | timer*X*-day-wed | Switch | -| Timer *X*: Thursday | charge | timer*X*-day-thu | Switch | -| Timer *X*: Friday | charge | timer*X*-day-fri | Switch | -| Timer *X*: Saturday | charge | timer*X*-day-sat | Switch | -| Timer *X*: Sunday | charge | timer*X*-day-sun | Switch | -| Override Timer: Enabled | charge | override-enabled | Switch | -| Override Timer: Departure Time | charge | override-departure | DateTime | -| Override Timer: Departure Time Hour | charge | override-departure-hour | Number | -| Override Timer: Departure Time Minute | charge | override-departure-minute | Number | +* There are 3 timers *T1, T2 and T3* available. Replace *X* with number 1,2 or 3 to target the correct timer +* Additional override Timer *OT* defines a single departure besides the 3 predefined schedule timers + +| Channel Label | Channel Group ID | Channel ID | Type | +|----------------------------|------------------|---------------------------|----------| +| Charge Mode | charge | profile-mode | String | +| Charge Preferences | charge | profile-prefs | String | +| Window Start Time | charge | window-start | DateTime | +| Window Start Time Hour | charge | window-start-hour | Number | +| Window Start Time Minute | charge | window-start-minute | Number | +| Window End Time | charge | window-end | DateTime | +| Window End Time Hour | charge | window-end-hour | Number | +| Window End Time Minute | charge | window-end-minute | Number | +| A/C at Departure | charge | profile-climate | Switch | +| T*X* Enabled | charge | timer*X*-enabled | Switch | +| T*X* Departure Time | charge | timer*X*-departure | DateTime | +| T*X* Departure Time Hour | charge | timer*X*-departure-hour | Number | +| T*X* Departure Time Minute | charge | timer*X*-departure-minute | Number | +| T*X* Days | charge | timer*X*-days | String | +| T*X* Monday | charge | timer*X*-day-mon | Switch | +| T*X* Tuesday | charge | timer*X*-day-tue | Switch | +| T*X* Wednesday | charge | timer*X*-day-wed | Switch | +| T*X* Thursday | charge | timer*X*-day-thu | Switch | +| T*X* Friday | charge | timer*X*-day-fri | Switch | +| T*X* Saturday | charge | timer*X*-day-sat | Switch | +| T*X* Sunday | charge | timer*X*-day-sun | Switch | +| OT Enabled | charge | override-enabled | Switch | +| OT Departure Time | charge | override-departure | DateTime | +| OT Departure Time Hour | charge | override-departure-hour | Number | +| OT Departure Time Minute | charge | override-departure-minute | Number | The channel _profile-mode_ supports diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties index f7796b26ce2e8..29a7389df2acf 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties @@ -13,8 +13,8 @@ thing-type.config.bmwconnecteddrive.account.region.option.CHINA = China thing-type.config.bmwconnecteddrive.account.region.option.ROW = Rest der Welt # thing types -thing-type.bmwconnecteddrive.bev_rex.label = BMW Elektrofahrzeug mit REX -thing-type.bmwconnecteddrive.bev_rex.description = BMW Elektrofahrzeug mit Range Extender (bev_rex) +thing-type.bmwconnecteddrive.bev_rex.label = Elektrofahrzeug mit REX +thing-type.bmwconnecteddrive.bev_rex.description = Elektrofahrzeug mit Range Extender (bev_rex) thing-type.config.bmwconnecteddrive.bev_rex.vin.label = Fahrzeug Identifikationsnummer (VIN) thing-type.config.bmwconnecteddrive.bev_rex.vin.description = VIN des Fahrzeugs thing-type.config.bmwconnecteddrive.bev_rex.refreshInterval.label = Datenaktualisierung in Minuten @@ -34,7 +34,7 @@ thing-type.config.bmwconnecteddrive.bev_rex.imageViewport.option.SIDE = Seitenan thing-type.config.bmwconnecteddrive.bev_rex.imageViewport.option.DASHBOARD = Innenansicht Armaturen thing-type.config.bmwconnecteddrive.bev_rex.imageViewport.option.DRIVERDOOR = Seitenansicht Fahrertür -thing-type.bmwconnecteddrive.bev.label = BMW Elektrofahrzeug +thing-type.bmwconnecteddrive.bev.label = Elektrofahrzeug thing-type.bmwconnecteddrive.bev.description = Batterieelektrisches Fahrzeug (bev) thing-type.config.bmwconnecteddrive.bev.vin.label = Fahrzeug Identifikationsnummer (VIN) thing-type.config.bmwconnecteddrive.bev.vin.description = VIN des Fahrzeugs @@ -55,7 +55,7 @@ thing-type.config.bmwconnecteddrive.bev.imageViewport.option.SIDE = Seitenansich thing-type.config.bmwconnecteddrive.bev.imageViewport.option.DASHBOARD = Innenansicht Armaturen thing-type.config.bmwconnecteddrive.bev.imageViewport.option.DRIVERDOOR = Seitenansicht Fahrertür -thing-type.bmwconnecteddrive.phev.label = BMW Plug-in-Hybrid Elektrofahrzeug +thing-type.bmwconnecteddrive.phev.label = Plug-in-Hybrid Elektrofahrzeug thing-type.bmwconnecteddrive.phev.description = Konventionelles Fahrzeug mit Elektromotor (phev) thing-type.config.bmwconnecteddrive.phev.vin.label = Fahrzeug Identifikationsnummer (VIN) thing-type.config.bmwconnecteddrive.phev.vin.description = VIN des Fahrzeugs @@ -76,7 +76,7 @@ thing-type.config.bmwconnecteddrive.phev.imageViewport.option.SIDE = Seitenansic thing-type.config.bmwconnecteddrive.phev.imageViewport.option.DASHBOARD = Innenansicht Armaturen thing-type.config.bmwconnecteddrive.phev.imageViewport.option.DRIVERDOOR = Seitenansicht Fahrertür -thing-type.bmwconnecteddrive.conv.label = BMW Konventionelles Fahrzeug +thing-type.bmwconnecteddrive.conv.label = Konventionelles Fahrzeug thing-type.bmwconnecteddrive.conv.description = Konventionelles Benzin/Diesel Fahrzeug (conv) thing-type.config.bmwconnecteddrive.conv.vin.label = Fahrzeug Identifikationsnummer (VIN) thing-type.config.bmwconnecteddrive.conv.vin.description = VIN des Fahrzeugs diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml index fbe966aa021dc..0123768ccdd77 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml @@ -10,6 +10,7 @@ String + Mode for selecting immediate or delyed charging @@ -19,7 +20,8 @@ String - + + Preferences for delayed charging @@ -29,198 +31,244 @@ DateTime - + + Start time of charging window Number - + + Starting hour of charging window Number - + + Starting minute of charging window DateTime - + + End time of charging window Number - + + Ending hour of charging window Number - + + Ending minute of charging window DateTime - + + Departure time for regular schedule timer 1 Number - + + Departure hour for regular schedule timer 1 Number - + + Departure minute for regular schedule timer 1 String - + + Days scheduled for timer 1 Switch - + + Monday scheduled for timer 1 Switch - + + Tuesday scheduled for timer 1 Switch - + + Wednesday scheduled for timer 1 Switch - + + Thursday scheduled for timer 1 Switch - + + Friday scheduled for timer 1 Switch - + + Saturday scheduled for timer 1 Switch - + + Sunday scheduled for timer 1 Switch - + + Timer 1 enabled DateTime - + + Departure time for regular schedule timer 2 Number - + + Departure hour for regular schedule timer 2 Number - + + Departure minute for regular schedule timer 2 String - + + Days scheduled for timer 2 Switch - + + Monday scheduled for timer 2 Switch - + + Tuesday scheduled for timer 2 Switch - + + Wednesday scheduled for timer 2 Switch - + + Thursday scheduled for timer 2 Switch - + + Friday scheduled for timer 2 Switch - + + Saturday scheduled for timer 2 Switch - + + Sunday scheduled for timer 2 Switch - + + Timer 2 enabled DateTime - + + Departure time for regular schedule timer 3 Number - + + Departure hour for regular schedule timer 3 Number - + + Departure minute for regular schedule timer 3 String - + + Days scheduled for timer 3 Switch - + + Monday scheduled for timer 3 Switch - + + Tuesday scheduled for timer 3 Switch - + + Wednesday scheduled for timer 3 Switch - + + Thursday scheduled for timer 3 Switch - + + Friday scheduled for timer 3 Switch - + + Saturday scheduled for timer 3 Switch - + + Sunday scheduled for timer 3 Switch - + + Timer 3 enabled DateTime - + + Departure time for override timer Number - + + Departure hour for override timer Number - + + Departure minute for override timer Switch - + + Override timer enabled diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml index 7ba95f2516397..c9b6f83cb984e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev.xml @@ -9,7 +9,7 @@ - + Battery Electric Vehicle (BEV) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml index 00396b53479df..a685d37f9aca0 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-bev_rex.xml @@ -9,7 +9,7 @@ - + Battery Electric Vehicle with Range Extender (BEV_REX) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml index 730cf57c8e2b3..a0056b2d8389c 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-conv.xml @@ -9,7 +9,7 @@ - + Conventional Fuel Vehicle (CONV) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml index 21cebda1c3dc6..33ceb7f7cc9e3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/thing-phev.xml @@ -9,7 +9,7 @@ - + Conventional Fuel Vehicle with supporting Electric Engine (PHEV) From 03f4787e5360aaa452c7edf81800a5521341fe02 Mon Sep 17 00:00:00 2001 From: Bernd Weymann Date: Mon, 29 Mar 2021 03:05:48 +0200 Subject: [PATCH 165/176] add state tags to channels Signed-off-by: Bernd Weymann --- .../i18n/bmwconnecteddrive_de.properties | 12 +- .../OH-INF/thing/charge-channel-types.xml | 116 +++++++++--------- .../thing/check-control-channel-types.xml | 1 + .../thing/door-status-channel-types.xml | 12 ++ .../OH-INF/thing/image-channel-types.xml | 1 + .../OH-INF/thing/last-trip-channel-types.xml | 7 ++ .../OH-INF/thing/lifetime-channel-types.xml | 5 + .../OH-INF/thing/location-channel-types.xml | 1 + .../OH-INF/thing/range-channel-types.xml | 9 ++ .../thing/remote-services-channel-types.xml | 1 + .../OH-INF/thing/service-channel-types.xml | 2 + .../thing/vehicle-status-channel-types.xml | 9 ++ 12 files changed, 115 insertions(+), 61 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties index 29a7389df2acf..2d05ad417f61f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties @@ -184,12 +184,12 @@ channel-type.bmwconnecteddrive.profile-mode-channel.option.DELAYED_CHARGING = La channel-type.bmwconnecteddrive.profile-prefs-channel.label = Ladeprofil Präferenz channel-type.bmwconnecteddrive.profile-prefs-channel.option.NO_PRESELECTION = Keine Präferenz channel-type.bmwconnecteddrive.profile-prefs-channel.option.Charging Window = Zeitfenster -channel-type.bmwconnecteddrive.window-start-channel.label = Startzeit Ladefenster -channel-type.bmwconnecteddrive.window-start-hour-channel.label = Startzeit Ladefenster Stunde -channel-type.bmwconnecteddrive.window-start-minute-channel.label = Startzeit Ladefenster Minute -channel-type.bmwconnecteddrive.window-end-channel.label = Endzeit Ladefenster -channel-type.bmwconnecteddrive.window-end-hour-channel.label = Endzeit Ladefenster Stunde -channel-type.bmwconnecteddrive.window-end-minute-channel.label = Endzeit Ladefenster Minute +channel-type.bmwconnecteddrive.window-start-channel.label = Ladefenster Startzeit +channel-type.bmwconnecteddrive.window-start-hour-channel.label = Ladefenster Startzeit Stunde +channel-type.bmwconnecteddrive.window-start-minute-channel.label = Ladefenster Startzeit Minute +channel-type.bmwconnecteddrive.window-end-channel.label = Ladefenster Endzeit +channel-type.bmwconnecteddrive.window-end-hour-channel.label = Ladefenster Endzeit Stunde +channel-type.bmwconnecteddrive.window-end-minute-channel.label = Ladefenster Endzeit Minute channel-type.bmwconnecteddrive.timer1-enabled-channel.label = Zeitprofil 1 - Aktiviert channel-type.bmwconnecteddrive.timer1-departure-channel.label = Zeitprofil 1 - Abfahrtszeit channel-type.bmwconnecteddrive.timer1-departure-hour-channel.label = Zeitprofil 1 - Abfahrtszeit Stunde diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml index 0123768ccdd77..531c782227c42 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml @@ -10,7 +10,7 @@ String - Mode for selecting immediate or delyed charging + Mode for selecting immediate or delyed charging @@ -21,7 +21,7 @@ String - Preferences for delayed charging + Preferences for delayed charging @@ -32,243 +32,249 @@ DateTime - Start time of charging window + Start time of charging window + Number - Starting hour of charging window - + Starting hour of charging window + Number - Starting minute of charging window - + Starting minute of charging window + DateTime - End time of charging window + End time of charging window + Number - Ending hour of charging window + Ending hour of charging window Number - Ending minute of charging window + Ending minute of charging window DateTime - Departure time for regular schedule timer 1 + Departure time for regular schedule timer 1 + Number - Departure hour for regular schedule timer 1 + Departure hour for regular schedule timer 1 Number - Departure minute for regular schedule timer 1 + Departure minute for regular schedule timer 1 String - - Days scheduled for timer 1 + + Days scheduled for timer 1 Switch - Monday scheduled for timer 1 + Monday scheduled for timer 1 Switch - Tuesday scheduled for timer 1 + Tuesday scheduled for timer 1 Switch - Wednesday scheduled for timer 1 + Wednesday scheduled for timer 1 Switch - Thursday scheduled for timer 1 + Thursday scheduled for timer 1 Switch - Friday scheduled for timer 1 + Friday scheduled for timer 1 Switch - Saturday scheduled for timer 1 + Saturday scheduled for timer 1 Switch - Sunday scheduled for timer 1 + Sunday scheduled for timer 1 Switch - Timer 1 enabled + Timer 1 enabled DateTime - Departure time for regular schedule timer 2 + Departure time for regular schedule timer 2 + Number - Departure hour for regular schedule timer 2 + Departure hour for regular schedule timer 2 Number - Departure minute for regular schedule timer 2 + Departure minute for regular schedule timer 2 String - Days scheduled for timer 2 + Days scheduled for timer 2 Switch - Monday scheduled for timer 2 + Monday scheduled for timer 2 Switch - Tuesday scheduled for timer 2 + Tuesday scheduled for timer 2 Switch - Wednesday scheduled for timer 2 + Wednesday scheduled for timer 2 Switch - Thursday scheduled for timer 2 + Thursday scheduled for timer 2 Switch - Friday scheduled for timer 2 + Friday scheduled for timer 2 Switch - Saturday scheduled for timer 2 + Saturday scheduled for timer 2 Switch - Sunday scheduled for timer 2 + Sunday scheduled for timer 2 Switch - Timer 2 enabled + Timer 2 enabled DateTime - Departure time for regular schedule timer 3 + Departure time for regular schedule timer 3 + Number - Departure hour for regular schedule timer 3 - + Departure hour for regular schedule timer 3 + Number - Departure minute for regular schedule timer 3 - + Departure minute for regular schedule timer 3 + String - Days scheduled for timer 3 + Days scheduled for timer 3 Switch - Monday scheduled for timer 3 + Monday scheduled for timer 3 Switch - Tuesday scheduled for timer 3 + Tuesday scheduled for timer 3 Switch - Wednesday scheduled for timer 3 + Wednesday scheduled for timer 3 Switch - Thursday scheduled for timer 3 + Thursday scheduled for timer 3 Switch - Friday scheduled for timer 3 + Friday scheduled for timer 3 Switch - Saturday scheduled for timer 3 + Saturday scheduled for timer 3 Switch - Sunday scheduled for timer 3 + Sunday scheduled for timer 3 Switch - Timer 3 enabled + Timer 3 enabled DateTime - Departure time for override timer + Departure time for override timer + Number - Departure hour for override timer - + Departure hour for override timer + Number - Departure minute for override timer - + Departure minute for override timer + Switch - Override timer enabled + Override timer enabled diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-channel-types.xml index 9d4de838b7d0b..d1e95971798fe 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/check-control-channel-types.xml @@ -14,5 +14,6 @@ Number:Length + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/door-status-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/door-status-channel-types.xml index dacd93e016901..89aa6df5a2343 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/door-status-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/door-status-channel-types.xml @@ -6,49 +6,61 @@ String + String + String + String + String + String + String + String + String + String + String + String + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/image-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/image-channel-types.xml index a472e0c651503..78842c1e71bec 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/image-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/image-channel-types.xml @@ -6,6 +6,7 @@ Image + String diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/last-trip-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/last-trip-channel-types.xml index df9fa0434a108..332e19afab8eb 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/last-trip-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/last-trip-channel-types.xml @@ -6,33 +6,40 @@ DateTime + Number:Time + Number:Length + Number:Length Total distance driven since last charging + Number:Energy Average electric power consumption per 100 km/mi + Number:Volume Average combined consumption in liter per 100 km/mi + Number:Energy Average electric recuperation per 100 km/mi + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/lifetime-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/lifetime-channel-types.xml index 4b1d42df36e7c..e4b1567d26ef3 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/lifetime-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/lifetime-channel-types.xml @@ -6,24 +6,29 @@ Number:Length + Number:Length + Number:Energy Average Combined Consumption electric power consumption per 100 km/mi + Number:Energy Average electric recuperation per 100 km/mi + Number:Volume Average combined consumption in liter per 100 km/mi + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/location-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/location-channel-types.xml index e49d26256ba40..e275a1bf7e744 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/location-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/location-channel-types.xml @@ -10,5 +10,6 @@ Number:Angle + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/range-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/range-channel-types.xml index d0e286ed696ae..b289d9bdeca85 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/range-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/range-channel-types.xml @@ -6,37 +6,46 @@ Number:Length + Number:Length + Number:Length + Number:Length + Number:Dimensionless + Number:Volume + Number:Length + Number:Length + Number:Length + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-types.xml index 0bbc38ce79a75..aa9b2df8a6293 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/remote-services-channel-types.xml @@ -10,5 +10,6 @@ String + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-channel-types.xml index ad54e90480ead..3f558b1077f73 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/service-channel-types.xml @@ -14,9 +14,11 @@ DateTime + Number:Length + diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/vehicle-status-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/vehicle-status-channel-types.xml index b91784af20cf1..1fa005aff175e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/vehicle-status-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/vehicle-status-channel-types.xml @@ -6,37 +6,46 @@ String + String + String + DateTime + Number:Length + String + String + Number:Time + DateTime + From 59865cf56f626eaabf6bdbb10d3a9190fa43435a Mon Sep 17 00:00:00 2001 From: Bernd Weymann Date: Sat, 3 Apr 2021 12:38:32 +0200 Subject: [PATCH 166/176] writable datetime channels for charge profile Signed-off-by: Bernd Weymann --- .../internal/handler/VehicleHandler.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 7db63980b93a1..025521cc73da5 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -25,6 +25,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants; import org.openhab.binding.bmwconnecteddrive.internal.VehicleConfiguration; import org.openhab.binding.bmwconnecteddrive.internal.action.ChargeProfileActions; import org.openhab.binding.bmwconnecteddrive.internal.dto.DestinationContainer; @@ -48,6 +49,7 @@ import org.openhab.binding.bmwconnecteddrive.internal.utils.ImageProperties; import org.openhab.binding.bmwconnecteddrive.internal.utils.RemoteServiceUtils; import org.openhab.core.io.net.http.HttpUtil; +import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.RawType; @@ -722,6 +724,21 @@ private void handleChargeProfileCommand(ChannelUID channelUID, Command command) processed = true; } } + } else if (command instanceof DateTimeType) { + DateTimeType dtt = (DateTimeType) command; + logger.debug("Accept {} for ID {}", dtt.toFullString(), id); + final ChargeKeyHour keyHour = ChargeProfileUtils.getKeyHour(id + ConnectedDriveConstants.CHARGE_HOUR); + if (keyHour != null) { + profile.setHour(keyHour.key, dtt.getZonedDateTime().getHour()); + updateTimedState(profile, keyHour.key); + } + final ChargeKeyHour keyMinute = ChargeProfileUtils + .getKeyHour(id + ConnectedDriveConstants.CHARGE_MINUTE); + if (keyMinute != null) { + profile.setMinute(keyMinute.key, dtt.getZonedDateTime().getMinute()); + updateTimedState(profile, keyMinute.key); + } + processed = true; } else if (command instanceof DecimalType) { final ChargeKeyHour keyHour = ChargeProfileUtils.getKeyHour(id); if (keyHour != null) { From 64813ea3c24871b12f0b7fcca8cf8be80b89e88b Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sat, 3 Apr 2021 14:40:58 +0200 Subject: [PATCH 167/176] editable DateTimeType-channels, removal of minute and hour-channels Signed-off-by: Norbert Truchsess --- .../internal/ConnectedDriveConstants.java | 4 -- .../handler/VehicleChannelHandler.java | 5 -- .../internal/handler/VehicleHandler.java | 27 ++----- .../internal/utils/ChargeProfileUtils.java | 17 +---- .../internal/utils/ChargeProfileWrapper.java | 16 ----- .../OH-INF/thing/charge-channel-groups.xml | 12 ---- .../OH-INF/thing/charge-channel-types.xml | 72 ------------------- .../internal/handler/ChargeProfileTest.java | 2 +- 8 files changed, 8 insertions(+), 147 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java index 4b9ec1267a037..31e22c4a09337 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/ConnectedDriveConstants.java @@ -143,15 +143,11 @@ public enum ChargingPreference { public static final String CHARGE_PROFILE_MODE = "profile-mode"; public static final String CHARGE_PROFILE_PREFERENCE = "profile-prefs"; public static final String CHARGE_WINDOW_START = "window-start"; - public static final String CHARGE_WINDOW_START_HOUR = "window-start-hour"; - public static final String CHARGE_WINDOW_START_MINUTE = "window-start-minute"; public static final String CHARGE_WINDOW_END = "window-end"; public static final String CHARGE_TIMER1 = "timer1"; public static final String CHARGE_TIMER2 = "timer2"; public static final String CHARGE_TIMER3 = "timer3"; public static final String CHARGE_OVERRIDE = "override"; - public static final String CHARGE_HOUR = "-hour"; - public static final String CHARGE_MINUTE = "-minute"; public static final String CHARGE_DEPARTURE = "-departure"; public static final String CHARGE_ENABLED = "-enabled"; public static final String CHARGE_DAYS = "-days"; diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java index 393a1daebd959..6ff369b1714b7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleChannelHandler.java @@ -46,7 +46,6 @@ import org.openhab.binding.bmwconnecteddrive.internal.utils.RemoteServiceUtils; import org.openhab.binding.bmwconnecteddrive.internal.utils.VehicleStatusUtils; import org.openhab.core.library.types.DateTimeType; -import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.PointType; import org.openhab.core.library.types.QuantityType; @@ -352,10 +351,6 @@ protected void updateTimedState(ChargeProfileWrapper profile, ProfileKey key) { final LocalTime time = profile.getTime(key); updateChannel(CHANNEL_GROUP_CHARGE, timed.time, time == null ? UnDefType.UNDEF : new DateTimeType(ZonedDateTime.of(Constants.EPOCH_DAY, time, ZoneId.systemDefault()))); - updateChannel(CHANNEL_GROUP_CHARGE, timed.time + CHARGE_HOUR, - time == null ? UnDefType.UNDEF : new DecimalType(time.getHour())); - updateChannel(CHANNEL_GROUP_CHARGE, timed.time + CHARGE_MINUTE, - time == null ? UnDefType.UNDEF : new DecimalType(time.getMinute())); if (timed.timer != null) { final Boolean enabled = profile.isEnabled(key); updateChannel(CHANNEL_GROUP_CHARGE, timed.timer + CHARGE_ENABLED, diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 025521cc73da5..f7c1616fdc653 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -25,7 +25,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.openhab.binding.bmwconnecteddrive.internal.ConnectedDriveConstants; import org.openhab.binding.bmwconnecteddrive.internal.VehicleConfiguration; import org.openhab.binding.bmwconnecteddrive.internal.action.ChargeProfileActions; import org.openhab.binding.bmwconnecteddrive.internal.dto.DestinationContainer; @@ -41,7 +40,6 @@ import org.openhab.binding.bmwconnecteddrive.internal.handler.RemoteServiceHandler.RemoteService; import org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileUtils; import org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileUtils.ChargeKeyDay; -import org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileUtils.ChargeKeyHour; import org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileWrapper; import org.openhab.binding.bmwconnecteddrive.internal.utils.ChargeProfileWrapper.ProfileKey; import org.openhab.binding.bmwconnecteddrive.internal.utils.Constants; @@ -727,27 +725,10 @@ private void handleChargeProfileCommand(ChannelUID channelUID, Command command) } else if (command instanceof DateTimeType) { DateTimeType dtt = (DateTimeType) command; logger.debug("Accept {} for ID {}", dtt.toFullString(), id); - final ChargeKeyHour keyHour = ChargeProfileUtils.getKeyHour(id + ConnectedDriveConstants.CHARGE_HOUR); - if (keyHour != null) { - profile.setHour(keyHour.key, dtt.getZonedDateTime().getHour()); - updateTimedState(profile, keyHour.key); - } - final ChargeKeyHour keyMinute = ChargeProfileUtils - .getKeyHour(id + ConnectedDriveConstants.CHARGE_MINUTE); - if (keyMinute != null) { - profile.setMinute(keyMinute.key, dtt.getZonedDateTime().getMinute()); - updateTimedState(profile, keyMinute.key); - } - processed = true; - } else if (command instanceof DecimalType) { - final ChargeKeyHour keyHour = ChargeProfileUtils.getKeyHour(id); - if (keyHour != null) { - if (keyHour.isHour) { - profile.setHour(keyHour.key, ((DecimalType) command).intValue()); - } else { - profile.setMinute(keyHour.key, ((DecimalType) command).intValue()); - } - updateTimedState(profile, keyHour.key); + final ProfileKey key = ChargeProfileUtils.getTimeKey(id); + if (key != null) { + profile.setTime(key, dtt.getZonedDateTime().toLocalTime()); + updateTimedState(profile, key); processed = true; } } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java index 4a8e865c3f5e3..67da7ae94e14e 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileUtils.java @@ -70,16 +70,6 @@ public static class TimedChannel { } }; - public static class ChargeKeyHour { - public final ProfileKey key; - public final boolean isHour; - - ChargeKeyHour(final ProfileKey key, final boolean isHour) { - this.key = key; - this.isHour = isHour; - } - } - public static class ChargeKeyDay { public final ProfileKey key; public final DayOfWeek day; @@ -101,11 +91,10 @@ public static class ChargeKeyDay { }; @SuppressWarnings("serial") - private static final Map CHARGE_TIME_CHANNEL_KEYS = new HashMap<>() { + private static final Map CHARGE_TIME_CHANNEL_KEYS = new HashMap<>() { { TIMED_CHANNELS.forEach((key, channel) -> { - put(channel.time + CHARGE_HOUR, new ChargeKeyHour(key, true)); - put(channel.time + CHARGE_MINUTE, new ChargeKeyHour(key, false)); + put(channel.time, key); }); } }; @@ -137,7 +126,7 @@ public static class ChargeKeyDay { return CHARGE_DAYS_CHANNEL_KEYS.get(id); } - public static @Nullable ChargeKeyHour getKeyHour(final String id) { + public static @Nullable ProfileKey getTimeKey(final String id) { return CHARGE_TIME_CHANNEL_KEYS.get(id); } diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java index adec905cec6bb..83a72765806ee 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/utils/ChargeProfileWrapper.java @@ -208,22 +208,6 @@ public void setTime(final ProfileKey key, @Nullable LocalTime time) { } } - public void setHour(final ProfileKey key, final int hour) { - LocalTime dateTime = times.get(key); - if (dateTime == null) { - dateTime = NULL_LOCAL_TIME; - } - times.put(key, dateTime.withHour(hour)); - } - - public void setMinute(final ProfileKey key, int minute) { - LocalTime dateTime = times.get(key); - if (dateTime == null) { - dateTime = NULL_LOCAL_TIME; - } - times.put(key, dateTime.withMinute(minute)); - } - public String getJson() { final ChargeProfile profile = new ChargeProfile(); final WeeklyPlanner planner = new WeeklyPlanner(); diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-groups.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-groups.xml index a2db5c14b0cf2..cb3537ace2d14 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-groups.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-groups.xml @@ -11,14 +11,8 @@ - - - - - - @@ -29,8 +23,6 @@ - - @@ -41,8 +33,6 @@ - - @@ -53,8 +43,6 @@ - - diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml index 531c782227c42..5db7580926e81 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/thing/charge-channel-types.xml @@ -35,54 +35,18 @@ Start time of charging window - - Number - - Starting hour of charging window - - - - Number - - Starting minute of charging window - - DateTime End time of charging window - - Number - - Ending hour of charging window - - - - Number - - Ending minute of charging window - - DateTime Departure time for regular schedule timer 1 - - Number - - Departure hour for regular schedule timer 1 - - - - Number - - Departure minute for regular schedule timer 1 - - String @@ -134,18 +98,6 @@ Departure time for regular schedule timer 2 - - Number - - Departure hour for regular schedule timer 2 - - - - Number - - Departure minute for regular schedule timer 2 - - String @@ -197,18 +149,6 @@ Departure time for regular schedule timer 3 - - Number - - Departure hour for regular schedule timer 3 - - - - Number - - Departure minute for regular schedule timer 3 - - String @@ -260,18 +200,6 @@ Departure time for override timer - - Number - - Departure hour for override timer - - - - Number - - Departure minute for override timer - - Switch diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java index e85f1cd051c9f..0f181d5923220 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/test/java/org/openhab/binding/bmwconnecteddrive/internal/handler/ChargeProfileTest.java @@ -43,7 +43,7 @@ public class ChargeProfileTest { private final Logger logger = LoggerFactory.getLogger(VehicleHandler.class); - private static final int PROFILE_CALLBACK_NUMBER = 49; + private static final int PROFILE_CALLBACK_NUMBER = 37; @Nullable ArgumentCaptor channelCaptor; From b53dd5f943811a2b00101c7c441011e24a31e354 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sat, 3 Apr 2021 16:08:12 +0200 Subject: [PATCH 168/176] channel-type-definitions & documentation-update Signed-off-by: Norbert Truchsess --- .../README.md | 32 +++++++------------ .../OH-INF/thing/charge-channel-types.xml | 12 +++---- 2 files changed, 18 insertions(+), 26 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index d39e5b85bd027..72610c455ede6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -283,16 +283,10 @@ Charging options with date and time for preferred time windows and charging mode | Charge Mode | charge | profile-mode | String | | Charge Preferences | charge | profile-prefs | String | | Window Start Time | charge | window-start | DateTime | -| Window Start Time Hour | charge | window-start-hour | Number | -| Window Start Time Minute | charge | window-start-minute | Number | | Window End Time | charge | window-end | DateTime | -| Window End Time Hour | charge | window-end-hour | Number | -| Window End Time Minute | charge | window-end-minute | Number | | A/C at Departure | charge | profile-climate | Switch | | T*X* Enabled | charge | timer*X*-enabled | Switch | | T*X* Departure Time | charge | timer*X*-departure | DateTime | -| T*X* Departure Time Hour | charge | timer*X*-departure-hour | Number | -| T*X* Departure Time Minute | charge | timer*X*-departure-minute | Number | | T*X* Days | charge | timer*X*-days | String | | T*X* Monday | charge | timer*X*-day-mon | Switch | | T*X* Tuesday | charge | timer*X*-day-tue | Switch | @@ -303,8 +297,6 @@ Charging options with date and time for preferred time windows and charging mode | T*X* Sunday | charge | timer*X*-day-sun | Switch | | OT Enabled | charge | override-enabled | Switch | | OT Departure Time | charge | override-departure | DateTime | -| OT Departure Time Hour | charge | override-departure-hour | Number | -| OT Departure Time Minute | charge | override-departure-minute | Number | The channel _profile-mode_ supports @@ -641,14 +633,14 @@ Location i3DestLocation "GPS [%s]" Switch i3ChargeProfileClimate "Charge Profile Climatization" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:charge#profile-climate" } String i3ChargeProfileMode "Charge Profile Mode [%s]" (i3) {channel="bmwconnecteddrive:bev_rex:user:i3:charge#profile-mode" } DateTime i3ChargeWindowStart "Charge Window Start [%1$tH:%1$tM]" DateTime End time of charging window - + DateTime Departure time for regular schedule timer 1 - + String @@ -96,7 +96,7 @@ DateTime Departure time for regular schedule timer 2 - + String @@ -147,7 +147,7 @@ DateTime Departure time for regular schedule timer 3 - + String @@ -198,7 +198,7 @@ DateTime Departure time for override timer - + Switch From c368dc0c012446d0090f25c84784198436ae68de Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sun, 4 Apr 2021 13:17:16 +0200 Subject: [PATCH 169/176] rules for editing datetimes in sitemap Signed-off-by: Norbert Truchsess --- .../README.md | 123 ++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 72610c455ede6..7278cd42790a6 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -820,6 +820,129 @@ sitemap BMW label="BMW" { } ``` +### Rules File +``` +rule "i3ChargeWindowStartSetpoint" +when + Item i3ChargeWindowStartMinute changed or + Item i3ChargeWindowStartHour changed +then + val hour = (i3ChargeWindowStartHour.state as Number).intValue + val minute = (i3ChargeWindowStartMinute.state as Number).intValue + val time = (i3ChargeWindowStart.state as DateTimeType).zonedDateTime + i3ChargeWindowStart.sendCommand(new DateTimeType(time.withHour(hour).withMinute(minute))) +end + +rule "i3ChargeWindowStart" +when + Item i3ChargeWindowStart changed +then + val time = (i3ChargeWindowStart.state as DateTimeType).zonedDateTime + i3ChargeWindowStartMinute.sendCommand(time.minute) + i3ChargeWindowStartHour.sendCommand(time.hour) +end + +rule "i3ChargeWindowEndSetpoint" +when + Item i3ChargeWindowEndMinute changed or + Item i3ChargeWindowEndHour changed +then + val hour = (i3ChargeWindowEndHour.state as Number).intValue + val minute = (i3ChargeWindowEndMinute.state as Number).intValue + val time = (i3ChargeWindowEnd.state as DateTimeType).zonedDateTime + i3ChargeWindowEnd.sendCommand(new DateTimeType(time.withHour(hour).withMinute(minute))) +end + +rule "i3ChargeWindowEnd" +when + Item i3ChargeWindowEnd changed +then + val time = (i3ChargeWindowEnd.state as DateTimeType).zonedDateTime + i3ChargeWindowEndMinute.sendCommand(time.minute) + i3ChargeWindowEndHour.sendCommand(time.hour) +end + +rule "i3Timer1DepartureSetpoint" +when + Item i3Timer1DepartureMinute changed or + Item i3Timer1DepartureHour changed +then + val hour = (i3Timer1DepartureHour.state as Number).intValue + val minute = (i3Timer1DepartureMinute.state as Number).intValue + val time = (i3Timer1Departure.state as DateTimeType).zonedDateTime + i3Timer1Departure.sendCommand(new DateTimeType(time.withHour(hour).withMinute(minute))) +end + +rule "i3Timer1Departure" +when + Item i3Timer1Departure changed +then + val time = (i3Timer1Departure.state as DateTimeType).zonedDateTime + i3Timer1DepartureMinute.sendCommand(time.minute) + i3Timer1DepartureHour.sendCommand(time.hour) +end + +rule "i3Timer2DepartureSetpoint" +when + Item i3Timer2DepartureMinute changed or + Item i3Timer2DepartureHour changed +then + val hour = (i3Timer2DepartureHour.state as Number).intValue + val minute = (i3Timer2DepartureMinute.state as Number).intValue + val time = (i3Timer2Departure.state as DateTimeType).zonedDateTime + i3Timer2Departure.sendCommand(new DateTimeType(time.withHour(hour).withMinute(minute))) +end + +rule "i3Timer2Departure" +when + Item i3Timer2Departure changed +then + val time = (i3Timer2Departure.state as DateTimeType).zonedDateTime + i3Timer2DepartureMinute.sendCommand(time.minute) + i3Timer2DepartureHour.sendCommand(time.hour) +end + +rule "i3Timer3DepartureSetpoint" +when + Item i3Timer3DepartureMinute changed or + Item i3Timer3DepartureHour changed +then + val hour = (i3Timer3DepartureHour.state as Number).intValue + val minute = (i3Timer3DepartureMinute.state as Number).intValue + val time = (i3Timer3Departure.state as DateTimeType).zonedDateTime + i3Timer3Departure.sendCommand(new DateTimeType(time.withHour(hour).withMinute(minute))) +end + +rule "i3Timer3Departure" +when + Item i3Timer3Departure changed +then + val time = (i3Timer3Departure.state as DateTimeType).zonedDateTime + i3Timer3DepartureMinute.sendCommand(time.minute) + i3Timer3DepartureHour.sendCommand(time.hour) +end + +rule "i3OverrideDepartureSetpoint" +when + Item i3OverrideDepartureMinute changed or + Item i3OverrideDepartureHour changed +then + val hour = (i3OverrideDepartureHour.state as Number).intValue + val minute = (i3OverrideDepartureMinute.state as Number).intValue + val time = (i3OverrideDeparture.state as DateTimeType).zonedDateTime + i3OverrideDeparture.sendCommand(new DateTimeType(time.withHour(hour).withMinute(minute))) +end + +rule "i3OverrideDeparture" +when + Item i3OverrideDeparture changed +then + val time = (i3OverrideDeparture.state as DateTimeType).zonedDateTime + i3OverrideDepartureMinute.sendCommand(time.minute) + i3OverrideDepartureHour.sendCommand(time.hour) +end +``` + ### Action example ``` From 420dae39cafb44ef91fcae768214e983047903c8 Mon Sep 17 00:00:00 2001 From: Bernd Weymann Date: Fri, 9 Apr 2021 17:44:05 +0200 Subject: [PATCH 170/176] bugfix: set legacy mode only one time Signed-off-by: Bernd Weymann --- .../internal/handler/VehicleHandler.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index f7c1616fdc653..9e7bdf7f31cf7 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -73,7 +73,7 @@ */ @NonNullByDefault public class VehicleHandler extends VehicleChannelHandler { - private boolean legacyMode = false; // switch to legacy API in case of 404 Errors + private int legacyMode = Constants.INT_UNDEF; // switch to legacy API in case of 404 Errors private Optional proxy = Optional.empty(); private Optional remote = Optional.empty(); @@ -269,10 +269,10 @@ public void dispose() { public void getData() { proxy.ifPresentOrElse(prox -> { configuration.ifPresentOrElse(config -> { - if (!legacyMode) { - prox.requestVehcileStatus(config, vehicleStatusCallback); - } else { + if (legacyMode == 1) { prox.requestLegacyVehcileStatus(config, oldVehicleStatusCallback); + } else { + prox.requestVehcileStatus(config, vehicleStatusCallback); } addCallback(vehicleStatusCallback); if (isSupported(Constants.STATISTICS)) { @@ -611,6 +611,8 @@ public class VehicleStatusCallback implements StringResponseCallback { @Override public void onResponse(@Nullable String content) { if (content != null) { + // switch to non legacy mode + legacyMode = 0; updateStatus(ThingStatus.ONLINE); vehicleStatusCache = Optional.of(content); try { @@ -635,7 +637,8 @@ public void onResponse(@Nullable String content) { @Override public void onError(NetworkError error) { logger.debug("{}", error.toString()); - if (error.status != 200) { + // only if legacyMode isn't set yet try legacy API + if (error.status != 200 && legacyMode == Constants.INT_UNDEF) { logger.debug("VehicleStatus not found - try legacy API"); proxy.get().requestLegacyVehcileStatus(configuration.get(), oldVehicleStatusCallback); } @@ -664,7 +667,7 @@ public void onResponse(@Nullable String content) { VehicleAttributesContainer vac = Converter.getGson().fromJson(content, VehicleAttributesContainer.class); vehicleStatusCallback.onResponse(Converter.transformLegacyStatus(vac)); - legacyMode = true; + legacyMode = 1; logger.debug("VehicleStatus switched to legacy mode"); } catch (JsonSyntaxException jse) { logger.debug("{}", jse.getMessage()); From 1156d891ed24218989a88e90519b827f8480a7be Mon Sep 17 00:00:00 2001 From: Bernd Weymann Date: Fri, 9 Apr 2021 17:44:25 +0200 Subject: [PATCH 171/176] add missing translation Signed-off-by: Bernd Weymann --- .../main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties index 2d05ad417f61f..ab6509c50d7f1 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/i18n/bmwconnecteddrive_de.properties @@ -143,6 +143,7 @@ channel-type.bmwconnecteddrive.next-service-date-channel.label = N channel-type.bmwconnecteddrive.next-service-mileage-channel.label = Nächster Service in Kilometern channel-type.bmwconnecteddrive.check-control-channel.label = Warnung Aktiv channel-type.bmwconnecteddrive.charging-status-channel.label = Ladezustand +channel-type.bmwconnecteddrive.charging-remaining-channel.label = Verbleibende Ladezeit channel-type.bmwconnecteddrive.last-update-channel.label = Letzte Aktualisierung channel-type.bmwconnecteddrive.driver-front-channel.label = Fahrertür From 5876481a43950f941b56d4995dfc699f074f734a Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sun, 11 Apr 2021 14:48:20 +0200 Subject: [PATCH 172/176] rename actions-scope as requested by @kaikreuzer Signed-off-by: Norbert Truchsess --- ...ons.java => BMWConnectedDriveActions.java} | 84 +++++++++---------- .../internal/handler/VehicleHandler.java | 4 +- 2 files changed, 44 insertions(+), 44 deletions(-) rename bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/{ChargeProfileActions.java => BMWConnectedDriveActions.java} (83%) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/BMWConnectedDriveActions.java similarity index 83% rename from bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java rename to bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/BMWConnectedDriveActions.java index e51fcfbdec2d7..10884ddaa804f 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/ChargeProfileActions.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/action/BMWConnectedDriveActions.java @@ -32,13 +32,13 @@ import org.openhab.core.thing.binding.ThingHandler; /** - * The {@link ChargeProfileActions} provides actions for VehicleHandler + * The {@link BMWConnectedDriveActions} provides actions for VehicleHandler * * @author Norbert Truchsess - Initial contribution */ -@ThingActionsScope(name = "chargeprofile") +@ThingActionsScope(name = "bmwconnecteddrive") @NonNullByDefault -public class ChargeProfileActions implements ThingActions { +public class BMWConnectedDriveActions implements ThingActions { private Optional handler = Optional.empty(); @@ -213,150 +213,150 @@ public void setOverrideTimerDays( setDays(OVERRIDE, days); } - @RuleAction(label = "send", description = "sends the charging profile to the vehicle") - public void send() { + @RuleAction(label = "sendChargeProfile", description = "sends the charging profile to the vehicle") + public void sendChargeProfile() { handler.ifPresent(handle -> handle.sendChargeProfile(getProfile())); } @RuleAction(label = "cancel", description = "cancel current edit of charging profile") - public void cancel() { + public void cancelEditChargeProfile() { profile = Optional.empty(); } public static Optional getTimer1Departure(ThingActions actions) { - return ((ChargeProfileActions) actions).getTimer1Departure(); + return ((BMWConnectedDriveActions) actions).getTimer1Departure(); } public static void setTimer1Departure(ThingActions actions, @Nullable LocalTime time) { - ((ChargeProfileActions) actions).setTimer1Departure(time); + ((BMWConnectedDriveActions) actions).setTimer1Departure(time); } public static Optional getTimer1Enabled(ThingActions actions) { - return ((ChargeProfileActions) actions).getTimer1Enabled(); + return ((BMWConnectedDriveActions) actions).getTimer1Enabled(); } public static void setTimer1Enabled(ThingActions actions, @Nullable Boolean enabled) { - ((ChargeProfileActions) actions).setTimer1Enabled(enabled); + ((BMWConnectedDriveActions) actions).setTimer1Enabled(enabled); } public static Optional getTimer2Departure(ThingActions actions) { - return ((ChargeProfileActions) actions).getTimer2Departure(); + return ((BMWConnectedDriveActions) actions).getTimer2Departure(); } public static void setTimer2Departure(ThingActions actions, @Nullable LocalTime time) { - ((ChargeProfileActions) actions).setTimer2Departure(time); + ((BMWConnectedDriveActions) actions).setTimer2Departure(time); } public static Optional getTimer2Enabled(ThingActions actions) { - return ((ChargeProfileActions) actions).getTimer2Enabled(); + return ((BMWConnectedDriveActions) actions).getTimer2Enabled(); } public static void setTimer2Enabled(ThingActions actions, @Nullable Boolean enabled) { - ((ChargeProfileActions) actions).setTimer2Enabled(enabled); + ((BMWConnectedDriveActions) actions).setTimer2Enabled(enabled); } public static Optional getTimer3Departure(ThingActions actions) { - return ((ChargeProfileActions) actions).getTimer3Departure(); + return ((BMWConnectedDriveActions) actions).getTimer3Departure(); } public static void setTimer3Departure(ThingActions actions, @Nullable LocalTime time) { - ((ChargeProfileActions) actions).setTimer3Departure(time); + ((BMWConnectedDriveActions) actions).setTimer3Departure(time); } public static Optional getTimer3Enabled(ThingActions actions) { - return ((ChargeProfileActions) actions).getTimer3Enabled(); + return ((BMWConnectedDriveActions) actions).getTimer3Enabled(); } public static void setTimer3Enabled(ThingActions actions, @Nullable Boolean enabled) { - ((ChargeProfileActions) actions).setTimer3Enabled(enabled); + ((BMWConnectedDriveActions) actions).setTimer3Enabled(enabled); } public static Optional getOverrideTimerDeparture(ThingActions actions) { - return ((ChargeProfileActions) actions).getOverrideTimerDeparture(); + return ((BMWConnectedDriveActions) actions).getOverrideTimerDeparture(); } public static void setOverrideTimerDeparture(ThingActions actions, @Nullable LocalTime time) { - ((ChargeProfileActions) actions).setOverrideTimerDeparture(time); + ((BMWConnectedDriveActions) actions).setOverrideTimerDeparture(time); } public static Optional getOverrideTimerEnabled(ThingActions actions) { - return ((ChargeProfileActions) actions).getOverrideTimerEnabled(); + return ((BMWConnectedDriveActions) actions).getOverrideTimerEnabled(); } public static void setOverrideTimerEnabled(ThingActions actions, @Nullable Boolean enabled) { - ((ChargeProfileActions) actions).setOverrideTimerEnabled(enabled); + ((BMWConnectedDriveActions) actions).setOverrideTimerEnabled(enabled); } public static Optional getPreferredWindowStart(ThingActions actions) { - return ((ChargeProfileActions) actions).getPreferredWindowStart(); + return ((BMWConnectedDriveActions) actions).getPreferredWindowStart(); } public static void setPreferredWindowStart(ThingActions actions, @Nullable LocalTime time) { - ((ChargeProfileActions) actions).setPreferredWindowStart(time); + ((BMWConnectedDriveActions) actions).setPreferredWindowStart(time); } public static Optional getPreferredWindowEnd(ThingActions actions) { - return ((ChargeProfileActions) actions).getPreferredWindowEnd(); + return ((BMWConnectedDriveActions) actions).getPreferredWindowEnd(); } public static void setPreferredWindowEnd(ThingActions actions, @Nullable LocalTime time) { - ((ChargeProfileActions) actions).setPreferredWindowEnd(time); + ((BMWConnectedDriveActions) actions).setPreferredWindowEnd(time); } public static Optional getClimatizationEnabled(ThingActions actions) { - return ((ChargeProfileActions) actions).getClimatizationEnabled(); + return ((BMWConnectedDriveActions) actions).getClimatizationEnabled(); } public static void setClimatizationEnabled(ThingActions actions, @Nullable Boolean enabled) { - ((ChargeProfileActions) actions).setClimatizationEnabled(enabled); + ((BMWConnectedDriveActions) actions).setClimatizationEnabled(enabled); } public static Optional getChargingMode(ThingActions actions) { - return ((ChargeProfileActions) actions).getChargingMode(); + return ((BMWConnectedDriveActions) actions).getChargingMode(); } public static void setChargingMode(ThingActions actions, @Nullable String mode) { - ((ChargeProfileActions) actions).setChargingMode(mode); + ((BMWConnectedDriveActions) actions).setChargingMode(mode); } public static Optional> getTimer1Days(ThingActions actions) { - return ((ChargeProfileActions) actions).getTimer1Days(); + return ((BMWConnectedDriveActions) actions).getTimer1Days(); } public static void setTimer1Days(ThingActions actions, @Nullable Set days) { - ((ChargeProfileActions) actions).setTimer1Days(days); + ((BMWConnectedDriveActions) actions).setTimer1Days(days); } public static Optional> getTimer2Days(ThingActions actions) { - return ((ChargeProfileActions) actions).getTimer2Days(); + return ((BMWConnectedDriveActions) actions).getTimer2Days(); } public static void setTimer2Days(ThingActions actions, @Nullable Set days) { - ((ChargeProfileActions) actions).setTimer2Days(days); + ((BMWConnectedDriveActions) actions).setTimer2Days(days); } public static Optional> getTimer3Days(ThingActions actions) { - return ((ChargeProfileActions) actions).getTimer3Days(); + return ((BMWConnectedDriveActions) actions).getTimer3Days(); } public static void setTimer3Days(ThingActions actions, @Nullable Set days) { - ((ChargeProfileActions) actions).setTimer3Days(days); + ((BMWConnectedDriveActions) actions).setTimer3Days(days); } public static Optional> getOverrideTimerDays(ThingActions actions) { - return ((ChargeProfileActions) actions).getOverrideTimerDays(); + return ((BMWConnectedDriveActions) actions).getOverrideTimerDays(); } public static void setOverrideTimerDays(ThingActions actions, @Nullable Set days) { - ((ChargeProfileActions) actions).setOverrideTimerDays(days); + ((BMWConnectedDriveActions) actions).setOverrideTimerDays(days); } - public static void send(ThingActions actions) { - ((ChargeProfileActions) actions).send(); + public static void sendChargeProfile(ThingActions actions) { + ((BMWConnectedDriveActions) actions).sendChargeProfile(); } - public static void cancel(ThingActions actions) { - ((ChargeProfileActions) actions).cancel(); + public static void cancelEditChargeProfile(ThingActions actions) { + ((BMWConnectedDriveActions) actions).cancelEditChargeProfile(); } @Override diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java index 9e7bdf7f31cf7..035f0c1b6e74b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/java/org/openhab/binding/bmwconnecteddrive/internal/handler/VehicleHandler.java @@ -26,7 +26,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.bmwconnecteddrive.internal.VehicleConfiguration; -import org.openhab.binding.bmwconnecteddrive.internal.action.ChargeProfileActions; +import org.openhab.binding.bmwconnecteddrive.internal.action.BMWConnectedDriveActions; import org.openhab.binding.bmwconnecteddrive.internal.dto.DestinationContainer; import org.openhab.binding.bmwconnecteddrive.internal.dto.NetworkError; import org.openhab.binding.bmwconnecteddrive.internal.dto.compat.VehicleAttributesContainer; @@ -766,7 +766,7 @@ private void saveChargeProfileSent() { @Override public Collection> getServices() { - return Set.of(ChargeProfileActions.class); + return Set.of(BMWConnectedDriveActions.class); } public Optional getChargeProfileWrapper() { From f2a23ec9b3a2b782df8eb5873986cfcaf249f9c0 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Sun, 11 Apr 2021 14:56:23 +0200 Subject: [PATCH 173/176] adjust README to renames of actions Signed-off-by: Norbert Truchsess --- bundles/org.openhab.binding.bmwconnecteddrive/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index 7278cd42790a6..bff78ad9fe787 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -821,6 +821,7 @@ sitemap BMW label="BMW" { ``` ### Rules File + ``` rule "i3ChargeWindowStartSetpoint" when @@ -946,7 +947,7 @@ end ### Action example ``` - val profile = getActions("chargeprofile", "bmwconnecteddrive:bev_rex:user:i3") + val profile = getActions("bmwconnecteddrive", "bmwconnecteddrive:bev_rex:user:i3") val now = ZonedDateTime.now.toLocalTime profile.setChargingMode("DELAYED_CHARGING") profile.setTimer1Departure(now.minusHours(2)) @@ -956,7 +957,7 @@ end profile.setTimer3Enabled(false) profile.setPreferredWindowStart(now.minusHours(6)) profile.setPreferredWindowEnd(now.minusHours(2)) - profile.send() + profile.sendChargeProfile() ``` ## Credits From afd5b16f5c0f474d9d0d10c15af80ab2b1954d8a Mon Sep 17 00:00:00 2001 From: Bernd Weymann Date: Sun, 11 Apr 2021 23:26:49 +0200 Subject: [PATCH 174/176] correct Actions section in readme Signed-off-by: Bernd Weymann --- .../README.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index bff78ad9fe787..fdab7b366cc0d 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -426,12 +426,9 @@ The possible values are the same mentioned in [Thing Configuration](#thing-confi | Image Viewport | view | String | Write | | Image Picture Size | size | Number | Write | -## Rule Actions +## Actions -## Charge Profile Action - -The Charge Profile is accessible and modifiable in rules via action. -Get the corresponding action from your car using the Thing ID +Get the _Actions_ object for your vehicle using the Thing ID * bmwconnecteddrive - Binding ID, don't change! * bev_rex - [Thing UID](#things) of your car @@ -439,9 +436,11 @@ Get the corresponding action from your car using the Thing ID * i3 - Thing ID of your car ``` - val profile = getActions("chargeprofile", "bmwconnecteddrive:bev_rex:user:i3") + val profile = getActions("bmwconnecteddrive", "bmwconnecteddrive:bev_rex:user:i3") ``` +### Charge Profile Editing + Like in the Charge Profile Channels 3 Timers are provided. Replace *X* with 1, 2 or 3 to address the right timer. | Function | Parameters | Returns | Description | @@ -466,8 +465,8 @@ Like in the Charge Profile Channels 3 Timers are provided. Replace *X* with 1, 2 | setOverrideTimerDeparture | LocalTime | void | Sets the override timer departure time | | getOverrideTimerDays | void | Set | Returns the days of week the overrideTimer is enabled for | | setOverrideTimerDays | Set | void | Sets the days of week the overrideTimer is enabled for | -| cancel | void | void | Sends the charging profile to the vehicle | -| send | void | void | Cancel current edit of charging profile | +| cancelEditChargeProfile | void | void | Sends the charging profile to the vehicle | +| sendChargeProfile | void | void | Cancel current edit of charging profile | Values for valid charging mode get/set From db78bab2051fc41a8411035b8bda8f4bd6dcb9a4 Mon Sep 17 00:00:00 2001 From: Norbert Truchsess Date: Mon, 12 Apr 2021 09:33:49 +0200 Subject: [PATCH 175/176] descriptions were swapped Signed-off-by: Norbert Truchsess --- bundles/org.openhab.binding.bmwconnecteddrive/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index fdab7b366cc0d..e1b85ccb6a555 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -465,8 +465,8 @@ Like in the Charge Profile Channels 3 Timers are provided. Replace *X* with 1, 2 | setOverrideTimerDeparture | LocalTime | void | Sets the override timer departure time | | getOverrideTimerDays | void | Set | Returns the days of week the overrideTimer is enabled for | | setOverrideTimerDays | Set | void | Sets the days of week the overrideTimer is enabled for | -| cancelEditChargeProfile | void | void | Sends the charging profile to the vehicle | -| sendChargeProfile | void | void | Cancel current edit of charging profile | +| cancelEditChargeProfile | void | void | Cancel current edit of charging profile | +| sendChargeProfile | void | void | Sends the charging profile to the vehicle | Values for valid charging mode get/set From ac539e837ce75a05cff7b07f152bf240893c0084 Mon Sep 17 00:00:00 2001 From: Bernd Weymann Date: Sat, 1 May 2021 13:07:28 +0200 Subject: [PATCH 176/176] remove logo and author from documentation Signed-off-by: Bernd Weymann --- .../README.md | 4 +--- .../doc/bmw-connected.png | Bin 7392 -> 0 bytes .../main/resources/OH-INF/binding/binding.xml | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) delete mode 100644 bundles/org.openhab.binding.bmwconnecteddrive/doc/bmw-connected.png diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/README.md b/bundles/org.openhab.binding.bmwconnecteddrive/README.md index e1b85ccb6a555..2ed6771af160b 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/README.md +++ b/bundles/org.openhab.binding.bmwconnecteddrive/README.md @@ -1,7 +1,5 @@ # BMW ConnectedDrive Binding - - The binding provides a connection between [BMW's ConnectedDrive Portal](https://www.bmw-connecteddrive.com/country-region-select/country-region-selection.html) and openHAB. All vehicles connected to an account will be detected by the discovery with the correct type @@ -274,7 +272,7 @@ Charging options with date and time for preferred time windows and charging mode * Channel Group ID is **charge** * Available for electric and hybrid vehicles -* Read/Write access for UI. Use [Charge Profile Actions](#charge-profile-action) in rules +* Read/Write access for UI. Use [Charge Profile Editing Action](#charge-profile-editing) in rules * There are 3 timers *T1, T2 and T3* available. Replace *X* with number 1,2 or 3 to target the correct timer * Additional override Timer *OT* defines a single departure besides the 3 predefined schedule timers diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/doc/bmw-connected.png b/bundles/org.openhab.binding.bmwconnecteddrive/doc/bmw-connected.png deleted file mode 100644 index 579be907833faa43b7d7b3595a139c48cdf5a572..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7392 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 NCWhw>Uh9#f{tun#4Z#2a diff --git a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/binding/binding.xml b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/binding/binding.xml index f2395ba6ee8f1..7e2b71d1e2ef1 100644 --- a/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/binding/binding.xml +++ b/bundles/org.openhab.binding.bmwconnecteddrive/src/main/resources/OH-INF/binding/binding.xml @@ -5,6 +5,5 @@ BMW ConnectedDrive Provides access to your Vehicle Data via BMW Connected Drive Portal - Bernd Weymann

rzvwCtgo$;G|Lh$WM^TpG=uc{w-8V$6buU)l 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

Pq9?@ z)%wW;TRW?z79TAc<=JSjwvBz?Q-ZVi`#vh&)i1>jsj6{F$kAdmxv&2SG*g;V)p+r9 zzIF6HN5fCXPG~!=bi_8?39j=rd+68q9VtE;-k+Yj=ezw)F`k3(d3J5GQ#-Dxw>G7S zT2Da;%=^q$NS|g5B$?143#(m=GKcyY!f}EVU9@|;Nr)Gf$R07O#hG_S)rl?R81q~D z7a3a|>#S|Few1D1OMkHy!e%Lm@+So*%y97(2F0&}#xv|u94TWT8IUQupzwH1pE%p~ zASt_BKxvqH4`lPBe!&|wj8@E8N%U4akO<&vs--II^ziW4G^=44 zHUkh)e4y^Aa83K(>d~-}KM_Jql#G6^zp9f}nt4x??!Rn=o0E-SZM6a?2RX5isNl)F zbM*NoNU1s!o*pRE8?`xi4#5p2OBzip=G3rwRop<`+vDj?QZw4s4F=E3)aZsJVLp(`B{owQ*>T8CAj@x1T5Lw5CE57f)c*4} zx0a2b2aSK&71&qL0tRPFD3{mcoo++ur(glhTbynoh@LvVc)X2hjPHF?(xBN6r57B` zmVaOCPe_mQf;JTZVDq^zR9o{b+ERP3`X>);kG*7wAAU6QenI?V>k@N%G07f^Xfs;! zD)aO^@-q|H+$3+PUiGhB7KHYnIICZp&mRMPG9@z32$wHc^0VC#ZT$?}ovz)V>tH-{ zatXYJd7B5g>ifQQE(lDs&(7|1x`+|*(@YAPI>cR3r|H}EEMzp@=LdnMhK866V)=(b z#S#*d?#p(|CpMlIBV34u09LgJg;t3i;RG3`sG(o=vVeTtWY*F4I96OErIaK>i}t zLz0ral=k5FxgPsKutJp7=f_W5MkL@}V&7RxlJcX&37~w*hV*2K%RPEFk{WEBChcm* z>rH`KrCAW`XfzC6+g<&KKCfXv?(}%e<>bg(@S9LU$Z;IL66SP`<3;Aj%T-qe2;}=t zH80Ba2M`9KnIYL@8Z8!Kp`m6@-46^e;rf!g6nvX)a(+5o_30sL+)!21)F(FGDf}UK z*hx{nWwwM^{Ja^MpJP(KEmS*}5gNzT%nzA``%er~%Kd+nof|2vfyu(GH^MqD5#D|U zt)YIMQ^~#n9K&^RHRi@XOfenRAgoL#B>q%9_%yV z;T(b3D(XX|InkkE#P)!!aCm8pLc+DlgT5{(h@4B$zxL5Fg=+_XTF!2Ld+bmrt(8QI z+uK9Nzt+pil*nZGibOMNxVS=HwzS!w*N&B{l%edOxj}sVwxa2DBInX9uFtXuZ2ihxvdOXRmP42Z8qjLbI!O_-#(qWy%igrGq%m4!@^jpAlp$4 z;bTLJb{{trTLLEqLTLcX*fU4GiJN<_D28Gku#Fw%+v(eg*W(vbAS)KUqWy(H7Y-wm z6bOTc6EJ6kiv*xP&=L3e+aVr>R9FU1>q1tOMkVL{+!Xd_iv5XA+~*?Enf%>*fS76f zfI_U}IA534N~JeV40{0#gW(GL)!S)jeLs|+Kifv6?g=tqF>;R&@2PEUnxg>s0a7 z*wl`o?3EzXN~-`ih&6zFS7Fss@_>Vym+R6t6p+J}&nKYB{Cf=OOg zv}xWDx!$UPZg}?7G!JR&WZA_%8Ej?T=ZNSl^T6pzUl@YW4y3TFGDV4fS7R^$|$fCKYF`J!2-v z93DMVrfVx;@m@5U8?A(R=vkllgma+)kt~kKG`W9Z6k>n})7fUz5(vLLpHD9nboMeg5FL$TZrJxfU`X4dNP*?1&6IfUbTtfC%|C z+u;G3b$j)O%FXdrQnDRs?xkYc0Jk`0kghC3NwwuE(wrOr?txygWX2-o+A=P*fR%LLi9T*GJ%=5m* zVM4N62t%Sv$WG_k6#V9|Xi9Y8P%;$*0|tm1P~X7Mrr$vh4O8me7ORbU9wW@_@eZ8R zLzJz>o8}VzsB(umMXL5fTyo8zIUxn6UZQB;h&?98%CP%ec#yf3!HGhRPf}U5I5~1& z-2hwLT;USoZ!L<2a5C3D=PCP}Ex$#cpPApsWN()cncZ1i52F%0NyoDM0r(@PAkn(AI`MyG(W zDX>n<5t&#?zxnBzT#u@2kspYD(V^M--*g{F^v=s-|%FnwGtIS#z!}f^Sgh zvxy@uILX50AZ||_Kh7u~+nQ(x;WhoJTUg;_^sv^RhOlelh9)x(UdIfHWk?si6ci{p z1Uc+Vg-Kxpi(MBGR|J%YL^XnRyf6zpF-%zGD6KIU(Z6w+MutOO?X+VW&?q%|K^=eo{*8~`axQwNrsrg5b zrz1g2>za=R{MmI+tMdv&S;OPX`2Cg|rmbBx$srgCe67-;L5wE>31l6u;iVMmgCo_fAo+u2PRQ1Q8Vfr=)od{;h3;?> zyj_JV4YGh&@?6%DU0Zn4an`w#szz#rV8}grDUY?SXhK2=dgd)>*HCSSL+(#r(p&v` z>mF_UbyufKWm@)jPN!(tF0h->93PoeDa)t?>bz;7G@8&yM?m9xS&XeFhf$u+A+2mU zC8-gV#6SLA^tD~(+sIxpvGA2_aRwcxh3>?VI2^&V>UOzFiTZ?sA(w0$A9o=Ihn4g= zS6wTL4e~5J*a&6;zQva`eIE;3ni2P)B(e#24HlXaZV6dtCDLK&?JTPCXK`+2npqE) zlL?%t2ngboUFW#kVkkk1kW`#f2L95>SUj}E`M(wXzcq%&f`~-$(;vyt>Cg)u*4tF< zgW-^Vev-|AT=cmXs23=&jD-?Rw~rv&wfVCn8r4VMsQS=39@T8ke%|N#{7g!VY^Zj@a;9B(W8I0I$xBI8RaoNc>+4)4b zuwlOvl&QD)xXU*Ax;?Ss`+inB(R?`iP83!2jtKKRH2Zt@HI}PzHH~KMJDT$0?ZY`x z&bj?_sb|0WIN{dmblR{W(i`i&OE%?YAA&H9l{)36_waJi)Ok@cZVf!hZL^4(phN~2 zx{P7*jf(Y3k%HcR2%spnQLw>*M(b8!H;O%N{I@P7uqrZeT{bX@VCdsZy_(=pdQp!l zMTUxyuL@JhP2mV`1aR#WaLu9bXuDWoBcMl<2oI(jror?=KGsq z71%9-Nm6GTXBmOa5=R`|?5Nc70KwdRR6%IW-~>@glKd^W?37WVg*_(=@}&%+U)q?{ zRw%<{B#Kf*tTYPT?kG#L2}0{r-sTVSsmSjuT_gxtEu012;pp26{P_mG92tnXK zNgN}1;JkOGrp`07GalX$IkT=RmDi8%+b(lnv>1Txg+c%~`u?}8QnfS*>63T!7V0~{ zLO{jS>qqWdxGJc^IJ}#E9z1a9Acd9seYQt^#%trb(`n*$6AJ6)dLZ|Sy+TP}H3SF0 z#4&9uo<}4`=+Q;8S6ZLoh5z+t78d#|y`KT1vZQZBxf!^HLHs8q!`P9>aiml|Ck0G$ z5~P=1%*qDyicdK6It=K%&A<1W_rsAc@tww4jHkh6SiyHhKI?-)l(Sy_aW^M3mP12> z@krPnV%Ys;Ib~UUQg&bu*rVGI_)9y1da@wAA~X=wNjC#_9T5r+)R>$lgBw3`F-~Cg z@v1+p%&!~tSgu8Y^=fY}OCg#y*`yMmu4?L^tg*4!(%Op0Zt~HQ@Yx<&a!bqbSl>%c+{GHFgFPK5JEyKY>5X`u!VJBx=JU$aZ?SGPcnysa>Tj)WgshY}FckN^ z;FGkJttSF5%x?=M|@;Gi-jGcTF7HK;vVcdz7=|N`t>*i3DW2Y zq@@^ep80tLQHX^qvhnZ;2SL}?J;74GP=!NB9+1-+kj9VYJ8*!Rr<=4*pBzMAncqz; z5xn~W9LVn`N9jjMw{KSzVs_wPZN@C$sg;Nqu|$g$D4Rf!(!A$q0%*9JPEG@53EQVp z@P+9>sN%02?{{tE;OO!S=)J#1p3`3j#U$w>roUR(Ct1d{R{EZ-6P>O(I?XoX-FIAc z?+U4XVb&bhC*~?kFeC%opA_7>!!fCjM%sq#I4X=@l94SDa2&c5(N5DWlzg;Dq9VcIUK}espqCJ#pXAa~T)O!#r&(Uarvz!aOH1no>&^p;ho^XA zT{!8Vg0%KfN!tZ}*^(jT+-_N+dB1#?|0YnGkB z({{1(F`#V!PqdGg4cUryA(N(x7Q)DH&$&7$h)Kf3wIa*4BJ=gXPcwyWIqi0niA|jR z@8z$PZxsgDuLNy`|7_f4r(c?Xot9mm9hkv1nuj%JeD}hn%yjwTTG%?8cXB)C-2V+x zx^F!xKT-FP-aYBck#}b`eHu+JHai?)*99HB06OG?XLJcy^H&n-1^wMFs<}+Hk$XmX ztMCuRAzy5UZ&0)A?Y5kzG)vjD2Av?crd`N?7#)2Bd(*7j+={6MM~<=@+Gi71=lKCOWiC6+vUmnG$px7>aaC3@xle){Q1TtwB4Jt0zP5Av z=jwSwOVY?_Pz#{+k%de^J)B}acKE&m7Z6lB3&GLHyj;c(g5+T;#d~dU9S}KoW&_{7 zt}7w}FvdluN3K#-M$n`+FtI8kveGfk7U_AQ7@OEd0CuXP$rnEH(zzB;?ZG!LEu%(C zu{ZrwDK1YX+vdiB_y(r<6!Yk&fX#LSX*_NMTjqoB`w(l=W={2(E4X!y{q)4y|3ZXE zcx9pf{QD`FXV${*+m)}plSesgtu(rSOJ6Fw=xkaWH+6AXWjJCjm9Bw1JRqd9bfG}W zHEO!D;~JM)NZNiac*?7i@i$^z6b3nkwp;~D1FUp(=ohEnZ>0)+ScQ4=^Qwwn(h542 z>Vx7u?dZ|DA{A-)J+bD^+9J~wI9E-iJ#oK4tuZG91X8lAFeTt*nR?MMxQ0_`+EnK2>^v)vy~sP$*7F4|vx|iS`!ArW*fJDcU3DQI?}E-Baq+ zHiQ@Pj?lf>AB)r|gb?kR4x}1>BJm4+#7$I=iNfS7*#%QdVJnxp66j3ZChr%{`W$q3 z!#9=*AjaI&gbaQ_zvJEIzkf=+eTM<=6!v^!A0>_Q8`rd210{*;E8g&<53?ZZCY4%y zi+Cct>|C`H-+s0gQPNgK7Cq7sddxhWxlQ!ju2$yeWs~^-lSH=ti+)#qniu#^ruLIk zX`LEt@0KdH&9>_jK$n`{pRKvAI{X2WqHip+V8Xhp@ zIc)1*!v|G9S0Sl9lKXCmcz>K@_UG?-&wVbm1iQ|Q?z54T%Q4te4SOn1}lPGZL$ z5|H8mng&&*_dHZ$(dgUEJn*)N@BHB{#6W3R&nIMaC~oLLCo4PW;h(%Mz{s6l-@bqD zx?Nuc2)m3Q_Y?kn^)zQ;eN*w;=}92h;gbxn$d$5MfCBz2kn({<>nel`)7ba9(yhbl zRYmS4ZWpLyziz?^y7xd~eWXX3mHWs)aCRbG({uc*JZ=~-6#=!HLSKYlk0U?ExTG^TaA!91b zlT8}L_45m0U-$nG=S)c-kmuBm{E9#TMVLThjFfSKPD0`khoL?ExnIX02IGgY5dxoI zx&svV!jHGn7$7qH?l}^|K(z}eZJ^yJfbROwnqop_TZBWGUrHJc5&la|A#xXe@~_9_ zK9Mqd<64#sxq&{J*%8#f{+n3vy^l1h(!-F*-d==z=lAoIw3=^ihWqFXY!<9cCcooX z!T!{09;9nUEu~rjE;VM$6@j0}Q>_Tr)7`1bGBq_~%jBsX2vxc<v z!^0vXOf$GSxDzn2tt?5f7V0DFYzyKj)$terS{@UXCOF=U019Aeuu5L6a`5VbgBjJU zNz8YGw)QB3J`EUj>PN6iRjB&gPblroik*B8cLVPkDTWB?x2fXTc+-s343CzI0OZ3W zD_hGlQ0NXD;dWrzMx5N-8F10bO5qn^sBgU-bLcLs)%TC<;a+^7*G)4!+}hnn15F)6 zl%$7WQU6@Wq&F66F_aP;`@;gr=#H|@l%+Bq_|R!XTg&9rXr5=K^}8ak(mzv&tYs-3 zM%J}z7oXXrAz_@(bXgXeprCg@)q*oFx|*W?gsV+ub+tbfs{-~AiEd}5zki2!%`FLK z-jS^9I=gD)QQCYOw;hDXF;u|LCNDuJ1E!Hgo#5j*^nd&9c@U5F%&x|v>2-D*X;u-u zyzuLk%kw{?{aDJ%eX#`KkzN!yhny5ZZnZfbi}UVoa$!&d1#rZaaBMN2*~!>1Ozx(7 za2Bq`@d8PpxljaY6{j8~m!J{qgh>9`oyk+r>5hLplKD+`ae@#~jMg0&mHX#w6Se^d zZ>5FZb}8pDL|s=+f^9M_2h%MvRO}tGlec`HdAIrTubF>%36-1dl-T)KS8m!;bdar= zoHy!X-#k|m1=lX0bI;swfOm9Sy{Et|yYc<)IG7G7q54ZODSOw!T#|5Z@T8kc0wb+KRFh2&5|-(1Xk$OJ6o@5Xw=_AwZtb z2HU2g_u1xjtK+l+o{-&{3n56C@e>b3f*lbn2`7hwgw**px4vuoGuR4U6PK2tTS; zC`BVco|qzVBnUYMG(6<=eQ{R(eP~HA{U#yU;t;HM{)(JGZmn!kQ-z6ySCm9Tkm8+0 zXZ7RmG5Pz7i%GawwJtbAZJ3r1?ha1k;G9906(}j07GjYI<5YA0>QbPPUZDZ9MB;yk zcG%2FB){Zu`0swf<(x-`nI6}7*`airqmGygf2k{QnYJw{ljfPrwnsDt$8FTt_uwBL zue(7=42tWlZ(^`L1_lo0oVO%5a;)zref%_7HBe_?xwgLQ27OZuzIG+I9#>SBG&Bf| zA==y)O~RT%3rR^!#ztxq8&{vL9D_W-ZWTPuHb~$JV7(+&S?qS=$(eUVr|dJhB`r;b zo3;K$)c_hmGyxwuNub4=ujU34s{_RwpGW(6---CEM#!8*5(_-zm{hNmEs-F4mXg1J zr7!MH8qLZ;nrd{U=u0V}>B&q6e>9Av5vTpGNo%I;-Cbj9Aw!;~rC+p{ob25qViLj( zq8o5}VWlf_r^z%9bQmPctBC7Q$ofKw1Ypdb9)eK`&P((P2!N0$!*AGG__#QZt*qE_O{)qg70g7gmhKOe8vC~z?(4Z_Ju}=i=H=aG} zW#-*TVJ1cKIZe)`?e`D|KKn=KZx5*wD}hu!H{)JjfA({I9G;Q=p2}nOym1g{%;9NX zyEgT8B2rQo^L5posvo&W;t6n1I`xAfdGW#DdM6G(sO{GDlf37A=JZ>B{-Iqs?;ZOY zR!0v^&Bs+;gfCMvz|1iR#8IySdR<(Lv(02Hk5>OH;wVx4+Iq_yI_AqESXn%$&#bguocceg5Ze4N@0fqD0X&`z;2EB z#nA{LoFOKD0G@36x|xUsybq^(=90e_YtxHR86gnx{8D24U8zE1iwISjjz+}S49Ad_ zozc8=r`Pd5#uoeZx}D#3nbTk67X+}&q~AK>7FtmnGAL;d&x?U=MB`p*hcC zO+9;QMw=dU_alOo42V68pWs!*UdC!7ujliFdL=ja8lAu%7#UJ zQ}z%7D-7TZ9~U9BGY%}+SRnV|$R77lJw0^CEFM-B1g3s0vGJn8CptUk3{;2o8{p|0 z!^<*bf%oSHrMWvqqc-cK9;@_<={7+%>TBuagPKs}SS!H##e_D9Sv_+?vf9WOfLTM3 z+$Dz9K-LjgZ9h=d^tVX9%Fn+eH7t9({f7x&S@JO{pUL*ZTOkt^MlAxt?-fUnj5jaK z@}H@mamnC)oOc5tAUK;&y~PS&eEZ<#vHzfJpWuxC{r0Ta{%!hYGvJNr%y(;j{VZSm zrbc>T98v2W+uT?G*Zch2tJ@uCtQl~<`L{K5rO)CY?qBR*i;kO+`Xolg`hcMg$p*C) z8Ed|hJ$p7rGOBI=m&WWQh!cft7F-#O4Ck(*CucrLqmKj6Z|D1Rb5 zLHCfSsSW*aTf41xIaP_xYH<($#=cG8%0RZLZw1GU>EL_^0*(c8(pix5RUv$oKMR=< z$Ag_As!$J923U=2_XB+tKy+fpGUZ8zI$3_4A;{UIV+}R%qK??1dQ?rIM|O;gwTGLQ z{Awo!wqpCtu=+ZGsSN!pP+aoVmYuP6 z_mH*8hdyZF!XIA|lMF(^U;@G=C;+a|*>2t6I-sUo>UitbMQhW5=2x7Ef|EJwp{M{z zql9dnN^3ts3mtLI;qV~FJb@LHu>D)Hs6J)zb}yWYRh9qiIj9dtr&RE z?YRFGwJkLpdg?+BxEz@Ecl>*BWZ5Zkqinjl5BzPiAY#(=Ysr)9B)DbBED9(OaK25{ zczGs(yStrtzF)tq&Y8zup02rhd3m{cp)>tH`fBIm;-WS;d(M}PiRSB;4|{eV;KxW> zm6v2s6Dld*9i;np%bkkgIO!sDZT`!$+8!rK%$k4Q`uVOhDj~-2Ywpq2C-5+|u5EG( zTb=BU9wg}NlUjD`b(u6GAy)c8=kiZ8akKbsNqch*q3z#D%;F`%hCy)N=~+z?Ulr3Q zu2mIV#TCx}iJb7L)Mq1A<8V@K_c8In)f|fT&G|ajXeAz~_$PTqTk~{ZVYAWqdWW(0 zEk6bfe>(R@DN#lhNN~E8UyBb;jNtY3ky@fnh+kR>9`Dar3#7EwbYqsB1j z`M6#*6?dG(u<2unY&5sb?&2OT)$LG#dN9Mg4=XX3JJgA25=GQDK zXSP3LT2AUq=%|%FAM*%KU-nP^qp~Mb-bS=zz^x#_?JDS2jbiWAgCZD*;ERiebg_k) zw8DC6U;`kDHv{_P5{P@r!SJgB6XOd9yQg@)`>DACCUg0(Be=Kv>7qSRk0- zP~fuS<1arLRyR|kqp3_(``xMe-Nqqtj@A2*YKoh}%C;NsD`!m$g6%uI>2)m?%jfcD zeiw6FYw}&S7yBzP$T&Y333PV4wxnt|c-5oxBL6U&_$N9pE<@w&bd$o&t1D>LRtG@M zB+)2u7HrOdjQR@1Bb8o|AucyQ;I9ENgz78{Pz{=HQ;EIIsACIkjp4PpkN{? zxO!QUMe;O+2o6JvNmM>zDq5)uUYsuI!95ZL!(+$1Ug32?kwZb=JBblLGQefALsF_! z6+pOp@*7KXoeP1QHz2tzY9dd)pAlVH1V!aJv(O?!{>2Gbol3ehNejxZ#@-o{a4|`^ zD+huZT60BBtrvMPk;V}3cPLN<-=TS}1HRFSToQ`3pId0+L2bFgV2NzR*IL$tk%;a( zkXz#Jj9^ZQ{{v(}o4!qyBF#YIRe7K24Io;OF1-ecPGdl# zCej6h!y$pG3*9Uz2XsLc+$pFPR2VLb0KxHS{n?xaqh9;Fv4V(G|V_xq8W>G_?+mU2sNw?f!0q zzsC^jF$Q{!zV5D2kA>;8F};>>uMHB!FS^5&!y;FU>p9{E&KybKRmxvqvc{0{tj!{l zi`zQbxz)8_v#P(Ttj$+wxKx}kG;pc}e2Gy=#rS4Vdr>=AYO3%Ui(Q&JzoVU^(Vj&? zZ>8Imh2RfOYuL+;1Y5$0tG6ZWZl;~pe)D;o2x8BpEs})Uc1gZNQ5Ucwa2A0Vv;g6} zApsNRGN?54TkLR@Sn^^dmmDeVK@c$F1@4D>+nFG?gCmp?zrlY&ARHS7Q=kjvr$4s5 z_-p$2ru^D~v9{M$>Cmt`TFY9SO0}YVw=%~qEAYs202 zKJ&4T=0|@1w$N`n*vxvl@Z90{+G4Bvu(WOWu|qW$ZLQZ>5jBINO1G}Ut1FEf3nQ95 zMv=>)o!`y`cxi~1SCA3vJWq+v1klcGDWnyFtpUUcd@j(LL#c8pbpfNzp^#}aBs=9p z#=LlwF2r|S6w~B{{k}%;r{o|NgVV!^M_*0< z{`IsUpFi=%zQZ3r`{QTNA9(56kKfw+)qx$Ky|(p}7q@@*^4@O`ym;h`SAYKYt#dye z$o~1`qO+fuXMIy&_)|yu2@yhp({!9Hi!jeA&GpD~{j$Q4vYathU=+B3(I5kAwA~;2 z0FXj~Gik)~dRS?`()6& zKreKaQk{s^+*qj+Rng|E#3cwA1lbxRD`WN!DpO#yF>&)yvH zcT!Q2#Ue6jd4Ul5?Lr4dHwC>_UURMA4ySEYsM2eOS7MGshDjcz`A!AA+DX}SWnuVWf7r|?m9Sm~9bQA5Uqm8W* zCpU^ds=+%DUWQE}XMNCC?YGqUt*w-gO$7^GYA6{h1IO6*kk+?I_ zgSLI^>GSpUdArdDaelN-+yzf}pDWU1kMy|W=oIY^$83eZ9FlfA zTadU~b$+qRCs2C%=8!TNvBzS*NZb>EG(n|1Y=Dq>JQ#_4shFLL+q_Yu)-OVw5B7Sl zy7douVe$qTLw~;x zy%w|k4#a#(VmO6ZNCT(fzY0!Z_{LVj$d(uif;Zzw- z4FH*6ef8Dz=g)uk*=IX;?6~vJJ8!=E=H<(8y=D3GrAwDBT(oGxf`#+v&!01A4lEL2 z0W$^f6bEaAQKJzX-H;(eV9fxFjo-LIgJ*7hY2|At@7c8LfejCDe)P%vc04ohuFa#T z%()R(SJ>VKj>t#=JMa((6UKq=_XzL5?g;n`ixvX@!rBJv3Co+wlMw|TENS2>QsfWh z7p8>&7a9aEeC5iOt5&VL`|i8%x#ymH@4XjJApvAT>$YjrQkM_qK=#{jza3J}nl%ef z!9n?;jwpo%7&uV6_Q5sZ9r{Yh>o8%!5u=R=b_6jaJh31D{VfWd#DDuyVB0_x_>#FR z;extD_9mqdj!7&S!NHM8*lICRp&-J1(avmmb2d!o zkTUO0qP>{L0rU1^>fU~i2n6_I^IoU`rfwK$z?&rDO(DGfAn$K@c#}}?Z_(Z)X+x5+ z0on6{5b&2Ezn8FG1n;7zLsr!Y;Y|uOJ2WzcBZSw05ng=~-qmYWAUcf_M5|U{k!w_P zjZ&^w$_9!CL?wp=kP@Q>RdWs2J!YjQ}2~GXz4$%i4iB2m}Z123HN$B{hSp6Eqs~LhYf_5CUn4 z7U&0{6B>*Ny7$+@vH|rIbWi^g`!gvMqEO@&z5fmL!iYI=9U8yriu5`>F!}`dq}ve+T3r^sS*9E=|EH^zzrG@LR%&b++hqa!z|*D^H*oc*6oF&UXg5O|tfqj(V@X(qnE4x;a#sOEGPTmC{og z(AW4a&5Vl|rH~15#M?wUE4;>hhw>c4AcScc6G<}*vTWjNzo{W)D|PFdf=+A>ObH?p zHtl26{#MG*M)bi9_Y$6a$^MrJHvUDziTF5?03i z)s-?~wOLicZ7boo7T83YUeQTE{{-Ig?6jYcxEkV?%7nQhVXE%7RVN&27Rkd$zW7nz zcE%_^#IAj>yx==A`j?`Y9{_bw zR34)!h-%T^ab$}*%y)6x&r4I+fA{@s|27JoVt)7+T|jnu`T_Fh-vR}`zvT6;2cCZ` zU?($8N#bNJ(3U%#>Avsd#{3D^N{q2qMs3B6;T+=06~JB2p_F-HO@Ucd+|gXx zP|IqpXYtxf%#u>KhUHL~xzxFSIix8L8#05aZy;jgu!SY!K+5ut)=G`I+H0zbyDFph zd>Ym5m1BFVn&x9 z5J6`vi5OT>GmEj6hRj(O`C(COhDBaT>maZq4v(t2D55(blAH?);EKRg8Fgd?MFi#s zbC^-U}86!L$1O=xz?bM6ArV(zGm9h z!noTa?v{v?&A`hrh^T=nM_s@Q@8s5?AKtM!b{UkG?@)oi*sUQbaIL`;IbD1)9E!x9 z@g8rq+tuCU>Fq_lz`eb}o}OT&+v-nfLp{cLudDZhKi1<6#7vH`R^tgfq|cLx*Q zUM6n$gdtF8r?pzYNbB#Ey4yh@7ZZ0u2{uY&59yegI}&%ryL}$UXbQ=VA(<{961&&} zM^|#0``5;=>50!!kqs3=bx{vtbF&q z_h5+yll%4S*QceW9Y212@7{f|@_BU6W8eSy)7kUcXV2%HJezUs=Tko&IdbTmZ$AC> zv-jVB|CLu>*|TR4WLddt<&q^!U=0I{9$2Ul1Qvs_$c*$PjCeMg{2EDfd~#e5d4KD*4(*s7c5wCnep%Kx8J^E#frP`y6et6@4W4{ z+aP@2ym^oX7IWlUpiEc@!6|rP9R>4QSS&%}pO61+Fc{j~+aG-JL1;s8paK-loH-MY zPzR{M`gLoM9r>|Sz$M@#h%sqT3X;Nt2^@?dOAG`L;DQ*40^3Xu5c>cW7_-y*l61gc zv>jZC>;*?yAPC_=ygQNT>F)09?dj|5y?~{!uLn-?7HtFtPC#O}%Lx)gR>LXeH6A%?NW`5|v9MndISuitANW7_&uSZkEVjq zbie#^@t^+b&%M1pZkGe<1FDHq&DKDI6srs!^F&T|H#TP>2E#)|&)pVUUHz~|B_hrc^Q-2lGBuf5O5?G9B6@D1oYg#bH}5P?b)~gsr^qq z3CCTJ?w&ez+JuP{MvfdcV&sV7!$%B5_PX$QIE0KGH5wfWEIb++1&oHvE(95&K|m3~f=Nb5M$!*-xB*ZLK(Z-QrVxS%nCd_q zrrHGR0F6wtqdw5zAK-?9kPh&l-LFt$EO1T=2mckl{|oiPdUN19G}7Z>dh9Mn=kyqC zMxEKDatHO{9xK!9q|hvyfmM$XQ$V4LcwOr+ZGOR=rEFSs4eVo3ft>x zdo$zghy=M2x;5;p30R90QOMwG~un!|YFA{8v`Us*|V^Np4G_jf*EBGD7 zW@%;!QSP3^d&C|0wxx%}#rOy2l?h8l!d%^Lslq5Q;sy2_>iYZ{dfA)B*$11-PUt#! z96wYM_0;tSb3E$j3(p=^@xJ2MzfqA>d1*}!jZj@y%mh`fz-+2Tv<_pe+!JUUE?y=r!Fzwn3!|#Ss5*~Pjy79_U_AjUVLKr>(6a__xX))KlRW%Pwn{d zrM;iM_w?5Xpa1^zSB`)4*15y)=bZSYEbXi6-0xdUkMb&imNcAGbz~YkbFGpBx3b8q zDGq8%XkAW7dCbW^=4SuoYB}L1FEznuW zXwO5-`}v3|BCLUA*rFB$F)a{K6@(Z9!(C=YE#*-QVScEHS&BpYVwIq@xxTEexm43x zXb=@RWTnxr0!Ehu-GJ8QhLqWek62s8=%KS!Ms3w`SC!XTWl~khgykG|rBqnW*r9Wt z3kczkLl1-+Li+Nk85FUiW<*R8)}8Yw8KRH6TcHjZzUU6$>TWY~ldm|+#4Gs__Ad_ONR!iz1!3}i%%EQJxF1Y(3Rwo_C` zIM~X#TEfoOu&ar&HPMb{+Sx+6nkiR((B2SqwuXGoK`$iEcPNXT>iVFwIpl5(I>)I0 z8D9H8Yuu4@r59u2?jB!HZ?L<^-_zsm>-F{Y_!HfMShv^3s1?3;GcC2zia^v9jF~Nz zT;=5{yWusIQSDVPi_J&P##7)PX?r@hYtn)AiH{BJA zIGC6_mT>iS2YP!!g`bW(f)NW9bq1q0DrR@kD5WtVF$Wbv#uklx>8R7kn5c*|5f9ix zYI8`@6_n@$Vp9-2vQB5S!pjjjn+1-hPG<{LN#*52-NY_7h|}5*@%>+V$vgn!(WsB-7RkhTszC~Y z5b}c~0mX-*wkrFu8|C$j2Xl{LMGtKD_gZT`zz0 z{5Q3)ALo8_UUaBfaim&zve9ym?a1J`@7tfh92Ua7nP=WOc zENQ@{z+Z5%0)uM-EqHx36;_f2{GH#={JRuZTFcN{3mlw6O`t$nkU>UR>OfJXKyoAo z%i!QzKpm7!92EQAci)-KX1!j2`t)g1&b)pH8pn+t3yY{ncRh0M^hrLqU8|B4IMSd~ z8}%B~02CNOz%XGo>MTY*7K8#@2>6RoU<3psE?R60oI-(#A+X1lDC70GO-2LcB{sj<;Fpm3(wN3KNHE`|Z7;!m z3CQaPxg6E?xaLoh+imroi6hx}nG6bksDRW&MwQZA88 zMFT4UN0~$@mv&-A7}XPj%UYG$WPlqAcfr`Dht5-9UGdY8-`%-l#eakM#udGPGrcfS zl5vxawd8Z_-$8FG78P~n{$A1hpQ#r+R5B4b!GXvO5Q-Q!Y&a?n>Vsh*0z|@4J8jxD zg8#y(J#peh7>gk>1}d+@2rx=H&_OIr0AO5(aeNBi$#%$)AtdTwOiu#AK}JvqiD5bc zxnO1jV>c*;(HxGC?sCOmNAFiU|80S8x>#jpATQK<WgsF51YV?sfEw9$Ns(Js7qIaeCdm%W zM7ZH_UBFrD*4Oy0+yN*s=6pb~Z$I+`ioz&x@b@S%vH!)$a)72<`kS0&IEa2tR4^ka6# zAz{P2)rGGYW&R{;%XVsCEIN0vrQ!!^`#ZJyA2gL@IkjK$>tAPO7dUk_0b7nryyfTs z6xgM$?+c#NiMIXtd5uX^WmL0tl1h)Rf-zOl#!8E-QYx%eiOOSUR>BBUmM|2>wFNPC z4kJ$s3D1YnPu-!C1Xe4Hnh~-VvsOhBQdS%>6ovI!Avt1%z*NGJt0b-~ifM|Y`b>xH zj8S+>!%s6vGK{jbTJb4`5d4)f3o-(wRmBl~VZ@M+jD-y)5n~o5&!Q1ia2~DBrB&cb z3n1!YIA&AwjDYy8Uzi>gBU~7Py!_*swEzRb9mqh~EBHy>eq7Hv<>a04btGevc`~Ai zCF!9AxSZpbmIDoG|HkfcL{#Sy9mHksFEauY2_9ayzi9vS%ujIZ{}S5!m%>x>Wc1j= zeGk2Q;?T>-zIx_|k9L3g)~?TA+x^LFk9_p%&I2!RdHdO|Z$H2D*++Lg_t?X)?BDp> z{&lbI-Sp;@yFYmKiI3lT^2_&;Iq=c1-aPZe`#C>b&op%Z_ksPD)zNskrC$ zow+t?zDrT)RTuj;r3eL<9(T1tV;*y}kGT+a#`&P6G-51dba1D@1Gl>@Vk!(Hyf{0g z$fGsjht5#M=*|T?;ie3LQwb34sE*sK<2LYA#gJWaX%rdf7C{NLvO3|cVeBl0u(Y+Q zg5ObTLnO{QwB}qultm-k?K5Z(Kp}Y20-bQvAtNLxWsGHvshH_1iWo}$x^lSyo~8<$ z8afQzRybnLVtonI1-h^mupR0Qg%CCd^12pM4f;-l zQRsFHLSa4~io_k7uwh@&mqsTOCfuu$IK1|s=QVRL2o%6OAz5K#EpZn z;C@~RaS9a9unIG6@^fYlL4gV23xOFHA*9K&i^)!L5L@lFA{vUYzlpIoP}YW!wVtxp z1(8(wO*MW?W6;IMd)C$ZZBV^3x4y`!f)Fkf;xfU-`ahwMf7%d}R@&3c#CkokUT?e` z#GUB&M&fQiWAQ~zj<8DRZZ`xZ=8z%~HPZ>ZomQ!QJY!I*@pkHcXv;M^>U4$mR!Zrm zEL7BP4k}DR1q4zNmnYl>DQ&cpid&hu3qry%7Zo={QK6XG%XHakjfGN}LrPcJ5Q)E$X>=!i2KcSjShXx!%un^a!D$k{4(wJJPZQ&8>*Ym7m$H_~MaO2jTU zLSW1y!S%L#U1j2#`ui?-N z4oZVn*}_pgCSsq0$&aRn-FoqWhk%>#9~CKD6$0}$O!DfhQOE$BH%+r5J@gzvKJg8 zg6Qrif_AZO-=e()@J(XA{WK1Qz(J#ut5q^+ zUTk11R>+V&uMFGsBA8Vqkcb50PQFaisaDFwLLLEmg?x^X*C7DmwhOpzd=L(shlShG zillvjbhPq1P!ylj2I+5)46WgDBkN|ki3os} zOXLXrCAc$B3?f8FNhhCdZHEkvr6PqCVZmyp6fO-e7A{{QlXSE-*H*Dk96tgNDOn?> z9^rwH^WW#aLHwyxlJbh)zfLc)1twoyL10(~e<~T$H9*VXP%kNMVC-f7)G0}MMeh~8 zf1O_B{f!?S@Gp(2p$u0t#bFpf`|GG*DaWrTSj256Ek2~rMlSK}Sz zuEj7e-N=a z)-G9k^Q6gBVP-pS{KUb7haed;bO;D!9y)9&!Gb}C4<9jNBoZ_q!B{X9O?ZJ3G?@c)Y5|75*nb(&g-wy_$Cw3O8~m)10t zRyEhv8Z=U)QD!zNq+EVeRc%dqd2MxNTT7EhDK57sQQ&j!GM2`|c6)df)#3{lDzzuu zxTo9rEQ6^%KykxiKEnuThHvw7+EpDa9#?0t_L-X~R|iEQI*3rHCFEZ`ce=20di)F5YvJX4PxV#W)@`Ir4@cdGn9k4eKBauL_r;!4%GOqxXP#I0QgOz6^+oSDmcCn8_#MBw z$f9GpjVCnxw`=ncwy+@ZtVvSII8VsA-?FPqEb1DEp5@TLQ(aINb{yC6kEwZu0b^aS zFUO%dP?}R?(^bYCd5pF=sw<2jpcZii`wf*A1uJGMjTu;ID=l4NOj8(B=SP(}n9?DS zQ57)SGDHD^3^_|9U5M?ML57*d5d%aO(Au!0=P-TgD%`o9_l-lhM1#Uq=Z`sTx@ zzy4tFXYcGh`0};`FKm17g>COVzw_-Ew!QxBmKXPKdwk30=k~09;n4@4-?jFo$2Pz5 z^se__ef*=hp8VpyXTCZ3;!j_^e&)OPvX6aSeD2H2obMV-f8x}f6t$dFaWV~}T#G!< zr7Z9%i-X!yN}m-FpZ4)i`}olK&`KcC;25|x<GJfY+jxb?+8god9FNs-w*Wd5Y zJB}K^xz=xO3V2#Wfm**EUcXg7L|B~fP_|G$9s_Sh`auiY6!b}LB7CwS8uNz|cDlzN z?RLhx-LZr>6tUYWttVoj;ud>Y?Tr{hF-yGH-P7w2$6W5P!5ircgzbT_Ef(|lBcBhE$vhohA+dvj^iWkr zr?VLXL4?j`nWtUpL*~Gp&K9k&)8H3r0z#+*M2X#P7Fy|!>D&>OBdjC~Pqga%-8vMG zDSzseq=W%C6#`@NwS$KYyXxv|@CiB&9X0|+Vr=4s<^kx-FpSyoADy62zVHW5LBOB< zu8YQVJl^9u0UF~|vq}768ToKVI3^R|B?L)BjxZS|xzH&t8UB)}D|-Ke-m9N}`f0UV zt<&k=e*5h;Yu3QpVE_L8ufP8KEAM~v$*1OlNTC?TeO}kfbfBK=lZ|r^R(5I)$(@I(%dE^mTW}rpV zuwk%*x^30!jgP;x`T6g+zxMOq57M6dH1qjS&p-1~`cogC-T(gSz3-iR{GF4JzI9^P z>&JJzc5M5rN4CB4)3%pE4ink_%8?zf9pCllsmI z_`G@Z2>1(^081lqu&9G0oI)V1VW1|kn1MA9R3`OPO4KgbT?a>Sut0)vh=oNCM8P5l z)>^N;^2(t@hn|1_dGd=?SQFlT_ucp1ci%nt+_PcBhPt{shr^*#sg55%zG~Gfr~|Cc zZoT!^#fuli+I8j1J70P6`MjL-0$#gPF2P2l==c6zdUZbp{4ZGnBM2Cyz)1)gp}+(J zMuxx`0#2g9#1I&73P;RNLqR`H1u+Cn$0AGu@9Ngm9mmYS-G~dKx9371NG}0`FQLGR zIN^VY#UfNFpi;;Pvu)Dm7bCye&bJ@%#W*j5diz0MY{`olD*EAFgzzHiM|hKht$I_2 zy&%N4_g?^f^-11deLrb$(#RKa^(JW?2%`cvtwn$@MtgZ8Ay0(ud4D{;8`A{Cbz#Wf43`OkP*ns*6N_U3SIFz=Xlt&nWSvhx_tTHxANuNx@4or^ z)QRH-c{xoDwU9t2N!kUIYZQ0#p(ZtzWoc(lZrrc|t-Al0zOViP^};}T!;OQ<_f=d5 z8dm=fdO^SsAt)n6{-d`u$Q8Z+ReCQKJ3ucM6b{G!aAdLyV>FDjOP4NPvSbO2+AthL zegaAo2lJMJFePLkK72R~@i5jydKknZFcq8f56lHwQs5@!nl)?I{Q2`i9r<|>9B;bm zCJ2Ek1SD8|)6xYC7f+utYs}d3BSwxMJ!TyGeGo>0lW;KhqiGJ*gIEL)A3=a%LJ*9o zfw4U>0fO-dFu`yY5<_3AYbKKS6;wQFIv zcK`kN!xZKA+i!=O!`uUE3*|!TFo%K3474O%JG36TaN@}2LljgLDVs6{j!-RVG-#87 zX~02ta!P=5NCt_aX3%b={Ny+CapU3g$<0Og8ty4E+r07|UD5k@(F;mIZE79b#%gRW zt7lg<2%6hCbm5rrUtz~r(2vHrC&D@&S_L`=Kit3uua&}eSH$vl8%3p`b{^?XL zuUM(8b353Sj}xZJ&iF*wRH&8qaw1`YJ;-4z+eqR z_1o)04nZV_jCn)00vFnk{ya8z%dm*jE%NhL(K(F&5`ohKr?Sd#Vl$p*%H0tO3Zh|t zB+Lm1x#3V#$j$N?F*`6pd*OKb&Tm*KUW7uH$l)NH_O^vRJOlxwC}DC>IS`ar5DA~T zh_-?H`cHM0Av3GKw#KBcb{Z@2~%~#Qk}3OAUJNWj@xT` zoHe~3R@hb+wpB!(H9g+?gtyjXtkTJAUB;@Awb*B@rffA{OQpk5Vb@i;4K+?fwLw`I zuvXBHx*mU3+*1*CRK)C+-Hz&rqr#%8HY!V*E=;^DFN$gr>>D$JfYS1Wxj3pTj%o84 zMINIpjA{^=8_^aN8tjdHUfOpW6KR*3J8Nu7CQ` z)z9o&{p_xFFFn5X&1ZML`_i6+Z|wW*-KW3(@P(f~fBEF0H#2_vpy2dp6E-W3G=5=uw#=X$fNhji47g8}u~H>OiP<+pN-oT?s4F6f)FLg2P;%(@C^2;PKqov71OZ0{#x12W zT|rEq6Op8cgruXU1%z;cP$uMp-V5FGi*Oa(0Q)YJ7+S6cB)S8kh{GN3VtQPOJ`dCD=EoJ(#hRip|eHp6S$eKaNH&La3pTF zJ**6O+kFv4;A^4f_OMDH6pLJJzN5iTYnhlU9CL~8CHwTfJ=kXP)6!W-pYjxW{~ z>vejfIy0ppEWR+^`~5ofdQAHZ!z)UF$5!%#n`^GU9ugCp2uOJq480J9W{lTdH)QDW zVZ%qFP>cejks1%u$uS^XDh%$++IRvO@7b%YRMd?XImZ2iZD^I^fXbom1hJ^JpqS=+bo zm^N)1tP^I>U9f7+wvGEfUcK+D+aG@Y=GBkia^JSw?%RCZJsWPlYu)mdYi_x7_020D zxOv6>%kH>;+3oi&z5U*P0snm{aK!`5?p$;8%C$GI+IY*|TW)<|*NRQgt$yP3eP7g^ zF6#L7i*H~pgw|N&#u3aHloAVHv>L;1(4avC@P#AsfJ5zpmpb5wg&mXt>mtYtxnMQ; z#v5;>rKNGX+>(-#ef##o1uj~&Xa#n6+;PW&0|&HPt<7eusHoV#fB)jei(%;q;jo5; zWNTJG@YWlz7Z>D;gj{ScicnykMq$vYO$NdR@f!&EazkKqzag-N5J6xFc%UJ$!|Hb0 zJT3>~g7CNlK2Ip%qY)QGayz(03`4+4{1-#O{dBP)fqd})pL9K-Z z{Ds6qUPp67U3O;1XPzqNq@6pk>^ z!pMq>`UkzxT)(m@#8u zT!v_HSK)LRoV?_L*darPOu)QPFzCamjSEah5zjz}>v!oVKGUa9hcW%uTW^H{9p(?< zVEA6Xd^t>JAPS0wWH412G-$}MVIzhQ9|^}1BSwuLJr>@;H{5U|$e=-khhSr1WE4!S zf-w@Da>y!}Fhn3cm@q`(4dVzHjIDwvPMky#;fa$bBf*I9iag^^kTBY)H+nq*v4sSl=B5zmmu2R%6RL7j)stO2xQ5z%c}gQwul#PB}e%=7zO4;LhW>r6Am_p93^gDUBJO% zC?4W-NE-S6ULa#fIM6|d8Uyb7pp6>|5E5Z*FPusi;zzYxGG_)N|-AX*6JQxRkx!$VXx}8SNFK8 z6Cm#DpruM9t>Co5vCeI-P)Q0JYjfF+#a3k%#QMz@LM}wr#y!<>Om7;q6f)X8MpMR^ zYHV5-yQPvbV=7)lMciDTFqI_?L`vg&RzhElG2g7PBtN1kj%iEdhLV^ehfx&9bR|&( zGTLP%=jqNf0p1xu?_8iWJES;;`F4-G*(W?5XT1EgUg254@O)5w${;)Uo;cep3CUthsQBB8p%I2dEv{x7gh|yMNSwTcAamvR5 z6}chh2glxWf4B590QWCS+=(FIf0YiH$e+*L`toP@KmX@5FZ|!M6r}s_m1lZS%zOUf zN8WvT>zmJQedF29uROKsrF{>*xbLAC_HTUtiA~S%-Sq6<4cpgkc!8nTP8+TIZ+9E zSWw4CgvIcTWQL^W5exLd6R5AUzYW!sdwtr*Nxh&_0;icaQK3uCp~4^nCf;e#cUr7m zCRXovmV1n4Ze6w4nq!xyTliTvalS)Q<+bpssDO^~s0d_f4tk4S+8l>8+abwu$iRac zAbwj@KOtc=OLw{E<0Re4#f=MXj+OPj|1swTRLl{GT5Po1AMK*LZNZq8Fh%IRQngPY zavJ0By-mmEQm{|a~0Ei2aU`~1uFwzm#^40VPD z4=j72N}v&ru)={w3setMf(lr-z*-0vb#T?N0E7Autoh=_i(v)0diCm!8#iv*vIW*u zJ9qAU|AY76c;k&Pzx?vpv12d4{PN0`D`BApi^iL8z8U!NhcrgBqmlVq*}Gypi^B=1o1DRz=lg)5Eg6*j3Hnf##kLTlM}NI zxSVKHIFB21L3rJS3nEO1B4G>x$79{Z1Q>z8$oTid1(3drzZD4Y>+R|3j>ltB$QTOx z{XRDoE)w#bb_)T25%P;+Uq_P0Aqn`V&|b7f8?NmDtKNR7w;%0Aw!Qs)4#`d1u!XN) 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¥XM<=N9w7v#6|Gr-{E`DTah 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℘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 z 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 z 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