Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BMWConnectedDrive] Authorization fix + channel enhancements #11264

Merged
merged 13 commits into from
Oct 3, 2021
56 changes: 45 additions & 11 deletions bundles/org.openhab.binding.bmwconnecteddrive/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ The region Configuration has 3 different options
* _CHINA_
* _ROW_ (Rest of World)


#### Advanced Configuration

| Parameter | Type | Description |
|-----------------|---------|--------------------------------------------------------------------|
| preferMyBmw | boolean | Prefer *MyBMW* API instead of *BMW Connected Drive* |


### Thing Configuration

Same configuration is needed for all things
Expand Down Expand Up @@ -147,8 +155,10 @@ Reflects overall status of the vehicle.
| 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 | Presence of active warning messages |
| Plug Connection Status | plug-connection | String | Only available for phev, bev_rex and bev |
| 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 |
| Last Status Update Reason | last-update-reason | DateTime | Date and time of last status update |

Overall Door Status values

Expand Down Expand Up @@ -180,6 +190,27 @@ Charging Status values
* _Charging Goal reached_
* _Waiting For Charging_

Last update reasons

* _CHARGING_DONE_
* _CHARGING_INTERRUPED_
* _CHARGING_PAUSED
* _CHARGING_STARTED_
* _CYCLIC_RECHARGING_
* _DISCONNECTED_
* _DOOR_STATE_CHANGED_
* _NO_CYCLIC_RECHARGING_
* _NO_LSC_TRIGGER_
* _ON_DEMAND_
* _PREDICTION_UPDATE_
* _TEMPORARY_POWER_SUPPLY_FAILURE_
* _UNKNOWN_
* _VEHICLE_MOVING_
* _VEHICLE_SECURED_
* _VEHICLE_SHUTDOWN_
* _VEHICLE_SHUTDOWN_SECURED_
* _VEHICLE_UNSECURED_

#### Services

Group for all upcoming services with description, service date and/or service mileage.
Expand Down Expand Up @@ -253,17 +284,20 @@ See description [Range vs Range Radius](#range-vs-range-radius) to get more info
* Availability according to table
* Read-only values

| 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 | |
| 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 |
| Max Battery Range | range-electric-max | Number:Length | | X | X | X |
| Hybrid Range | range-hybrid | Number:Length | | X | X | |
| Battery Charge Level | soc | Number:Dimensionless | | X | X | X |
| Max Battery Capacity | soc-max | Number:Power | | | 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 | |
| Max Hybrid Range Radius | range-radius-hybrid-max | Number:Length | | X | X | |


#### Charge Profile
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,9 @@ public class ConnectedDriveConfiguration {
* BMW Connected Drive Password
*/
public String password = Constants.EMPTY;

/**
* Prefer MyBMW API instead of BMW Connected Drive
*/
public boolean preferMyBmw = false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,12 @@ public enum ChargingPreference {
public static final String SERVICE_DATE = "service-date";
public static final String SERVICE_MILEAGE = "service-mileage";
public static final String CHECK_CONTROL = "check-control";
public static final String PLUG_CONNECTION = "plug-connection";
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";
public static final String LAST_UPDATE_REASON = "last-update-reason";

// Door Details
public static final String DOOR_DRIVER_FRONT = "driver-front";
Expand Down Expand Up @@ -161,13 +163,18 @@ public enum ChargingPreference {

// Range
public static final String RANGE_HYBRID = "hybrid";
public static final String RANGE_HYBRID_MAX = "hybrid-max";
public static final String RANGE_ELECTRIC = "electric";
public static final String RANGE_ELECTRIC_MAX = "electric-max";
public static final String SOC = "soc";
public static final String SOC_MAX = "soc-max";
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_ELECTRIC_MAX = "radius-electric-max";
public static final String RANGE_RADIUS_FUEL = "radius-fuel";
public static final String RANGE_RADIUS_HYBRID = "radius-hybrid";
public static final String RANGE_RADIUS_HYBRID_MAX = "radius-hybrid-max";

// Last Trip
public static final String DURATION = "duration";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,9 @@ public class AuthResponse {
public String tokenType;
@SerializedName("expires_in")
public int expiresIn;

@Override
public String toString() {
return "Token " + accessToken + " type " + tokenType + " expires in " + expiresIn;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* 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.dto.navigation;

/**
* The {@link NavigationContainer} Data Transfer Object
*
* @author Bernd Weymann - Initial contribution
*/
public class NavigationContainer {
// "latitude": 56.789,
// "longitude": 8.765,
// "isoCountryCode": "DEU",
// "auxPowerRegular": 1.4,
// "auxPowerEcoPro": 1.2,
// "auxPowerEcoProPlus": 0.4,
// "soc": 25.952999114990234,
// "pendingUpdate": false,
// "vehicleTracking": true,
public double socmax;// ": 29.84
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@
*/
public class ExecutionStatusContainer {
public ExecutionStatus executionStatus;
public String eventId;
public String creationTime;
public String eventStatus;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
Expand All @@ -33,9 +34,11 @@
import org.openhab.core.io.net.http.HttpClientFactory;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
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.ThingHandler;
import org.openhab.core.thing.binding.ThingHandlerService;
import org.openhab.core.types.Command;
import org.slf4j.Logger;
Expand Down Expand Up @@ -73,23 +76,34 @@ public void initialize() {
troubleshootFingerprint = Optional.empty();
updateStatus(ThingStatus.UNKNOWN);
ConnectedDriveConfiguration config = getConfigAs(ConnectedDriveConfiguration.class);
logger.debug("Prefer MyBMW API {}", config.preferMyBmw);
if (!checkConfiguration(config)) {
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));
initializerJob = Optional.of(scheduler.schedule(this::requestVehicles, 2, TimeUnit.SECONDS));
Bridge b = super.getThing();
List<Thing> children = b.getThings();
logger.debug("Update {} things", children.size());
children.forEach(entry -> {
ThingHandler th = entry.getHandler();
if (th != null) {
th.dispose();
th.initialize();
} else {
logger.debug("Handler is null");
}
});
}
}

public static boolean checkConfiguration(ConnectedDriveConfiguration config) {
if (Constants.EMPTY.equals(config.userName) || Constants.EMPTY.equals(config.password)) {
return false;
} else if (BimmerConstants.AUTH_SERVER_MAP.containsKey(config.region)) {
return true;
} else {
return false;
return BimmerConstants.AUTH_SERVER_MAP.containsKey(config.region);
weymann marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand All @@ -102,6 +116,7 @@ public void requestVehicles() {
proxy.ifPresent(prox -> prox.requestVehicles(this));
}

// https://www.bmw-connecteddrive.de/api/me/vehicles/v2?all=true&brand=BM
public String getDiscoveryFingerprint() {
return troubleshootFingerprint.map(fingerprint -> {
VehiclesContainer container = null;
Expand All @@ -127,6 +142,8 @@ public String getDiscoveryFingerprint() {
});
return Converter.getGson().toJson(container);
}
} else {
logger.debug("container.vehicles is null");
}
}
} catch (JsonParseException jpe) {
Expand Down Expand Up @@ -172,7 +189,8 @@ public void onResponse(@Nullable String response) {
}
});
}
return Converter.getGson().toJson(container);
} else {
troubleshootFingerprint = Optional.of(Constants.EMPTY_JSON);
}
} catch (JsonParseException jpe) {
logger.debug("Fingerprint parse exception {}", jpe.getMessage());
Expand Down
Loading