diff --git a/bundles/org.openhab.binding.mybmw/README.md b/bundles/org.openhab.binding.mybmw/README.md index 5fc23608476..c1c1c30e912 100644 --- a/bundles/org.openhab.binding.mybmw/README.md +++ b/bundles/org.openhab.binding.mybmw/README.md @@ -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 | @@ -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: diff --git a/bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/MyBMWConstants.java b/bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/MyBMWConstants.java index 9c5945f7ea2..33664482b4e 100644 --- a/bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/MyBMWConstants.java +++ b/bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/MyBMWConstants.java @@ -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"; diff --git a/bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/handler/RemoteServiceExecutor.java b/bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/handler/RemoteServiceExecutor.java index 514af0a8de4..90589a9e3ae 100644 --- a/bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/handler/RemoteServiceExecutor.java +++ b/bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/handler/RemoteServiceExecutor.java @@ -87,7 +87,7 @@ public class RemoteServiceExecutor { ExecutionState.TIMEOUT.name().toLowerCase()); reset(); // immediately refresh data - handler.getData(); + handler.updateData(); } else { counter++; try { diff --git a/bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/handler/VehicleHandler.java index 8bac40024a9..5caaa1468f1 100644 --- a/bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/handler/VehicleHandler.java @@ -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; + } + } } } diff --git a/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/config/thing-config.xml b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/config/thing-config.xml index 0b45eb09e64..fcd28b08acb 100644 --- a/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/config/thing-config.xml +++ b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/config/thing-config.xml @@ -9,7 +9,7 @@ Unique VIN given by BMW - + Data refresh rate for your vehicle data 5 diff --git a/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/i18n/mybmw.properties b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/i18n/mybmw.properties index efe4407fc34..e7409349577 100644 --- a/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/i18n/mybmw.properties +++ b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/i18n/mybmw.properties @@ -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 diff --git a/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/ev-vehicle-update-group.xml b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/ev-vehicle-update-group.xml new file mode 100644 index 00000000000..1d7548ca8ae --- /dev/null +++ b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/ev-vehicle-update-group.xml @@ -0,0 +1,15 @@ + + + + + Triggering the vehicle update + + + + + + + diff --git a/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/thing-bev.xml b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/thing-bev.xml index 79231853b02..2cc92d32946 100644 --- a/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/thing-bev.xml +++ b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/thing-bev.xml @@ -13,6 +13,7 @@ Battery Electric Vehicle (BEV) + @@ -28,7 +29,7 @@ - 1 + 2 vin diff --git a/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/thing-bev_rex.xml b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/thing-bev_rex.xml index 1053f4772b7..e21f6c54450 100644 --- a/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/thing-bev_rex.xml +++ b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/thing-bev_rex.xml @@ -13,6 +13,7 @@ Battery Electric Vehicle with Range Extender (BEV_REX) + @@ -28,7 +29,7 @@ - 1 + 2 vin diff --git a/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/thing-conv.xml b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/thing-conv.xml index 52117d02a7a..1808edd814a 100644 --- a/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/thing-conv.xml +++ b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/thing-conv.xml @@ -13,6 +13,7 @@ Conventional Fuel Vehicle (CONV) + @@ -25,7 +26,7 @@ - 1 + 2 vin diff --git a/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/thing-phev.xml b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/thing-phev.xml index 9777d60d467..8e2e0c1c946 100644 --- a/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/thing-phev.xml +++ b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/thing-phev.xml @@ -13,6 +13,7 @@ Conventional Fuel Vehicle with supporting Electric Engine (PHEV) + @@ -28,7 +29,7 @@ - 1 + 2 vin diff --git a/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/vehicle-update-channel-types.xml b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/vehicle-update-channel-types.xml new file mode 100644 index 00000000000..b081aa9988a --- /dev/null +++ b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/vehicle-update-channel-types.xml @@ -0,0 +1,21 @@ + + + + Switch + + veto + + + Switch + + veto + + + Switch + + veto + + diff --git a/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/vehicle-update-group.xml b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/vehicle-update-group.xml new file mode 100644 index 00000000000..dec8a3de501 --- /dev/null +++ b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/thing/vehicle-update-group.xml @@ -0,0 +1,14 @@ + + + + + Triggering the vehicle update + + + + + + diff --git a/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/update/thing-update.xml b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/update/thing-update.xml index d7b93817dda..1f7fb82c4d6 100644 --- a/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/update/thing-update.xml +++ b/bundles/org.openhab.binding.mybmw/src/main/resources/OH-INF/update/thing-update.xml @@ -27,6 +27,23 @@ + + + + + mybmw:state-update-channel + + + + mybmw:charging-update-channel + + + + mybmw:image-update-channel + + + + @@ -44,6 +61,23 @@ + + + + + mybmw:state-update-channel + + + + mybmw:charging-update-channel + + + + mybmw:image-update-channel + + + + @@ -63,6 +97,19 @@ + + + + + mybmw:state-update-channel + + + + mybmw:image-update-channel + + + + @@ -88,6 +135,23 @@ + + + + + mybmw:state-update-channel + + + + mybmw:charging-update-channel + + + + mybmw:image-update-channel + + + + diff --git a/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV2/charging_sessions.json b/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV2/charging_sessions.json new file mode 100644 index 00000000000..7c9790e9a21 --- /dev/null +++ b/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV2/charging_sessions.json @@ -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" + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV2/charging_statistics.json b/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV2/charging_statistics.json new file mode 100644 index 00000000000..67a6aaf0bed --- /dev/null +++ b/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV2/charging_statistics.json @@ -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 + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV2/vehicles_base.json b/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV2/vehicles_base.json new file mode 100644 index 00000000000..d4ddb4cd558 --- /dev/null +++ b/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV2/vehicles_base.json @@ -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" + } + } + } +] \ No newline at end of file diff --git a/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV4/charging_sessions.json b/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV4/charging_sessions.json new file mode 100644 index 00000000000..7c9790e9a21 --- /dev/null +++ b/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV4/charging_sessions.json @@ -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" + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV4/charging_statistics.json b/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV4/charging_statistics.json new file mode 100644 index 00000000000..67a6aaf0bed --- /dev/null +++ b/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV4/charging_statistics.json @@ -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 + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV5/charging_sessions.json b/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV5/charging_sessions.json new file mode 100644 index 00000000000..7c9790e9a21 --- /dev/null +++ b/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV5/charging_sessions.json @@ -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" + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV5/charging_statistics.json b/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV5/charging_statistics.json new file mode 100644 index 00000000000..67a6aaf0bed --- /dev/null +++ b/bundles/org.openhab.binding.mybmw/src/test/resources/responses/BEV5/charging_statistics.json @@ -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 + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.mybmw/src/test/resources/responses/PHEV/charging_sessions.json b/bundles/org.openhab.binding.mybmw/src/test/resources/responses/PHEV/charging_sessions.json new file mode 100644 index 00000000000..7c9790e9a21 --- /dev/null +++ b/bundles/org.openhab.binding.mybmw/src/test/resources/responses/PHEV/charging_sessions.json @@ -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" + } +} \ No newline at end of file diff --git a/bundles/org.openhab.binding.mybmw/src/test/resources/responses/PHEV/charging_statistics.json b/bundles/org.openhab.binding.mybmw/src/test/resources/responses/PHEV/charging_statistics.json new file mode 100644 index 00000000000..67a6aaf0bed --- /dev/null +++ b/bundles/org.openhab.binding.mybmw/src/test/resources/responses/PHEV/charging_statistics.json @@ -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 + } +} \ No newline at end of file