SmartHashtag nach 68 Releases

TLDR: Angefangen hat es mit dem Akkustand in Home Assistant. Heute hupt, lüftet und entriegelt SmartHashtag das Auto. Ein Blick zurück auf knapp drei Jahre und 68 Releases.

Anfang November habe ich Version 0.12.1 von SmartHashtag veröffentlicht. Das ist meine Home-Assistant-Integration für den Smart #1, #3 und inzwischen auch den #5. Es ist das 68. Release, und das erste Commit ist noch keine drei Jahre alt. Zeit, einmal zurückzuschauen, wie das Projekt dahin gekommen ist.

Zeitstrahl von SmartHashtag von Januar 2024 bis November 2026 mit 68 Release-Tags und elf Meilensteinen
Alle 68 Release-Tags von SmartHashtag auf einer Linie, dazu die wichtigsten Meilensteine aus Integration und Bibliothek.

Ein Leerzeichen zu viel

Angefangen hat alles nicht in Home Assistant, sondern mit der Bibliothek pySmartHashtag. Das Repository habe ich am 17. Januar 2024 angelegt. Der Name kommt von den Autos selbst: Smart nennt seine Modelle #1, #3 und #5, also Hashtag. Eine offizielle Schnittstelle gibt es nicht, nur die Cloud hinter der Smart-App. Als Vorlage hatte ich eine funktionierende Umsetzung in JavaScript, die zumindest einen Login nachspielen konnte.

Die Commit-Nachrichten aus diesen Tagen lesen sich wie ein Tagebuch. Am 18. Januar klappt der Login, aber die API antwortet mit „The access token is invalid“. Kurz danach kommt „The inspection date has expired“, immerhin eine neue Fehlermeldung. Am 19. Januar steht „fix the timestamp and now it works!“ im Log, am 22. Januar wieder „still getting access token invalid“.

Am Abend des 23. Januar hatte ich dann die beiden Ursachen gefunden. Die erste war ein Leerzeichen. Jede Anfrage an die Cloud wird über den Body signiert, und Python schreibt mit json.dumps nach jedem Doppelpunkt ein Leerzeichen, JavaScript mit JSON.stringify nicht. Erst als der Body Zeichen für Zeichen so aussah wie bei der Vorlage, hat die Cloud den Token angenommen. Die zweite war die Auth-Funktion im httpx-Client, die sich in den Login eingemischt hat. Um 22:36 Uhr steht dann „Get all vehicle information“ im Log.

125 Commits im Februar

Am 4. Februar 2024 kam das erste Commit für die Integration, einen Tag später war v0.1.0 draußen. Devcontainer, Linting und Release-Drafter waren von Anfang an dabei. Im Februar kamen 125 Commits zusammen: mehrere Autos in einem Konto mit Auswahl über die VIN, die Anmeldemaske auf Deutsch und Englisch, die 12-V-Batterie, Fahrdaten, das Auto als Device Tracker auf der Karte und ein erster Versuch, die Klimaanlage aus Home Assistant zu starten.

Außerdem passt die Integration seitdem ihr Abfrageintervall an: Beim Laden und während der Fahrt fragt sie öfter nach als im Stand. Dieses Prinzip gibt es bis heute, und es hat mir noch vor ein paar Tagen Arbeit gemacht. Dazu weiter unten mehr.

Was im Alltag fehlt

Der Rest von 2024 war Alltag: Issues lesen, Einheiten korrigieren, fehlende Werte nachziehen. Das Vorklimatisieren hat erst im Juli richtig funktioniert. Seit v0.4.0 Ende Juli landen Kilometerstand und Tageszähler in der Langzeitstatistik von Home Assistant. Im August kam DC-Laden dazu, bei dem die Cloud andere Werte liefert als beim Laden an der Wallbox. Kurz vor Weihnachten folgte v0.6.0 mit Sitz- und Lenkradheizung. Die gewählten Heizstufen speichert die Integration selbst, weil sich die Bibliothek nichts merkt.

Im September habe ich ins README geschrieben, wie man die Daten an A Better Route Planner (ABRP) schickt. Im Oktober kam dazu der erste Beitrag von außen, von Christian Gonzalvez (chriscatuk). Christian ist geblieben und hat später einige der kniffligsten Stellen beim Login übernommen.

