# Automatisches Fahrtenbuch für BMW mit iDrive 6 – komplett in Home Assistant, ohne App und ohne Abo
Projekt: ein **vollautomatisches Fahrtenbuch für meinen BMW G31 (530d) mit iDrive 6**.
Jede Fahrt landet als eine Zeile in einem Google Sheet, ohne dass ich etwas tun muss:
- Datum, Start- und Endzeit, Fahrtdauer
- Start und Ziel mit **Straße, Hausnummer, PLZ, Ort** und Klarnamen wie „Home“ oder „Büro“
- Kilometerstand am Start und am Ende, gefahrene Kilometer
- Tankinhalt am Start und am Ende, Verbrauch in Litern und l/100 km
Ich brauche dafür keine BMW-App, keinen Fahrtenbuch-Dienst und kein Abo, nur Home Assistant, BMW CarData, ein iPhone und ein Google Sheet.
>
**Komplette Anleitung mit allen YAMLs, Helfern, iOS-Kurzbefehl und PDF:**
>
[GitHub: BMW-Fahrtenbuch für iDrive 6]( GitHub - ursubey/Home-Assistant-BMW-CarData-Logbook-iDrive6: Automatic driving logbook (Fahrtenbuch) for BMW iDrive 6 in Home Assistant: BMW CarData (BavarianData), iPhone Bluetooth webhook with start address, Google Sheets · GitHub )
Das klingt einfach. Mit einem iDrive-6-Auto war es das aber nicht. Unten beschreibe ich deshalb ausführlich, **warum** ich es so gebaut habe und in welche **Stolperfallen** ich unterwegs getreten bin.
—
## Das Grundproblem: iDrive 6 meldet nur am Fahrtende
Seit BMW die alte ConnectedDrive-Schnittstelle abgeschaltet hat, führt der offizielle Weg über **BMW CarData**: ein MQTT-Stream plus eine REST-API mit **50 Aufrufen pro Tag**.
Neuere BMW (iDrive 7/8 und Neue Klasse) liefern über den Stream laufend Daten, auch Positionen während der Fahrt. **Ein iDrive 6 macht das nicht.** Mein Auto schickt Kilometerstand, Tankinhalt und Position **nur einmal, am Ende einer Fahrt**. Während der Fahrt kommt nichts. Den Entriegelungsstatus der Türen streamt es überhaupt nicht.
Für ein Fahrtenbuch heißt das:
- Home Assistant weiß **nicht, wann** eine Fahrt beginnt.
- Home Assistant weiß **nicht, wo** sie beginnt.
- Es weiß nur: Irgendwann kommt ein neuer Kilometerstand mit einer neuen Position.
—
## Warum die Trip-Funktion von BavarianData hier nicht greift
[BavarianData]( GitHub - JustChr/BavarianData: BMW CarData for Home Assistant, in the HACS default store: live MQTT stream + REST API for your BMW or MINI, with charging history & cost, trip journal and battery health. The replacement for the Connected Drive / MyBMW integration. · GitHub ) von @JustChr hat eine eigene Fahrten-Erkennung, ein „Trip Journal“. Für neuere Autos ist das eine tolle Funktion. Laut Wiki setzt die Erkennung aber **Live-GPS aus dem Stream** voraus:
- Eine Fahrt beginnt, wenn Positionen eine Bewegung zeigen.
- Sie endet nach fünf Minuten Stillstand.
- Optional hilft der Status der Fahrertür.
Die Integration ist also für Fahrzeuge gebaut, die laufend Positionen streamen, **nicht für iDrive 6**. Bei meinem Auto kommt nur ein einziger Datenpunkt pro Fahrt an. Daraus kann keine Trip-Erkennung eine Fahrt rekonstruieren.
Das ist keine Kritik an der Integration, sondern eine Eigenschaft der älteren Fahrzeuge. Für die eigentlichen Werte (km, Tank, Position) nutze ich BavarianData trotzdem, und die sind sehr gut. Die Fahrtenlogik habe ich selbst gebaut.
—
## Warum BavarianData und nicht „BMW CarData“ (kvanbiesen)?
Es gibt zwei bekannte HACS-Integrationen für BMW CarData:
- [BMW CarData]( GitHub - kvanbiesen/bmw-cardata-ha: Use Free Cardata To Read BMW data in HA (EU only - For now) · GitHub ) von @kvanbiesen, hervorgegangen aus „BimmerData Streamline“
- [BavarianData]( GitHub - JustChr/BavarianData: BMW CarData for Home Assistant, in the HACS default store: live MQTT stream + REST API for your BMW or MINI, with charging history & cost, trip journal and battery health. The replacement for the Connected Drive / MyBMW integration. · GitHub ) von @JustChr
Ich hatte beide im Einsatz und sie verglichen. Am Ende habe ich mich für **BavarianData** entschieden:
1. **Genauere Werte bei meinem Auto.** Kilometerstand, Tankinhalt und Position am Fahrtende waren mit BavarianData bei mir zuverlässiger und stimmiger. Für ein Fahrtenbuch zählt genau das: Wenn der Kilometerstand nicht stimmt, ist die ganze Zeile wertlos.
2. **Nur ein Stream pro BMW-Konto.** BMW lässt pro Konto nur **eine** gleichzeitige MQTT-Verbindung zu. Steht eine zweite Integration (oder evcc, eine Bridge, …) mit derselben Client-ID daneben, bekommt man „Not authorized“, obwohl die Tokens gültig sind. Beide parallel laufen zu lassen geht also nicht. Man muss sich entscheiden, und ich habe mich für die genaueren Werte entschieden.
3. **Kein Fahrtenbuch in beiden.** „BMW CarData“ ist auf Live-Zustand und Akku-Prognosen ausgelegt und hat laut README keine Logbuch-Funktion. Die Trips von BavarianData helfen bei iDrive 6 nicht (siehe oben). Die Fahrtenbuch-Logik musste ich also so oder so selbst bauen.
Beide Projekte sind gut gepflegt und machen viel richtig. Bei anderen Modellen kann der Vergleich auch anders ausfallen. Probiert es mit eurem Auto aus, aber immer nur **eine** Integration gleichzeitig.
—
## Die Lösung: Start vom iPhone, Ende vom Auto
Weil das Auto den Fahrtbeginn nicht meldet, kommt er vom **iPhone**:
Ausgeschrieben:
```text
iPhone verbindet sich per Bluetooth mit dem BMW
→ iOS-Kurzbefehl (persönliche Automation)
1\. „Aktuellen Ort abrufen“
2\. Webhook an Home Assistant (über Nabu Casa) – mit Straße, PLZ, Ort
→ HA merkt sich: Startzeit, Startadresse, km-Stand, Tankinhalt, „Fahrt aktiv“
BMW beendet die Fahrt → CarData-Stream → BavarianData: neuer km-Stand, Tank, Position
→ Places-Integration macht daraus Straße/Hausnummer/PLZ/Ort
→ km-Stand 10 Minuten unverändert = Fahrt zu Ende
→ Skript schreibt eine Zeile in Google Sheets
```
Die **Startadresse** wird in dieser Reihenfolge bestimmt:
1. die Adresse, die der Kurzbefehl im Webhook mitschickt
2. der „Geocoded Location“-Sensor der HA-Companion-App, wenn er höchstens 5 Minuten alt ist
3. das Ziel der vorherigen Fahrt
4. die letzte Position des Autos
So entsteht auch dann eine sinnvolle Zeile, wenn das iPhone mal nicht mitspielt.
**Verwendete Komponenten:**
| Komponente | Wofür |
|—|—|
| [BavarianData]( GitHub - JustChr/BavarianData: BMW CarData for Home Assistant, in the HACS default store: live MQTT stream + REST API for your BMW or MINI, with charging history & cost, trip journal and battery health. The replacement for the Connected Drive / MyBMW integration. · GitHub ) (HACS) | km-Stand, Tankinhalt, Position aus dem CarData-Stream |
| [Places]( GitHub - custom-components/places: Component to integrate with OpenStreetMap Reverse Geocode (places) · GitHub ) (HACS) | Reverse Geocoding (OpenStreetMap) der Auto-Position |
| [Google Sheets]( Google Sheets - Home Assistant ) | `google_sheets.append_sheet`, eine Zeile pro Fahrt |
| iOS-Kurzbefehle | Bluetooth-Automation mit Webhook |
| Nabu Casa (oder andere externe URL) | Webhook aus dem Mobilfunknetz erreichbar |
| HA Companion App | nur als Fallback für die Startadresse |
Alle YAMLs (Helfer, Automation, Skript) und die Einrichtung des Kurzbefehls Schritt für Schritt stehen im [GitHub-Repo]( GitHub - ursubey/Home-Assistant-BMW-CarData-Logbook-iDrive6: Automatic driving logbook (Fahrtenbuch) for BMW iDrive 6 in Home Assistant: BMW CarData (BavarianData), iPhone Bluetooth webhook with start address, Google Sheets · GitHub ).
—
## Die Stolperfallen
Auf diesem Teil liegt der eigentliche Wert des Beitrags. Fast jeder Punkt hat mich mindestens eine Fahrt gekostet.
### BMW CarData und iDrive 6
**1. Die Türentriegelung taugt nicht als Startsignal.**
Meine erste Idee: Auto wird entriegelt, also beginnt eine Fahrt. Bei iDrive 6 bleibt der Status im Stream aber immer „secured“. Den Trigger und den Helfer habe ich wieder gelöscht.
**2. Daten kommen nur am Fahrtende, manchmal mit Verzögerung.**
Die Endzeit im Fahrtenbuch ist der Zeitpunkt, an dem das Auto den neuen km-Stand meldet. Das kann ein paar Minuten nach dem Abstellen sein. Deshalb gilt eine Fahrt erst als beendet, wenn der km-Stand **10 Minuten** stabil ist.
**3. 50 API-Aufrufe pro Tag.**
Nicht pollen. Der MQTT-Stream ist die Datenquelle, die API nur die Notreserve.
**4. Der Stream verbindet sich etwa alle 45 Minuten neu.**
Das sieht in der Diagnose wie ein Fehler aus, ist aber nur der Token-Refresh. Dabei gehen keine Daten verloren.
**5. Nur eine Stream-Verbindung pro BMW-Konto.**
Siehe oben: Zwei Integrationen, evcc oder eine Bridge gleichzeitig führen zu „Not authorized“.
### iPhone und Webhook
**6. Der Webhook geht manchmal verloren.**
Beim Wechsel von WLAN auf 5G und mit dauerhaft aktivem VPN scheitert der Kurzbefehl ab und zu. Lösung: Die Fahrt wird am Ende **trotzdem** eingetragen. Als Start gilt dann das Ziel der letzten Fahrt, markiert mit „(no start signal)“.
**7. Die Rückfahrt startet, bevor die Hinfahrt abgeschlossen ist.**
Klassiker: kurz zum Bäcker und wieder zurück. Der Webhook für die Rückfahrt kommt, während HA noch die 10 Minuten bis zum Ende der Hinfahrt abwartet. In der ersten Version wurde dieser Webhook verworfen, und die Rückfahrt hatte keinen Start. Jetzt gilt: Ist beim neuen Webhook noch eine Fahrt offen und der km-Stand gestiegen, wird die alte Fahrt **sofort** abgeschlossen, dann startet die neue.
**8. Doppelte Bluetooth-Ereignisse.**
Das iPhone verbindet sich manchmal zweimal kurz hintereinander. Ein zweiter Webhook innerhalb von 30 Minuten wird ignoriert.
**9. Die Webhook-URL muss `/api/webhook/` enthalten.**
Richtig ist `https:///api/webhook/`. Ohne `/api/webhook/` passiert einfach nichts. Außerdem braucht der Webhook-Trigger `local_only: false`, sonst kommt er aus dem Mobilfunknetz nicht an.
**10. Eine lange, zufällige Webhook-ID verwenden.**
Mit `local_only: false` kann **jeder**, der die ID kennt, Fahrten anlegen. `bmw_fahrt_start` errät man leicht, `openssl rand -hex 16` nicht.
**11. „Standort aktualisieren“ der HA-App funktioniert im Hintergrund nicht.**
Die Kurzbefehl-Aktion der Companion App läuft nur, wenn die App geöffnet ist. Aus einer Bluetooth-Automation heraus klappt sie nicht. Die Lösung ist die eingebaute Aktion **„Aktuellen Ort abrufen“** der Kurzbefehle-App selbst, mit Genauigkeit „Optimal“. Die braucht die HA-App gar nicht.
**12. Der Kurzbefehl schickt die ganze Adresse statt nur der Straße.**
Auch wenn man bei der Variable „Straße“ auswählt, kam bei mir oft die komplette Adresse an: `Musterstraße 12⏎12345 Musterstadt⏎Deutschland`. Außerdem war mir beim Schlüssel `plz` ein Leerzeichen hinten reingerutscht (`"plz "`). Die Automation ist deshalb tolerant: Sie nimmt die erste Zeile, trennt Straße und Hausnummer, holt PLZ und Ort notfalls aus der Adresse und ignoriert Leerzeichen und Groß-/Kleinschreibung in den Schlüsseln.
**13. Die Aktion im Kurzbefehl verschieben.**
„Aktuellen Ort abrufen“ muss **vor** dem Webhook stehen. Zum Verschieben den **Titel** der Aktion gedrückt halten, bis sie sich anhebt, dann ziehen.
### Adressen und Zonen
**14. iPhone und Auto verorten denselben Ort unterschiedlich.**
Mein Auto parkt etwa 20 m vom Haus entfernt. Das iPhone meldet die Hausadresse, Places/OpenStreetMap für das Auto die Nachbarstraße. Beides stimmt, sieht im Fahrtenbuch aber unterschiedlich aus. Der **Klarname** („Home“) kommt deshalb aus der Zone, die Adresse aus der jeweiligen Quelle.
**15. Überlappende Zonen.**
Ein Device Tracker bekommt den Namen der **kleinsten** Zone, in der er steht. Hat man um „Home“ herum eine größere Zone (bei mir „Wohngebiet“) und parkt am Rand, steht als Ziel plötzlich „Wohngebiet“ statt „Home“. Die Zonen also bewusst anlegen.
### Home Assistant
**16. Die Reihenfolge der `variables:` kann sich ändern.**
Beim Speichern über die UI bzw. die Config-API landen die Schlüssel eines `variables:`-Blocks bei mir **alphabetisch sortiert**. Hängt `b` von `a` ab und `a` steht danach weiter unten, ist `a` beim Rendern noch nicht definiert. Lösung: Abhängige Variablen in **mehrere aufeinanderfolgende `variables:`-Schritte** aufteilen.
**17. Kein `initial:` am `input_boolean`.**
Sonst ist „Fahrt aktiv“ nach jedem Neustart zurückgesetzt, und eine offene Fahrt geht verloren.
**18. Sicherheitsnetz für Google Sheets.**
Vor dem Schreiben ins Sheet erzeugt das Skript eine **persistente Benachrichtigung** mit allen Werten. Gelöscht wird sie erst, wenn die Zeile im Sheet steht. Scheitert der Sheets-Aufruf, ist die Fahrt nicht verloren.
### Google Sheets
**19. Die PLZ wird zum Datum.**
`append_sheet` übergibt die Werte so, als hätte man sie in die Tabelle eingetippt. Eine PLZ wie `12345` kann so zu einer Zahl oder einem Datum werden. Lösung: die PLZ mit vorangestelltem `'` schreiben.
**20. Die Spaltennamen müssen exakt passen.**
`append_sheet` ordnet die Werte über die **Überschriften** zu. Ein Leerzeichen zu viel in der Kopfzeile, und die Spalte bleibt leer.
**21. Verbrauch bei Kurzstrecken.**
Der Tankinhalt kommt in ganzen Litern. Auf 3 km ändert er sich nicht, also steht dort 0 l. Über einen Monat gerechnet passt der Verbrauch dann wieder.
—
## Testen ohne zu fahren
Den Kurzbefehl kann man in der Kurzbefehle-App mit **
︎** auch von Hand ausführen. Im Trace der Automation sieht man unter `wj`, was angekommen ist, und unter `w`, was daraus geworden ist. Danach `input_boolean.bmw_fahrt_aktiv` wieder ausschalten. Eine Zeile entsteht bei so einem Test nicht, weil sich der km-Stand nicht ändert.
—
## Fazit
Mit einem iDrive 6 bekommt man kein Fahrtenbuch „out of the box“. Die Kombination funktioniert aber zuverlässig:
- **BavarianData** für saubere Werte
- **iPhone-Bluetooth** als Startsignal mit Adresse
- eine eigene Fahrtenlogik mit mehreren Fallbacks
Seit dem Umbau landen alle Fahrten automatisch mit Start- und Zieladresse im Sheet, inklusive Hin- und Rückfahrt zum Bäcker innerhalb von 10 Minuten.
>
Das ist meine private Aufzeichnung. Ob so ein Fahrtenbuch steuerlich anerkannt wird (Stichwort Manipulationssicherheit), müsst ihr mit eurem Steuerberater klären.
Alles zum Nachbauen, anonymisiert und mit Platzhaltern:
Ein großes Dankeschön an **@JustChr** für [BavarianData]( GitHub - JustChr/BavarianData: BMW CarData for Home Assistant, in the HACS default store: live MQTT stream + REST API for your BMW or MINI, with charging history & cost, trip journal and battery health. The replacement for the Connected Drive / MyBMW integration. · GitHub ), an **@kvanbiesen** für [BMW CarData]( GitHub - kvanbiesen/bmw-cardata-ha: Use Free Cardata To Read BMW data in HA (EU only - For now) · GitHub ), die ich zum Vergleich getestet habe, und an die Macher von [Places]( GitHub - custom-components/places: Component to integrate with OpenStreetMap Reverse Geocode (places) · GitHub ).
Fragen, Ideen oder eure Erfahrungen mit anderen BMW-Modellen gerne hier im Thread. Mich interessiert besonders, ob jemand mit iDrive 7/8 die Trip-Funktion von BavarianData direkt als Fahrtenbuch nutzt.
Viele Grüße
Chris
