[mybmw] Improve data refresh handling (#16418)

* [mybmw] add functionality for updating
disable updating by setting the refresh-interval to 0
enable force update by adding some switches

Signed-off-by: Martin Grassl <martin.grassl@digital-filestore.de>
Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
This commit is contained in:
Martin Grassl 2024-02-25 14:03:16 +01:00 committed by Ciprian Pascu
parent 8909249b49
commit b9dba4a8b2
23 changed files with 491 additions and 144 deletions

View File

@ -105,10 +105,10 @@ So if want your UI in english language place _en_ as desired language.
Same configuration is needed for all things
| Parameter | Type | Description |
|-----------------|---------|---------------------------------------|
| vin | text | Vehicle Identification Number (VIN) |
| refreshInterval | integer | Refresh Interval in Minutes |
| Parameter | Type | Description |
|-----------------|---------|-------------------------------------------------------------------------------------------------------------------------|
| vin | text | Vehicle Identification Number (VIN) |
| refreshInterval | integer | Refresh Interval in Minutes (by default set to 60; to be set to 0 if no automated refresh should be triggered) |
#### Advanced Configuration
@ -132,9 +132,10 @@ They differ for each vehicle type, build-in sensors and activated services.
| Channel Group ID | Description | conv | phev | bev_rex | bev |
|----------------------------------|---------------------------------------------------|------|------|---------|-----|
| [update](#vehicle-update) | Overall vehicle status | X | X | X | X |
| [status](#vehicle-status) | Overall vehicle status | X | X | X | X |
| [doors](#doors-details) | Details of all doors and windows | X | X | X | X |
| [range](#range-data) | Provides mileage, range and charge / fuel levels | X | X | X | X |
| [doors](#doors-details) | Detials of all doors and windows | X | X | X | X |
| [check](#check-control) | Shows current active CheckControl messages | X | X | X | X |
| [service](#services) | Future vehicle service schedules | X | X | X | X |
| [location](#location) | Coordinates and heading of the vehicle | X | X | X | X |
@ -145,6 +146,25 @@ They differ for each vehicle type, build-in sensors and activated services.
| [tires](#tire-pressure) | Current and wanted pressure for all tires | X | X | X | X |
| [image](#image) | Provides an image of your vehicle | X | X | X | X |
#### Vehicle Update
The BMW API has limits in the requests per time period.
This leads to unexpected errors stating that some quota is reached and the next successful request can be triggered in X minutes.
In this case the bridge as well as the vehicle things can be set to offline and nothing can be done with them anymore until the next successful refresh.
To reduce the probability of the error, the default automated API update has been set to 60 Minutes, but this is often not sufficient to retrieve continuous range or charging updates.
These channels can be used to control the update behavior from openHAB, e.g. via rules.
- Channel Group ID is status
- Available for all vehicles (charging channel only for xEV)
- switches which can be triggered by a command
- if the switches are set to ON, then immediately they will be set to OFF again for being able to trigger the next update
| Channel ID | Type | Description | conv | phev | bev_rex | bev |
|-----------------|--------|----------------------------------------------------------------------------------------------------------|------|------|---------|-----|
| state-update | Switch | When set to ON, the state channels of the vehicle will be updated | X | X | X | X |
| charging-update | Switch | When set to ON, the charging statistics and charging sessions channels of the vehicle will be updated | | X | X | X |
| image-update | Switch | When set to ON, the image of the vehicle will be updated | X | X | X | X |
#### Vehicle Status
Reflects overall status of the vehicle.
@ -153,19 +173,19 @@ Reflects overall status of the vehicle.
- Available for all vehicles
- Read-only values
| Channel Label | Channel ID | Type | Description | conv | phev | bev_rex | bev |
|---------------------------|---------------------|---------------|------------------------------------------------|------|------|---------|-----|
| Overall Door Status | doors | String | Combined status for all doors | X | X | X | X |
| Overall Window Status | windows | String | Combined status for all windows | X | X | X | X |
| Doors Locked | lock | String | Status if vehicle is secured | X | X | X | X |
| Next Service Date | service-date | DateTime | Date of next upcoming service | X | X | X | X |
| Mileage till Next Service | service-mileage | Number:Length | Mileage till upcoming service | X | X | X | X |
| Check Control | check-control | String | Presence of active warning messages | X | X | X | X |
| Plug Connection Status | plug-connection | String | Plug is _Connected_ or _Not connected_ | | X | X | X |
| Charging Status | charge | String | Current charging status | | X | X | X |
| Remaining Charging Time | charge-remaining | Number:Time | Remaining time for current charging session | | X | X | X |
| Last Status Timestamp | last-update | DateTime | Date and time of last status update | X | X | X | X |
| Last Fetched Timestamp | last-fetched | DateTime | Date and time of last time status fetched | X | X | X | X |
| Channel ID | Type | Description | conv | phev | bev_rex | bev |
|---------------------|---------------|------------------------------------------------|------|------|---------|-----|
| doors | String | Combined status for all doors | X | X | X | X |
| windows | String | Combined status for all windows | X | X | X | X |
| lock | String | Status if vehicle is secured | X | X | X | X |
| service-date | DateTime | Date of next upcoming service | X | X | X | X |
| service-mileage | Number:Length | Mileage till upcoming service | X | X | X | X |
| check-control | String | Presence of active warning messages | X | X | X | X |
| plug-connection | String | Plug is _Connected_ or _Not connected_ | | X | X | X |
| charge | String | Current charging status | | X | X | X |
| charge-remaining | Number:Time | Remaining time for current charging session | | X | X | X |
| last-update | DateTime | Date and time of last status update | X | X | X | X |
| last-fetched | DateTime | Date and time of last time status fetched | X | X | X | X |
Overall Door Status values
@ -208,9 +228,9 @@ The _raw data channel_ is marked as _advanced_ and isn't shown by default.
Target are advanced users to derive even more data out of BMW API replies.
As the replies are formatted as JSON use the [JsonPath Transformation Service](https://www.openhab.org/addons/transformations/jsonpath/) to extract data for an item,
| Channel Label | Channel ID | Type | Description |
|---------------------------|---------------------|---------------|------------------------------------------------|
| Raw Data | raw | String | Unfiltered JSON String of vehicle data |
| Channel ID | Type | Description |
|---------------------|---------------|------------------------------------------------|
| raw | String | Unfiltered JSON String of vehicle data |
<img align="right" src="./doc/RawData.png" width="400" height="125"/>
@ -239,19 +259,19 @@ 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 | |
| Electric 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 | |
| Estimated Fuel Consumption l/100km | estimated-fuel-l-100km | Number | X | X | X | |
| Estimated Fuel Consumption mpg | estimated-fuel-mpg | Number | 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 ID | Type | Description | conv | phev | bev_rex | bev |
|----------------------------|----------------------|-----------------------------------------------|------|------|---------|-----|
| mileage | Number:Length | Current mileage of the vehicle | X | X | X | X |
| range-fuel | Number:Length | Fuel range | X | X | X | |
| range-electric | Number:Length | Electric range | | X | X | X |
| range-hybrid | Number:Length | Combined hybrid range | | X | X | |
| soc | Number:Dimensionless | State of charge | | X | X | X |
| remaining-fuel | Number:Volume | Remaining fuel in l | X | X | X | |
| estimated-fuel-l-100km | Number | Estimated fuel consumption in l | X | X | X | |
| estimated-fuel-mpg | Number | Estimated fuel consumption in mpg | X | X | X | |
| range-radius-fuel | Number:Length | The calculated range radius combustion | X | X | X | |
| range-radius-electric | Number:Length | The calculated range radius electric | | X | X | X |
| range-radius-hybrid | Number:Length | The calculated range radius hybrid combined | | X | X | |
#### Doors Details
@ -261,20 +281,20 @@ Detailed status of all doors and windows.
- Available for all vehicles if corresponding sensors are built-in
- Read-only values
| 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 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 |
| Channel ID | Type | Description |
|-------------------------|---------------|-----------------------------------------|
| driver-front | String | Status of front door driver's side |
| driver-rear | String | Status of rear door driver's side |
| passenger-front | String | Status of front door passenger's side |
| passenger-rear | String | Status of rear door passenger's side |
| trunk | String | Status of trunk |
| hood | String | Status of hood |
| win-driver-front | String | Status of front window driver's side |
| win-driver-rear | String | Status of rear window driver's side |
| win-passenger-front | String | Status of front window passenger's side |
| win-passenger-rear | String | Status of rear window passenger's side |
| win-rear | String | Status of rear window |
| sunroof | String | Status of sunroof |
Possible states
@ -293,11 +313,11 @@ If more than one message is active the channel _name_ contains all active messag
- Available for all vehicles
- Read/Write access
| Channel Label | Channel ID | Type | Access |
|---------------------------------|---------------------|----------------|------------|
| Check Control Description | name | String | Read/Write |
| Check Control Details | details | String | Read |
| Severity Level | severity | String | Read |
| Channel ID | Type | Access |
|---------------------|----------------|------------|
| name | String | Read/Write |
| details | String | Read |
| severity | String | Read |
Severity Levels
@ -314,12 +334,12 @@ If more than one service is scheduled in the future the channel _name_ contains
- Available for all vehicles
- Read/Write access
| Channel Label | Channel ID | Type | Access |
|--------------------------------|---------------------|----------------|------------|
| Service Name | name | String | Read/Write |
| Service Details | details | String | Read |
| Service Date | date | DateTime | Read |
| Mileage till Service | mileage | Number:Length | Read |
| Channel ID | Type | Access |
|---------------------|----------------|------------|
| name | String | Read/Write |
| details | String | Read |
| date | DateTime | Read |
| mileage | Number:Length | Read |
#### Location
@ -329,12 +349,12 @@ GPS location and heading of the vehicle.
- Available for all vehicles with built-in GPS sensor. Function can be enabled/disabled in the head unit
- Read-only values
| Channel Label | Channel ID | Type |
|---------------------|---------------------|---------------|
| GPS Coordinates | gps | Location |
| Heading | heading | Number:Angle |
| Address | address | String |
| Distance from Home | home-distance | Number:Length |
| Channel ID | Type | Description |
|---------------------|---------------|--------------------------------------------------------------|
| gps | Location | Current GPS coordinates of the vehicle |
| heading | Number:Angle | Current direction of the vehicle |
| address | String | Current address |
| home-distance | Number:Length | Calculated distance from configured home position of Openhab |
#### Remote Services
@ -347,10 +367,10 @@ Parallel execution isn't supported.
- Available for all commands mentioned in _Services Activated_. See [Vehicle Properties](#properties) for further details
- Read/Write access
| Channel Label | Channel ID | Type | Access |
|-------------------------|---------------------|---------|--------|
| Remote Service Command | command | String | Write |
| Service Execution State | state | String | Read |
| Channel ID | Type | Access |
|---------------------|---------|--------|
| command | String | Write |
| state | String | Read |
The channel _command_ provides options
@ -379,25 +399,25 @@ Charging options with date and time for preferred time windows and charging mode
- Read access for UI.
- There are 4 timers _T1, T2, T3 and T4_ available. Replace _X_ with number 1,2 or 3 to target the correct timer
| Channel Label | Channel ID | Type |
|----------------------------|---------------------------|----------|
| Charge Mode | mode | String |
| Charge Preferences | prefs | String |
| Charging Plan | control | String |
| SoC Target | target | String |
| Charging Energy Limited | limit | Switch |
| Window Start Time | window-start | DateTime |
| Window End Time | window-end | DateTime |
| A/C at Departure | climate | Switch |
| T_X_ Enabled | timer_X_-enabled | Switch |
| T_X_ Departure Time | timer_X_-departure | DateTime |
| T_X_ Monday | timer_X_-day-mon | Switch |
| T_X_ Tuesday | timer_X_-day-tue | Switch |
| T_X_ Wednesday | timer_X_-day-wed | Switch |
| T_X_ Thursday | timer_X_-day-thu | Switch |
| T_X_ Friday | timer_X_-day-fri | Switch |
| T_X_ Saturday | timer_X_-day-sat | Switch |
| T_X_ Sunday | timer_X_-day-sun | Switch |
| Channel ID | Type |
|---------------------------|----------|
| mode | String |
| prefs | String |
| control | String |
| target | String |
| limit | Switch |
| window-start | DateTime |
| window-end | DateTime |
| climate | Switch |
| timer_X_-enabled | Switch |
| timer_X_-departure | DateTime |
| timer_X_-day-mon | Switch |
| timer_X_-day-tue | Switch |
| timer_X_-day-wed | Switch |
| timer_X_-day-thu | Switch |
| timer_X_-day-fri | Switch |
| timer_X_-day-sat | Switch |
| timer_X_-day-sun | Switch |
The channel _profile-mode_ supports
@ -417,11 +437,11 @@ Shows charge statistics of the current month
- Available for electric and hybrid vehicles
- Read-only values
| Channel Label | Channel ID | Type |
|----------------------------|-------------------------|----------------|
| Charge Statistic Month | title | String |
| Energy Charged | energy | Number:Energy |
| Charge Sessions | sessions | Number |
| Channel ID | Type | Description |
|-------------------------|----------------|-------------------------|
| title | String | Title of the statistics |
| energy | Number:Energy | Consumed energy |
| sessions | Number | Number of sessions |
#### Charge Sessions
@ -432,13 +452,13 @@ If more than one message is active the channel _name_ contains all active messag
- Available for electric and hybrid vehicles
- Read-only values
| Channel Label | Channel ID | Type |
|---------------------------------|--------------|----------|
| Session Title | title | String |
| Session Details | subtitle | String |
| Charged Energy in Session | energy | String |
| Issues during Session | issue | String |
| Session Status | status | String |
| Channel ID | Type | Description |
|--------------|----------|-------------------------|
| title | String | Title of the session |
| subtitle | String | Subtitle of the session |
| energy | String | Consumed energy |
| issue | String | If an issue occurred |
| status | String | Status of the session |
#### Tire Pressure
@ -448,16 +468,16 @@ Current and target tire pressure values
- Available for all vehicles if corresponding sensors are built-in
- Read-only values
| Channel Label | Channel ID | Type |
|----------------------------|-------------------------|------------------|
| Front Left | fl-current | Number:Pressure |
| Front Left Target | fl-target | Number:Pressure |
| Front Right | fr-current | Number:Pressure |
| Front Right Target | fr-target | Number:Pressure |
| Rear Left | rl-current | Number:Pressure |
| Rear Left Target | rl-target | Number:Pressure |
| Rear Right | rr-current | Number:Pressure |
| Rear Right Target | rr-target | Number:Pressure |
| Channel ID | Type | Description |
|-------------------------|------------------|------------------------------|
| fl-current | Number:Pressure | Current pressure front left |
| fl-target | Number:Pressure | Target pressure front left |
| fr-current | Number:Pressure | Current pressure front right |
| fr-target | Number:Pressure | Target pressure front right |
| rl-current | Number:Pressure | Current pressure rear left |
| rl-target | Number:Pressure | Target pressure rear left |
| rr-current | Number:Pressure | Current pressure rear right |
| rr-target | Number:Pressure | Target pressure rear right |
#### Image
@ -467,10 +487,10 @@ Image representation of the vehicle.
- Available for all vehicles
- Read/Write access
| Channel Label | Channel ID | Type | Access |
|----------------------------|---------------------|--------|----------|
| Rendered Vehicle Image | png | Image | Read |
| Image Viewport | view | String | Write |
| Channel ID | Type | Access | Description |
|---------------------|--------|----------|---------------------------|
| png | Image | Read | The image as png |
| view | String | Write | The view port of the car |
Possible view ports:

View File

@ -58,7 +58,7 @@ public interface MyBMWConstants {
static final int DEFAULT_IMAGE_SIZE_PX = 1024;
static final int DEFAULT_REFRESH_INTERVAL_MINUTES = 5;
static final int DEFAULT_REFRESH_INTERVAL_MINUTES = 60;
// See constants from bimmer-connected
// https://github.com/bimmerconnected/bimmer_connected/blob/master/bimmer_connected/vehicle.py
@ -107,6 +107,7 @@ public interface MyBMWConstants {
THING_TYPE_PHEV, THING_TYPE_BEV_REX, THING_TYPE_BEV);
// Thing Group definitions
static final String CHANNEL_GROUP_UPDATE = "update";
static final String CHANNEL_GROUP_STATUS = "status";
static final String CHANNEL_GROUP_SERVICE = "service";
static final String CHANNEL_GROUP_CHECK_CONTROL = "check";
@ -120,6 +121,11 @@ public interface MyBMWConstants {
static final String CHANNEL_GROUP_TIRES = "tires";
static final String CHANNEL_GROUP_VEHICLE_IMAGE = "image";
// types of updates
static final String STATE_UPDATE = "state-update";
static final String CHARGING_UPDATE = "charging-update";
static final String IMAGE_UPDATE = "image-update";
// Charge Statistics & Sessions
static final String SESSIONS = "sessions";
static final String ENERGY = "energy";

View File

@ -87,7 +87,7 @@ public class RemoteServiceExecutor {
ExecutionState.TIMEOUT.name().toLowerCase());
reset();
// immediately refresh data
handler.getData();
handler.updateData();
} else {
counter++;
try {

View File

@ -24,6 +24,7 @@ import static org.openhab.binding.mybmw.internal.MyBMWConstants.CHANNEL_GROUP_RE
import static org.openhab.binding.mybmw.internal.MyBMWConstants.CHANNEL_GROUP_SERVICE;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.CHANNEL_GROUP_STATUS;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.CHANNEL_GROUP_TIRES;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.CHANNEL_GROUP_UPDATE;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.CHANNEL_GROUP_VEHICLE_IMAGE;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.CHARGE_ENABLED;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.CHARGE_PROFILE_CLIMATE;
@ -34,6 +35,7 @@ import static org.openhab.binding.mybmw.internal.MyBMWConstants.CHARGE_PROFILE_P
import static org.openhab.binding.mybmw.internal.MyBMWConstants.CHARGE_PROFILE_TARGET;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.CHARGE_REMAINING;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.CHARGE_STATUS;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.CHARGING_UPDATE;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.CHECK_CONTROL;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.DATE;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.DETAILS;
@ -54,6 +56,7 @@ import static org.openhab.binding.mybmw.internal.MyBMWConstants.HEADING;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.HOME_DISTANCE;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.HOOD;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.IMAGE_FORMAT;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.IMAGE_UPDATE;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.IMAGE_VIEWPORT;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.ISSUE;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.LAST_FETCHED;
@ -81,6 +84,7 @@ import static org.openhab.binding.mybmw.internal.MyBMWConstants.SERVICE_MILEAGE;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.SESSIONS;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.SEVERITY;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.SOC;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.STATE_UPDATE;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.STATUS;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.SUBTITLE;
import static org.openhab.binding.mybmw.internal.MyBMWConstants.SUNROOF;
@ -207,6 +211,8 @@ public class VehicleHandler extends BaseThingHandler {
private ImageProperties imageProperties = new ImageProperties();
private ThingStatus currentStatus = ThingStatus.UNKNOWN;
public VehicleHandler(Thing thing, MyBMWCommandOptionProvider commandOptionProvider,
LocationProvider locationProvider, TimeZoneProvider timeZoneProvider, String driveTrain) {
super(thing);
@ -237,7 +243,8 @@ public class VehicleHandler extends BaseThingHandler {
@Override
public void initialize() {
logger.trace("VehicleHandler.initialize");
updateStatus(ThingStatus.UNKNOWN);
currentStatus = ThingStatus.UNKNOWN;
updateStatus(currentStatus);
vehicleConfiguration = Optional.of(getConfigAs(MyBMWVehicleConfiguration.class));
Bridge bridge = getBridge();
@ -257,20 +264,26 @@ public class VehicleHandler extends BaseThingHandler {
updateChannel(CHANNEL_GROUP_VEHICLE_IMAGE, IMAGE_VIEWPORT, Converter.toTitleCase(imageProperties.viewport),
null);
// start update schedule
startSchedule(vehicleConfiguration.get().getRefreshInterval());
}
private void startSchedule(int interval) {
logger.trace("VehicleHandler.startSchedule");
refreshJob.ifPresentOrElse(job -> {
if (job.isCancelled()) {
// start update schedule only if the refreshInterval is not 0
if (interval > 0) {
logger.info("VehicleHandler.startSchedule with interval {}min", interval);
refreshJob.ifPresentOrElse(job -> {
if (job.isCancelled()) {
refreshJob = Optional
.of(scheduler.scheduleWithFixedDelay(this::updateData, 0, interval, TimeUnit.MINUTES));
} // else - scheduler is already running!
}, () -> {
refreshJob = Optional
.of(scheduler.scheduleWithFixedDelay(this::getData, 0, interval, TimeUnit.MINUTES));
} // else - scheduler is already running!
}, () -> {
refreshJob = Optional.of(scheduler.scheduleWithFixedDelay(this::getData, 0, interval, TimeUnit.MINUTES));
});
.of(scheduler.scheduleWithFixedDelay(this::updateData, 0, interval, TimeUnit.MINUTES));
});
} else {
logger.info("VehicleHandler initialize: don't start schedule as interval is 0");
updateData();
}
}
@Override
@ -281,25 +294,44 @@ public class VehicleHandler extends BaseThingHandler {
remote.ifPresent(RemoteServiceExecutor::cancel);
}
public void getData() {
logger.trace("VehicleHandler.getData");
/**
* update all data
*/
void updateData() {
logger.trace("VehicleHandler.updateData");
updateVehicleStatus();
if (isElectric) {
updateCharging();
}
updateImage();
}
private void updateVehicleStatus() {
proxy.ifPresentOrElse(prox -> {
vehicleConfiguration.ifPresentOrElse(config -> {
boolean stateError = false;
try {
VehicleStateContainer vehicleState = prox.requestVehicleState(config.getVin(),
config.getVehicleBrand());
triggerVehicleStatusUpdate(vehicleState, null);
stateError = false;
currentStatus = ThingStatus.ONLINE;
updateStatus(currentStatus);
} catch (NetworkException e) {
logger.debug("{}", e.toString());
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
"Vehicle State Update failed");
stateError = true;
currentStatus = ThingStatus.OFFLINE;
updateStatus(currentStatus, ThingStatusDetail.COMMUNICATION_ERROR, "Vehicle State Update failed");
}
}, () -> {
logger.warn("MyBMW Vehicle Configuration isn't present");
});
}, () -> {
logger.warn("MyBMWProxy isn't present");
});
}
if (!stateError && isElectric) {
private void updateCharging() {
proxy.ifPresentOrElse(prox -> {
vehicleConfiguration.ifPresentOrElse(config -> {
if (isElectric && ThingStatus.ONLINE.equals(currentStatus)) {
try {
updateChargingStatistics(
prox.requestChargeStatistics(config.getVin(), config.getVehicleBrand()), null);
@ -309,7 +341,19 @@ public class VehicleHandler extends BaseThingHandler {
logger.debug("{}", e.toString());
}
}
if (!stateError && !imageCache.isPresent() && !imageProperties.failLimitReached()) {
}, () -> {
logger.warn("MyBMW Vehicle Configuration isn't present");
});
}, () -> {
logger.warn("MyBMWProxy isn't present");
});
}
private void updateImage() {
proxy.ifPresentOrElse(prox -> {
vehicleConfiguration.ifPresentOrElse(config -> {
if (!imageCache.isPresent() && !imageProperties.failLimitReached()
&& ThingStatus.ONLINE.equals(currentStatus)) {
try {
updateImage(prox.requestImage(config.getVin(), config.getVehicleBrand(), imageProperties));
} catch (NetworkException e) {
@ -334,8 +378,6 @@ public class VehicleHandler extends BaseThingHandler {
if (isElectric) {
updateChargingProfile(vehicleState.getState().getChargingProfile(), channelToBeUpdated);
}
updateStatus(ThingStatus.ONLINE);
} else {
logger.debug("configuration not present");
}
@ -951,6 +993,23 @@ public class VehicleHandler extends BaseThingHandler {
logger.debug("Cannot handle command {}, channel {} in group {} not a command channel",
command.toFullString(), channelUID.getAsString(), group);
}
} else if (command instanceof OnOffType) {
if (CHANNEL_GROUP_UPDATE.equals(group) && OnOffType.ON.equals(command)) {
// triggering the update of the respective channel
switch (channelUID.getIdWithoutGroup()) {
case STATE_UPDATE:
updateVehicleStatus();
break;
case CHARGING_UPDATE:
updateCharging();
break;
case IMAGE_UPDATE:
updateImage();
break;
default:
break;
}
}
}
}

View File

@ -9,7 +9,7 @@
<label>Vehicle Identification Number (VIN)</label>
<description>Unique VIN given by BMW</description>
</parameter>
<parameter name="refreshInterval" type="integer" min="1" unit="min" required="true">
<parameter name="refreshInterval" type="integer" min="0" unit="min" required="true">
<label>Refresh Interval</label>
<description>Data refresh rate for your vehicle data</description>
<default>5</default>

View File

@ -16,7 +16,7 @@ thing-type.config.mybmw.bridge.region.option.ROW = Rest of the World
thing-type.config.mybmw.bridge.userName.description = MyBMW Username
thing-type.config.mybmw.bridge.userName.label = Username
thing-type.config.mybmw.vehicle.refreshInterval.description = Data refresh rate for your vehicle data
thing-type.config.mybmw.vehicle.refreshInterval.description = Data refresh rate for your vehicle data. If set to 0 no refresh will be triggered automatically.
thing-type.config.mybmw.vehicle.refreshInterval.label = Refresh Interval
thing-type.config.mybmw.vehicle.vehicleBrand.description = Vehicle brand like BMW or Mini
thing-type.config.mybmw.vehicle.vehicleBrand.label = Brand of the Vehicle
@ -46,6 +46,8 @@ channel-group-type.mybmw.ev-range-values.description = Provides Mileage, remaini
channel-group-type.mybmw.ev-range-values.label = Range and Charge Data
channel-group-type.mybmw.ev-vehicle-status.description = Overall vehicle status
channel-group-type.mybmw.ev-vehicle-status.label = Vehicle Status
channel-group-type.mybmw.ev-vehicle-update.description = Force the update of the vehicle data
channel-group-type.mybmw.ev-vehicle-update.label = Force Vehicle Update
channel-group-type.mybmw.hybrid-range-values.description = Provides mileage, remaining fuel and range data for hybrid vehicles
channel-group-type.mybmw.hybrid-range-values.label = Range, Charge / Fuel Data
channel-group-type.mybmw.image-values.description = Provides an image of your vehicle
@ -65,12 +67,16 @@ channel-group-type.mybmw.tire-pressures.description = Current and wanted pressur
channel-group-type.mybmw.tire-pressures.label = Tire Pressure
channel-group-type.mybmw.vehicle-status.description = Overall vehicle status
channel-group-type.mybmw.vehicle-status.label = Vehicle Status
channel-group-type.mybmw.vehicle-update.description = Force the update of the vehicle data
channel-group-type.mybmw.vehicle-update.label = Force Vehicle Update
# channel types
channel-type.mybmw.address-channel.label = Address
channel-type.mybmw.charging-info-channel.label = Charging Information
channel-type.mybmw.charging-remaining-channel.label = Remaining Charging Time
channel-type.mybmw.charging-status-channel.label = Charging Status
channel-type.mybmw.charging-update-channel.label = Force update of the charging data
channel-type.mybmw.check-control-channel.label = Check Control
channel-type.mybmw.checkcontrol-details-channel.label = CheckControl Details
channel-type.mybmw.checkcontrol-name-channel.label = CheckControl Description
@ -91,6 +97,7 @@ channel-type.mybmw.home-distance-channel.description = Computed distance between
channel-type.mybmw.home-distance-channel.label = Distance From Home
channel-type.mybmw.hood-channel.label = Hood
channel-type.mybmw.image-update-channel.label = Force update of the image
channel-type.mybmw.image-view-channel.command.option.FrontLeft = Left Side View
channel-type.mybmw.image-view-channel.command.option.FrontRight = Right Side View
channel-type.mybmw.image-view-channel.command.option.FrontView = Front View
@ -161,6 +168,7 @@ channel-type.mybmw.session-subtitle-channel.label = Session Details
channel-type.mybmw.session-title-channel.label = Session Title
channel-type.mybmw.soc-channel.label = Battery Charge Level
channel-type.mybmw.state-update-channel.label = Force update of the vehicle state data
channel-type.mybmw.statistic-energy-channel.description = Total energy charged in current month
channel-type.mybmw.statistic-energy-channel.label = Energy Charged
channel-type.mybmw.statistic-sessions-channel.description = Number of charging sessions this month

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="mybmw"
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">
<channel-group-type id="ev-vehicle-update">
<label>Vehicle Update</label>
<description>Triggering the vehicle update</description>
<channels>
<channel id="state-update" typeId="state-update-channel"/>
<channel id="charging-update" typeId="charging-update-channel"/>
<channel id="image-update" typeId="image-update-channel"/>
</channels>
</channel-group-type>
</thing:thing-descriptions>

View File

@ -13,6 +13,7 @@
<description>Battery Electric Vehicle (BEV)</description>
<channel-groups>
<channel-group id="update" typeId="ev-vehicle-update"/>
<channel-group id="status" typeId="ev-vehicle-status"/>
<channel-group id="doors" typeId="door-values"/>
<channel-group id="range" typeId="ev-range-values"/>
@ -28,7 +29,7 @@
</channel-groups>
<properties>
<property name="thingTypeVersion">1</property>
<property name="thingTypeVersion">2</property>
</properties>
<representation-property>vin</representation-property>

View File

@ -13,6 +13,7 @@
<description>Battery Electric Vehicle with Range Extender (BEV_REX)</description>
<channel-groups>
<channel-group id="update" typeId="ev-vehicle-update"/>
<channel-group id="status" typeId="ev-vehicle-status"/>
<channel-group id="doors" typeId="door-values"/>
<channel-group id="range" typeId="hybrid-range-values"/>
@ -28,7 +29,7 @@
</channel-groups>
<properties>
<property name="thingTypeVersion">1</property>
<property name="thingTypeVersion">2</property>
</properties>
<representation-property>vin</representation-property>

View File

@ -13,6 +13,7 @@
<description>Conventional Fuel Vehicle (CONV)</description>
<channel-groups>
<channel-group id="update" typeId="vehicle-update"/>
<channel-group id="status" typeId="vehicle-status"/>
<channel-group id="doors" typeId="door-values"/>
<channel-group id="range" typeId="conv-range-values"/>
@ -25,7 +26,7 @@
</channel-groups>
<properties>
<property name="thingTypeVersion">1</property>
<property name="thingTypeVersion">2</property>
</properties>
<representation-property>vin</representation-property>

View File

@ -13,6 +13,7 @@
<description>Conventional Fuel Vehicle with supporting Electric Engine (PHEV)</description>
<channel-groups>
<channel-group id="update" typeId="ev-vehicle-update"/>
<channel-group id="status" typeId="ev-vehicle-status"/>
<channel-group id="doors" typeId="door-values"/>
<channel-group id="range" typeId="hybrid-range-values"/>
@ -28,7 +29,7 @@
</channel-groups>
<properties>
<property name="thingTypeVersion">1</property>
<property name="thingTypeVersion">2</property>
</properties>
<representation-property>vin</representation-property>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="mybmw"
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">
<channel-type id="state-update-channel">
<item-type>Switch</item-type>
<label>trigger the update of the state</label>
<autoUpdatePolicy>veto</autoUpdatePolicy>
</channel-type>
<channel-type id="charging-update-channel">
<item-type>Switch</item-type>
<label>trigger the update of the charging information</label>
<autoUpdatePolicy>veto</autoUpdatePolicy>
</channel-type>
<channel-type id="image-update-channel">
<item-type>Switch</item-type>
<label>trigger the update of the image</label>
<autoUpdatePolicy>veto</autoUpdatePolicy>
</channel-type>
</thing:thing-descriptions>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="mybmw"
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">
<channel-group-type id="vehicle-update">
<label>Vehicle Update</label>
<description>Triggering the vehicle update</description>
<channels>
<channel id="state-update" typeId="state-update-channel"/>
<channel id="image-update" typeId="image-update-channel"/>
</channels>
</channel-group-type>
</thing:thing-descriptions>

View File

@ -27,6 +27,23 @@
</add-channel>
<!-- channels to be updated -->
</instruction-set>
<instruction-set targetVersion="2">
<!-- channels to be removed -->
<!-- channels to be added -->
<add-channel id="state-update" groupIds="update">
<type>mybmw:state-update-channel</type>
<label>Force state update channel</label>
</add-channel>
<add-channel id="charging-update" groupIds="update">
<type>mybmw:charging-update-channel</type>
<label>Force charging update channel</label>
</add-channel>
<add-channel id="image-update" groupIds="update">
<type>mybmw:image-update-channel</type>
<label>Force image update channel</label>
</add-channel>
<!-- channels to be updated -->
</instruction-set>
</thing-type>
<thing-type uid="mybmw:bev">
<instruction-set targetVersion="1">
@ -44,6 +61,23 @@
</add-channel>
<!-- channels to be updated -->
</instruction-set>
<instruction-set targetVersion="2">
<!-- channels to be removed -->
<!-- channels to be added -->
<add-channel id="state-update" groupIds="update">
<type>mybmw:state-update-channel</type>
<label>Force state update channel</label>
</add-channel>
<add-channel id="charging-update" groupIds="update">
<type>mybmw:charging-update-channel</type>
<label>Force charging update channel</label>
</add-channel>
<add-channel id="image-update" groupIds="update">
<type>mybmw:image-update-channel</type>
<label>Force image update channel</label>
</add-channel>
<!-- channels to be updated -->
</instruction-set>
</thing-type>
<thing-type uid="mybmw:conv">
<instruction-set targetVersion="1">
@ -63,6 +97,19 @@
</add-channel>
<!-- channels to be updated -->
</instruction-set>
<instruction-set targetVersion="2">
<!-- channels to be removed -->
<!-- channels to be added -->
<add-channel id="state-update" groupIds="update">
<type>mybmw:state-update-channel</type>
<label>Force state update channel</label>
</add-channel>
<add-channel id="image-update" groupIds="update">
<type>mybmw:image-update-channel</type>
<label>Force image update channel</label>
</add-channel>
<!-- channels to be updated -->
</instruction-set>
</thing-type>
<thing-type uid="mybmw:phev">
<instruction-set targetVersion="1">
@ -88,6 +135,23 @@
</add-channel>
<!-- channels to be updated -->
</instruction-set>
<instruction-set targetVersion="2">
<!-- channels to be removed -->
<!-- channels to be added -->
<add-channel id="state-update" groupIds="update">
<type>mybmw:state-update-channel</type>
<label>Force state update channel</label>
</add-channel>
<add-channel id="charging-update" groupIds="update">
<type>mybmw:charging-update-channel</type>
<label>Force charging update channel</label>
</add-channel>
<add-channel id="image-update" groupIds="update">
<type>mybmw:image-update-channel</type>
<label>Force image update channel</label>
</add-channel>
<!-- channels to be updated -->
</instruction-set>
</thing-type>
</update:update-descriptions>

View File

@ -0,0 +1,14 @@
{
"chargingSessions": {
"total": "0 kWh",
"numberOfSessions": "0",
"emptyStateDescription": "Laden Sie Ihren BMW und verfolgen Sie Ihre Ladehistorie.\nLadevorgänge werden ab dem Aktivierungszeitpunkt gespeichert, d. h. ab dem 27.07.2020.",
"chargingListState": "CHARGE_AND_TRACK",
"costsGroupedByCurrency": []
},
"datePicker": {
"startDate": "2020-07-27T00:00:00Z",
"selectedDate": "2023-01-19T20:53:52Z",
"endDate": "2023-01-19T20:53:53Z"
}
}

View File

@ -0,0 +1,8 @@
{
"description": "Laden Sie Ihren BMW und verfolgen Sie Ihre Ladehistorie. Ladevorgänge werden ab dem Aktivierungszeitpunkt gespeichert, d. h. ab dem 27.07.2020.",
"optStateType": "OPT_IN_WITHOUT_SESSIONS",
"statistics": {
"totalEnergyCharged": 0,
"numberOfChargingSessions": 0
}
}

View File

@ -0,0 +1,48 @@
[
{
"vin": "anonymousBEV3",
"mappingInfo": {
"isAssociated": true,
"isLmmEnabled": false,
"mappingStatus": "CONFIRMED",
"isPrimaryUser": true
},
"appVehicleType": "CONNECTED",
"attributes": {
"lastFetched": "2023-01-21T18: 57: 39.114Z",
"model": "iX3 M Sport",
"year": 2022,
"color": 4280231501,
"brand": "BMW",
"driveTrain": "ELECTRIC",
"headUnitType": "MGU",
"headUnitRaw": "HU_MGU",
"hmiVersion": "ID7",
"softwareVersionCurrent": {
"puStep": {
"month": 3,
"year": 22
},
"iStep": 552,
"seriesCluster": "S15C"
},
"softwareVersionExFactory": {
"puStep": {
"month": 11,
"year": 21
},
"iStep": 564,
"seriesCluster": "S15C"
},
"telematicsUnit": "ATM2",
"bodyType": "G08",
"countryOfOrigin": "AT",
"driverGuideInfo": {
"androidAppScheme": "com.bmwgroup.driversguide.row",
"iosAppScheme": "bmwdriversguide: ///open",
"androidStoreUrl": "https://play.google.com/store/apps/details?id=com.bmwgroup.driversguide.row",
"iosStoreUrl": "https://apps.apple.com/de/app/id714042749?mt=8"
}
}
}
]

View File

@ -0,0 +1,14 @@
{
"chargingSessions": {
"total": "0 kWh",
"numberOfSessions": "0",
"emptyStateDescription": "Laden Sie Ihren BMW und verfolgen Sie Ihre Ladehistorie.\nLadevorgänge werden ab dem Aktivierungszeitpunkt gespeichert, d. h. ab dem 27.07.2020.",
"chargingListState": "CHARGE_AND_TRACK",
"costsGroupedByCurrency": []
},
"datePicker": {
"startDate": "2020-07-27T00:00:00Z",
"selectedDate": "2023-01-19T20:53:52Z",
"endDate": "2023-01-19T20:53:53Z"
}
}

View File

@ -0,0 +1,8 @@
{
"description": "Laden Sie Ihren BMW und verfolgen Sie Ihre Ladehistorie. Ladevorgänge werden ab dem Aktivierungszeitpunkt gespeichert, d. h. ab dem 27.07.2020.",
"optStateType": "OPT_IN_WITHOUT_SESSIONS",
"statistics": {
"totalEnergyCharged": 0,
"numberOfChargingSessions": 0
}
}

View File

@ -0,0 +1,14 @@
{
"chargingSessions": {
"total": "0 kWh",
"numberOfSessions": "0",
"emptyStateDescription": "Laden Sie Ihren BMW und verfolgen Sie Ihre Ladehistorie.\nLadevorgänge werden ab dem Aktivierungszeitpunkt gespeichert, d. h. ab dem 27.07.2020.",
"chargingListState": "CHARGE_AND_TRACK",
"costsGroupedByCurrency": []
},
"datePicker": {
"startDate": "2020-07-27T00:00:00Z",
"selectedDate": "2023-01-19T20:53:52Z",
"endDate": "2023-01-19T20:53:53Z"
}
}

View File

@ -0,0 +1,8 @@
{
"description": "Laden Sie Ihren BMW und verfolgen Sie Ihre Ladehistorie. Ladevorgänge werden ab dem Aktivierungszeitpunkt gespeichert, d. h. ab dem 27.07.2020.",
"optStateType": "OPT_IN_WITHOUT_SESSIONS",
"statistics": {
"totalEnergyCharged": 0,
"numberOfChargingSessions": 0
}
}

View File

@ -0,0 +1,14 @@
{
"chargingSessions": {
"total": "0 kWh",
"numberOfSessions": "0",
"emptyStateDescription": "Laden Sie Ihren BMW und verfolgen Sie Ihre Ladehistorie.\nLadevorgänge werden ab dem Aktivierungszeitpunkt gespeichert, d. h. ab dem 27.07.2020.",
"chargingListState": "CHARGE_AND_TRACK",
"costsGroupedByCurrency": []
},
"datePicker": {
"startDate": "2020-07-27T00:00:00Z",
"selectedDate": "2023-01-19T20:53:52Z",
"endDate": "2023-01-19T20:53:53Z"
}
}

View File

@ -0,0 +1,8 @@
{
"description": "Laden Sie Ihren BMW und verfolgen Sie Ihre Ladehistorie. Ladevorgänge werden ab dem Aktivierungszeitpunkt gespeichert, d. h. ab dem 27.07.2020.",
"optStateType": "OPT_IN_WITHOUT_SESSIONS",
"statistics": {
"totalEnergyCharged": 0,
"numberOfChargingSessions": 0
}
}