Skip to content

Commit

Permalink
[BMWConnectedDrive] Authorization fix + channel enhancements (openhab…
Browse files Browse the repository at this point in the history
  • Loading branch information
weymann authored and frederictobiasc committed Oct 26, 2021
1 parent db6b730 commit 99c3674
Show file tree
Hide file tree
Showing 28 changed files with 751 additions and 258 deletions.
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);
}
}

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

0 comments on commit 99c3674

Please sign in to comment.