Erst Tests, dann Funkstille

Im März 2025 hat das Projekt endlich Tests bekommen. Vorher gab es keine einzige Testdatei. Dazu kamen Regeln für Commit-Nachrichten, Ruff als Linter und ein Workflow, der an jedes Release ein ZIP hängt. Im April folgten Binärsensoren für Türen und Verriegelung, im Mai v0.7.0.

Danach wurde es ruhig. Im dritten Quartal 2025 stehen in beiden Repositories zusammen gerade einmal 18 Commits. Einer davon war trotzdem wichtig: Seit Juli wählt die Bibliothek die API-Adresse nach der Baureihe aus. Der Smart #1 und der #3 sprechen mit der alten API, der #5 mit einer neuen.

Der Copilot-Agent räumt auf

Ende November 2025 habe ich zum ersten Mal den Coding-Agent von GitHub Copilot an das Projekt gelassen. Allein am 30. November kam eine ganze Reihe von Pull Requests zusammen. Ein schönes Beispiel: Die gewählten Heizstufen gingen nach jedem Neustart von Home Assistant verloren. Die Integration hat ein Enum als Schlüssel im Dictionary benutzt, und das übersteht den Weg nach JSON und zurück nicht. Seitdem baut außerdem ein Workflow die Releases und setzt die Versionsnummer selbst.

Im Dezember hat der Agent Tests nachgezogen, aus gut 500 Zeilen Testcode wurden über 2000. Nicht alles hat gepasst. Die Unterstützung für die internationale Smart-App in Australien und Asien habe ich im Februar in der Bibliothek wieder zurückgenommen. Mit v0.8.0 im Februar 2026 kann Home Assistant das Laden starten und stoppen. Und die Sensoren bleiben verfügbar, wenn die Cloud ein paar Abfragen lang nicht antwortet, statt sofort auf „nicht verfügbar“ zu springen.

Wenn die Cloud nicht mitspielt

2026 hat mich vor allem die Cloud beschäftigt. SensorsIot hat im Frühjahr einen Backoff beigesteuert, damit sich die Bibliothek wieder fängt, wenn die Web Application Firewall nach zu vielen Anfragen dichtmacht. Seit Mai baut die Bibliothek vor dem Login eine Sitzung bei Gigya auf anstatt manuell ein Sessiontoken zusammenzubasteln. Im Juni kamen trotzdem Berichte über fehlgeschlagene Anmeldungen, die pySmartHashtag 0.9.1 behoben hat.

Christian hat im Sommer neu geregelt, wie die Bibliothek mit abgelaufenen Tokens umgeht: erst auffrischen, dann neu binden und nur, wenn gar nichts mehr geht, neu anmelden. Vorher konnte eine kurze Störung eine ganze Welle von Logins auslösen. Dazu gehört der Fehlercode 8040, den die Cloud schickt, wenn ein Auto nicht mehr mit dem Konto verknüpft ist. Home Assistant fragt dann nach neuen Zugangsdaten, statt es endlos weiter zu versuchen. Kurz danach haben wir gelernt, dass ein einzelnes 8040 noch nichts heißen muss.

Mein Lieblingsfund aus dieser Zeit: Seit Juni 2024 gab es einen Sensor für die durchschnittliche Leistungsaufnahme, mit Watt als Einheit und umgedrehtem Vorzeichen. Zwei Jahre später stellte sich in Issue #436 heraus, dass der Wert gar keine Leistung ist, sondern ein Korrekturfaktor für die Reichweite in Prozent.

Auch sonst kam mehr aus der Community. Fábio Oliveira hat die ABRP-Anleitung repariert, Jusii hat der Bibliothek das Fahrtenbuch mit GPS-Punkten beigebracht.

Vom Sensor zur Fernbedienung

Seit dem Spätsommer arbeite ich mit Claude Code an dem Projekt. Im September kamen ein Schalter zum Enteisen der Frontscheibe und das Ver- und Entriegeln der Türen dazu. Den Kofferraum wollte ich gleich mitnehmen. Die Cloud hat die Befehle zum Öffnen und Schließen zwar angenommen, die Heckklappe hat sich beim Test aber keinen Millimeter bewegt. Zwei Tage später war die Funktion wieder draußen.

