You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Magic SOC predicts battery drain during driving using real-time odometer distance and learned consumption rates. It provides a sub-integer SOC estimate that updates more frequently than BMW's native integer SOC. **Disabled by default** — enable via Settings.
-**Sensor**: `vehicle.magic_soc` per vehicle (BEV only; PHEVs get passthrough BMW SOC)
256
+
-**How it works**: Anchors on BMW's reported SOC at trip start, then subtracts `distance × learned_consumption / capacity` as the vehicle drives. Re-anchors when BMW sends a fresh SOC mid-drive — if the drift is < 0.5pp, keeps the sub-integer prediction for smoother display.
257
+
-**Consumption learning**: Uses EMA (Exponential Moving Average) with adaptive rate. Default 0.21 kWh/km globally, with per-model defaults (e.g. i4 eDrive40 = 0.18 kWh/km). Learns from completed trips where both SOC drop and distance are available. Requires at least 5 trips before the learning rate settles to 20%.
258
+
-**Trip detection**: Combines BMW's `isMoving` signal, GPS-derived motion, and odometer changes. Handles MQTT bursts and GPS gaps gracefully.
259
+
-**Capacity**: Uses live `maxEnergy` from BMW (reflects real degradation), falls back to `batterySizeMax`, then to per-model defaults.
260
+
-**Reset**: A "Reset Consumption Learning" button appears under Configuration entities for each BEV.
261
+
262
+
**Limitations**: This is experimental. Accuracy depends on BMW sending timely SOC and mileage data. Preheating, extended idle with accessories, and firmware glitches can cause temporary inaccuracy. PHEVs are excluded from prediction (hybrid powertrain makes distance-based estimation unreliable).
263
+
264
+
## Charging History (Optional)
265
+
266
+
The integration can fetch your BMW charging session history from the past 30 days. This is **disabled by default** to conserve your API quota.
267
+
268
+
-**Enable via**: Settings → Devices & Services → BMW CarData → Configure → Settings → Enable Charging History
269
+
-**API cost**: 1 call per vehicle per day (from your 50-call daily quota)
270
+
-**Sensor**: Creates a diagnostic sensor per vehicle showing session count and last charge date
271
+
-**Attributes**: Full session data including start/end SOC, energy consumed, duration, location, and cost information
272
+
-**Manual trigger**: Use `cardata.fetch_charging_history` service in Developer Tools
273
+
274
+
## Tyre Diagnosis (Optional)
275
+
276
+
The integration can fetch tyre health and wear data from BMW's Smart Maintenance system. This is **disabled by default** to conserve your API quota.
277
+
278
+
-**Enable via**: Settings → Devices & Services → BMW CarData → Configure → Settings → Enable Tyre Diagnosis
279
+
-**API cost**: 1 call per vehicle per day (from your 50-call daily quota)
280
+
-**Sensor**: Creates a diagnostic sensor per vehicle showing aggregate tyre status
281
+
-**Attributes**: Per-wheel data including dimension, wear, season, manufacturer, defect status, and production date
282
+
-**Manual trigger**: Use `cardata.fetch_tyre_diagnosis` service in Developer Tools
283
+
250
284
## Developer Tools Services
251
285
252
286
Home Assistant's Developer Tools expose helper services for manual API checks:
253
287
254
288
-`cardata.fetch_telematic_data` fetches the current contents of the configured telematics container for a VIN and logs the raw payload.
255
289
-`cardata.fetch_vehicle_mappings` calls `GET /customers/vehicles/mappings` and logs the mapping details (including PRIMARY or SECONDARY status). Only primary mappings return data; some vehicles do not support secondary users, in which case the mapped user is considered the primary one.
256
290
-`cardata.fetch_basic_data` calls `GET /customers/vehicles/{vin}/basicData` to retrieve static metadata (model name, series, etc.) for the specified VIN.
291
+
-`cardata.fetch_charging_history` fetches the last 30 days of charging sessions for a VIN. Uses 1 API call per vehicle.
292
+
-`cardata.fetch_tyre_diagnosis` fetches tyre health and wear data for a VIN. Uses 1 API call per vehicle.
257
293
-`migrations` call for proper renaming the sensors from old installations
258
294
259
295
## API Quota and MQTT Streaming
@@ -263,8 +299,9 @@ BMW imposes a **50 calls/day** limit on the CarData API. This integration does n
263
299
-**MQTT Stream (real-time)**: The MQTT stream is unlimited and provides real-time updates for events like door locks, motion state, charging power, etc. GPS coordinates are paired using BMW payload timestamps (same GPS fix detection) with an arrival-time fallback, so location updates work even when latitude and longitude arrive in separate MQTT messages. In direct BMW mode, token refresh during MQTT reconnection is lock-free to avoid blocking the connection, and the MQTT connection is proactively reconnected with fresh credentials to prevent session expiry (~1 hour).
264
300
-**Trip-end polling**: When a vehicle stops moving (trip ends), the integration triggers an immediate API poll to capture post-trip battery state. This ensures SOC is updated even when the MQTT stream only delivers GPS/mileage but not SOC (common on some models). A per-VIN 10-minute cooldown prevents GPS burst flapping from burning API quota.
265
301
-**Charge-end polling**: When charging completes or stops, the integration triggers an immediate API poll to get the actual BMW SOC for learning calibration of the predicted SOC sensor, subject to the same per-VIN cooldown.
266
-
-**Fallback polling**: The integration polls every 12 hours as a fallback in case MQTT stream fails or after Home Assistant restarts. VINs with fresh MQTT data are skipped individually, so in multi-car setups only stale VINs consume API calls.
267
-
-**Multi-VIN setups**: All vehicles share the same 50 call/day limit.
302
+
-**Fallback polling**: The integration polls periodically as a fallback in case MQTT stream fails or after Home Assistant restarts. VINs with fresh MQTT data are skipped individually, so in multi-car setups only stale VINs consume API calls.
303
+
-**Daily optional features**: When Charging History and/or Tyre Diagnosis are enabled, each adds 1 API call per vehicle per day. The polling interval automatically increases to compensate — e.g. with both features on 2 cars, polling stretches from 2h to 2.4h per VIN.
304
+
-**Multi-VIN setups**: All vehicles share the same 50 call/day limit. The poll interval scales with VIN count plus any enabled daily features. Each VIN is guaranteed at least 1 poll per day; BMW's 429 backoff handles actual quota enforcement.
268
305
-**Rate limiting**: If BMW returns a 429 (rate limited) response, the integration backs off automatically with exponential delay.
269
306
270
307
## Requirements
@@ -318,6 +355,7 @@ The integration is organized into focused modules:
318
355
|`stream_circuit_breaker.py`| Circuit breaker for reconnection rate limiting |
0 commit comments