Am 10. Oktober habe ich sieben Pull Requests an einem Tag gemergt. Sechs davon machen aus der Integration eine Fernbedienung: Ladelimit setzen, Kofferraum ver- und entriegeln, Fenster zum Lüften öffnen, das Sonnenrollo bewegen, Licht blinken lassen und hupen, ein Ziel ans Navi schicken und sogar einen geteilten Link aus Google Maps. Der siebte bringt die Sitzbelüftung für den Smart #5. Der Link aus Google Maps hatte einen netten Haken. Aus der EU leitet Google zuerst auf die Seite zur Cookie-Zustimmung um, und die eigentliche Maps-Adresse steckt dort in einem Parameter. Ohne den auszupacken, fand der Parser keine Koordinaten.

Bei der Sitzheizung im Smart #5 kam die entscheidende Hilfe aus der Community. Der #5 erwartet dafür ein eigenes Format, im Code heißt es ZAF. radzatm hat die funktionierende Anfrage der App mit einem Man-in-the-Middle-Proxy mitgeschnitten, ooooli hat das Format für Klima, Sitz- und Lenkradheizung dokumentiert, und krlimi69 hat die Testversionen auf einem #5 Brabus ausprobiert. Inzwischen kann die Integration beim #5 auch die Rücksitze heizen und die elektrische Ladeklappe öffnen und schließen.

Damit Tester nicht jedes Mal ZIP-Dateien von Hand installieren müssen, steht im Repository ein kleiner Trick: In Home Assistant die Aktion update.install auf die Update-Entität der Integration anwenden und als Version den kurzen Commit-Hash angeben. HACS installiert dann genau diesen Stand.

Und dann ist da noch v0.12.1 vom 7. November. Wer sich zu oft mit einem falschen Passwort anmeldet, wird bei Gigya gesperrt, und die Bibliothek hat es bisher trotzdem stur weiter versucht. Jetzt fragt Home Assistant nach dem neuen Passwort und sagt dazu, wenn das Konto gesperrt ist. Im selben Release hat Garm82 dafür gesorgt, dass das schnelle Abfrageintervall nicht mehr hängen bleibt. Im schlimmsten Fall hat die Integration bis zum nächsten Neustart alle fünf Sekunden nachgefragt. Das Prinzip aus dem Februar 2024 eben.

Wie das neben dem Job klappt

Gestapeltes Balkendiagramm der Commits pro Quartal von 2024 bis 2026, aufgeteilt nach Bastian, Community, Copilot-Agent, Claude und Bots
Commits pro Quartal in beiden Repositories, aufgeteilt nach Autor. Nach dem Start im Februar 2024 und der Pause im Sommer 2025 übernehmen ab Ende 2025 die Agenten einen sichtbaren Teil.

Ehrlich gesagt: Ohne KI-Agenten wäre SmartHashtag nicht da, wo es heute ist. In der Integration stehen 86 Commits vom Copilot-Agent und 28 von Claude, dazu 18 von mir mit Claude als Co-Autor. Ich arbeite hier genauso wie bei India Navi: Ich beschreibe das Problem und das Ziel dahinter, der Agent liefert einen Pull Request, und am Ende entscheidet der Test am Auto. Die Heckklappe zeigt, warum ich auf diesen letzten Schritt nicht verzichte. Wie ich mit den Agenten rede, darum ging es im Mai in Wie redet ihr eigentlich mit euren KI-Agenten?

Aus 546 Zeilen Python im Februar 2024 sind gut 4900 Zeilen Integration geworden, dazu noch einmal so viele Zeilen Tests. Aus einem einzigen Sensor-Modul wurden neun Plattformen, von Sensoren über Schlösser bis zu Knöpfen für Hupe und Licht. Das Repository hat 72 Sterne und 9 Forks.

Wer einen Smart #1, #3 oder #5 fährt: Die Integration gibt es über HACS, Fehlerberichte und Pull Requests sind willkommen. Gerade beim #5 hilft jeder Mitschnitt aus der App.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert