Ein in den Diagnose-Port von Michael Schillis Auto(s) gestöpselter Stecker sendet an das mitreisende Mobiltelefon per Bluetooth aktuelle Informationen wie Geschwindigkeit, Beschleunigung, Benzinverbrauch. Eine App und ein programmierbares API lesen die Daten aus und stellen sie ansprechend dar.
Wer wie ich den Gedanken absurd findet, ein halbes Jahresgehalt in ein neues Auto zu investieren, und statt teurer deutscher Wertarbeit lieber gebrauchte japanische “Opel Manta”-ähnliche Boliden aus den 90er Jahren fährt, bekommt leider nicht den elektronischen Schnickschnack unter dem Motto “Connected Car” geboten, der heutzutage üblich ist. In meiner Wahlheimat San Francisco hat sich daher bereits vor einiger Zeit eine Startup-Firma namens Automatic aufgemacht, einen Stecker für den On-Board-Diagnose-Port (OBD) zu entwickeln, der laufend Daten aus dem Autocomputer ausliest und per Bluetooth in eine auf dem mitgeführten Handy laufende App einspeist ([2], Abbildung 1).
Diese fasst die Daten nach Abschluss der Autofahrt zusammen, übermittelt sie bei vorliegender Internetverbindung an den Automatic-Server, wo der erstaunte Fahrer dann später nachsehen kann, wo er langgefahren ist, wie oft er wie ein Irrer Gas gegeben, stark gebremst, wie viel Benzin er verbraucht hat und was der Trip demnach gekostet hat.
Abbildung 2 zeigt, dass mein Integra GSR unter meiner Obhut 27,3 Meilen pro Gallone gefahren ist, also 11,6 Liter auf 100 Kilometer verbraucht hat. Die schwache Wertung von nur 29 von maximal 100 möglichen Punkten für sparsames Fahren ist also noch stark verbesserungsfähig.
Sogar für Fuhrparks
Falls jemand wie ich mehrere Autos besitzt, benötigt jedes einen eigenen Automatic-Stecker. Der OBD-Port findet sich oft unter dem Armaturenbrett im Bereich des Fußraums, meist auf der Fahrer-, manchmal aber auch auf der Beifahrerseite (Abbildung 3). Einmal registrierte Adapter ticken dann aber alle nahtlos mit verschiedenen Familienhandys zusammen, auf denen die Automatic-App installiert ist.
Ohne dass der jeweilige Fahrer des jeweiligen Autos etwas tun müsste, verbindet sich das Handy in der Hosentasche nach dem Starten des Motors automatisch mit dem Stecker, der dies durch eine fröhlich klingende Tonsequenz kundtut, und speichert die aktuellen geografischen Koordinaten als Anfangsort der Reise.
Nach der Ankunft am Ziel bemerkt das Handy, dass sich das Auto nicht mehr fortbewegt, speichert die aktuelle Adresse als Zielort des Trips und lädt die Daten automatisch übers Internet zum Server hoch, ohne dass dies der Fahrer überhaupt mitbekommt – die mobile App läuft im Hintergrund.
Die Tripdaten lassen sich später entweder über die App oder auf Wunsch auch im Browser eines Desktop-Computers anzeigen (Abbildungen 4 und 5), auch ein API bietet Automatic, das angemeldeten Usern per Json maschinenlesbare Daten zurückliefert, die weitere Skripte aufbereiten und anzeigen können.
Wo hab ich geparkt?
Wir Großstädter zirkeln ja schon mal eine Viertelstunde um den Block, bis wir endlich einen freien Parkplatz finden. Später kommt dann aber oft die Frage auf: “Wo hab ich jetzt nochmal geparkt?” Dank des Automatic-Stöpsels ist das nun sonnenklar, denn am jeweiligen geografischen Ende eines Trips in der Automatic-Welt muss auch das Auto stehen, falls es nicht gerade schon wieder in der Gegend herumfährt.
Das Einholen der Daten funktioniert mit Hilfe des Automatic-API auch mit einem Perl-Skript von der Kommandozeile aus. Dazu muss der User die Applikation zunächst auf der Developer-Seite von Automatic unter https://developer.automatic.com anmelden, er erhält dann nach dem so genannten Oauth-Token-Dance einen Access-Token zugeteilt, mit dem ein API-Client wie etwa das Skript in Listing 1 im Auftrag des Users private Daten vom Server geschickt bekommt.
Listing 1
wheresmycar
01 #!/usr/local/bin/perl -w
02 use strict;
03 use OAuth::Cmdline::Automatic;
04 use JSON qw( from_json );
05
06 my $oa = OAuth::Cmdline::Automatic->new();
07 $oa->raise_error( 1 );
08
09 my $vehicles =
10 from_json $oa->http_get(
11 "https://api.automatic.com/vehicle" );
12
13 for my $car (
14 @{ $vehicles->{ results } } ) {
15
16 my $trips =
17 from_json $oa->http_get(
18 "https://api.automatic.com/trip",
19 [ vehicle => $car->{ id } ]
20 );
21
22 for my $trip (
23 @{ $trips->{ results } } ) {
24 printf "%20s: %s\n",
25 "$car->{ make }-$car->{ model }-" .
26 "$car->{ year }",
27 $trip->{ end_address }->{ name };
28 last;
29 }
30 }
Listing 1 holt zunächst mit dem API-Call »vehicle« in Zeile 10 die Beschreibungen aller registrierten Autos des Users ein. Die For-Schleife ab Zeile 13 iteriert dann durch den Fuhrpark und ruft für jedes Fahrzeug in den Zeilen 17 und 18 die API-Methode »trip« mit der ID des aktuellen Fahrzeugs auf. Die API-Aufrufe liefern Daten im Json-Format an den Client, diese wandelt die aus dem CPAN-Modul »JSON« exportierte Funktion »from_json()« in Perl-Daten um, in denen der Code per Hash- oder Array-Zugriff herumstöbern kann.
Die Ausgabe in Abbildung 6 zeigt, dass der Acura Integra GSR, der Opel Manta Amerikas, gerade auf der 24. Straße in San Francisco parkt, während der Honda Fit, das Pendlerfahrzeug der Perlmeisterfrau, gerade im benachbarten Oakland weilt, wo sie arbeitet.
Trip-Mitschnitt
Die Ergebnisdaten liegen unter dem Schlüssel »results« in einem Array und im Fall des »trip« -Aufrufs enthält jener eine Reihe von Trip-Objekten, die die Koordinaten einer Reise, Angaben zur Geschwindigkeit, die Anzahl der Beschleunigungs- und Bremsmanöver sowie sogar die Straßenadressen am Ausgangs- und Endpunkt der Reise enthalten. Die Trips kommen in umgekehrter chronologischer Folge an, also ist der erste Trip in der Liste immer jeweils der letzte abgeschlossene.
Der unter dem Eintrag »end_address« vermerkte Endpunkt ist die Adresse, an der das Fahrzeug geparkt wurde. Bleibt nur noch, zur Unterscheidung der verschiedenen Fahrzeuge im Fuhrpark, die Marke, das Modell und das Baujahr des Automobils auszugeben (in der Perlmeistergarage standen vor einiger Zeit tatsächlich mal zwei Integras unterschiedlicher Jahrgänge). Zusammen mit dem »name« -Feld der Zieladresse des Trips ist dann klar, wo der Wagen steht. Der Befehl »last« in Zeile 28 bricht die Bearbeitung der Tripdaten jeweils nach dem ersten Satz ab, die For-Schleife ab Zeile 13 geht mit dem nächsten Auto aus dem Fuhrpark in eine neue Runde.
Oauth bittet zum Tanze
Wie kann der User das Skript dazu autorisieren, in seinem Namen private Daten vom Automatic-Server einzuholen? Das CPAN-Modul OAuth::Cmdline bietet neben den Helfern für Anbieter wie Google Drive oder Spotify seit Version 0.05 auch eine Schnittstelle für Automatic.com an. Um den User mit Hilfe eines Webbrowsers durch den Tokentanz zu führen, muss er die Applikation auf der Automatic-Developer-Seite erst einmal anmelden (Abbildung 7).
Unter »My Apps« drückt er dazu den »+« -Knopf und trägt neben dem App-Namen (hier »Perlsnapshot« ) im Feld »OAuth Redirect URL« den Wert
http://localhost:8082/ callback
ein, damit der Automatic-Server den Kommandozeilen-Client nach getaner Arbeit wieder zu seinem eigenen Webserver zurücklotst und ihn den eingefangenen Access-Token lokal auf der Festplatte ablegen lässt.
Automatic besteht bei kommerziellen Applikationen darauf, diese vor Inbetriebnahme zur Freischaltung zu überprüfen, aber im Testmodus kann der Betreiber auch ohne gestrenges Tribunal bis zu 25 User-Accounts verwalten. Die Registrierung der App quittiert Automatic mit zwei Schlüsseln: der Client ID und dem Client Secret. Beide legt der User nun in der Datei ».automatic.yml« im Yaml-Format im Homeverzeichnis ab:
~/.automatic.yml client_id: XXXXX client_secret: YYYY
Im Verzeichnis »eg« des CPAN-Moduls OAuth::Cmdline liegt ein Skript namens »automatic-token-init« , das nach dem Starten die Meldung ausgibt, dass es auf dem heimischen Rechner »localhost« auf Port 8082 einen Webserver gestartet hat. Nordet der User dann seinen Browser auf »http://localhost:8082« ein, zeigt dieser einen mit »Login on automatic« betitelten Link an, der auf einen Mausklick hin zur Login-Seite des Automatic-Servers verzweigt (Abbildung 8).
Zugriff genehmigt
Loggt der User sich dort ein und erklärt sich damit einverstanden, die neue namentlich angezeigte Applikation »Perlsnapshot« zum Einholen von Nutzerdaten zuzulassen (Abbildung 9), verzweigt der Automatic-Server wieder zurück zum Webserver des Initskripts, das daraufhin in der Datei »~/.automatic.yml« einige weitere Parameter wie den Access-Token ablegt, mit denen Skripte künftig Fahrdaten holen können, ohne dass der Nutzer sein Passwort eingeben muss.
Das CPAN-Modul bietet zum Einholen von authentisierten Webrequests die Methode »http_get()« an, die dann hinter den Kulissen den Access-Token aus der Yaml-Datei holt und ihn dann ordnungsgemäß dem Request in Header-Form beilegt, sodass der Server, ohne weitere Fisimatenten zu machen, die privaten Daten herausrückt.
Ein Detail am Rande: Anders als andere Oauth-Implementierungen bietet Automatic keinen so genannten Refresh-Token an, aber dafür bleibt ein einmal ausgestellter Access-Token ein ganzes Jahr lang gültig, nach dessen Ablauf der User erneut durch den Tokentanz muss.
Malen nach Zahlen
Die aufgezeichneten Tripdaten der Automatic-App enthalten aber noch weitere informationstechnische Leckerbissen. Im Feld »path« findet sich ein kryptischer String, der in der so genannten Polyline-Kodierung [3] alle paar Sekunden den aktuellen Ort des Fahrzeugs während eines Trips als geografische Breite und Länge mitschreibt:
qzjeFb|hjVDkBh@gAY]hBiDrAwBt@_A...
Mit dem CPAN-Modul Algorithm::GooglePolylineEncoding ist die Zeichenkolonne schnell entschlüsselt: (37.74393, -122.43922), (37.74369, -122.43832), … Der erste Zahlenwert gibt jeweils die geografische Breite (Latitude), der zweite Wert die Länge (Longitude) an.
Während der 10-minütigen Testfahrt zum Semmelholen von San Franciscos Stadtteil Noe Valley zum Supermarkt in Diamond Heights kamen insgesamt 38 Datenpunkte zusammen, die Listing 2 dekodiert und für die grafische Darstellung aufbereitet.
Listing 2
trip-path
01 #!/usr/local/bin/perl -w
02 use strict;
03 use OAuth::Cmdline::Automatic;
04 use JSON qw( from_json to_json );
05 use YAML qw( Dump );
06 use Algorithm::GooglePolylineEncoding;
07
08 my $oa = OAuth::Cmdline::Automatic->new();
09 $oa->raise_error( 1 );
10
11 my $trips = from_json $oa->http_get(
12 "https://api.automatic.com/trip", [] );
13
14 my @locs = Algorithm::GooglePolylineEncoding::decode_polyline(
15 $trips->{ results }->[ 0 ]->{ path } );
16
17 print Dump ( \@locs );
Wie gelangen die Messwerte auf eine Landkarte wie in Abbildung 10 gezeigt? Das Google-Maps-API bietet dafür eine praktische Schnittstelle und tatsächlich kam diese schon vor sechs Monaten zum Einsatz: Der Perl-Snapshot im Linux-Magazin 03/2016 [4] stellte dazu das Skript »map-draw« vor, das Latitude/Longitude-Punkte im Yaml-Format entgegennimmt und daraus Javascript produziert, mit dem der Browser per Google-Maps-API diese Punkte in die Landkarten einzeichnet.
Listing 2 muss also nur Yaml mit Lat/Lon-Paaren produzieren, dann erzeugt der Aufruf
./trip-path | ./map-draw >map.html
eine HTML-Seite, die man einfach mit »file:///…map.html« in den Browser lädt, um eine interaktive Landkarte mit der Wegstrecke zu bestaunen.
Auch in Echtzeit
Neben dem in den Skripten genutzten REST-API bietet Automatic auch noch ein Realtime-Stream-API an, entweder über Websockets oder Webhooks, das Applikationen praktisch verzögerungsfrei benachrichtigt, wenn bestimmte Ereignisse eintreten.
Beim Start des Wagens, am Ende eines Trips, beim Übertreten eines voreingestellten Geschwindigkeitswerts, scharfem Bremsen oder wenn die Kontrolllampe aufflackert, schickt der Webservice damit sofort eine Nachricht an die lauschende App, die diese auch auf dem Lockscreen des versperrten Handys anzeigt und es auf Wunsch vibrieren oder einen Ton spielen lässt.
Der in dem Perl-Snapshot des Linux-Magazins 07/2016 zur Integration des Fernschalters Wemo [5] besprochene Webservice Ifttt.com erleichtert auch im vorliegenden Fall des Autostöpsels das Einklinken beträchtlich. Statt API-Integration trägt sich der User dort auf dem Automatic-Channel ein, wird ähnlich wie beim vorher verwendeten CPAN-Modul durch den Tokentanz geführt und dann aufgefordert, Ifttt.com Zugriff auf die Automatic-Daten zu gewähren.
Abbildung 11 zeigt das Ifttt-Rezept, das jedes Mal eine Kurznachricht auf das Mobiltelefon des Users schickt, falls ein Fahrer die Zündung des Wagens einschaltet. Allerdings erfolgt dies naturgemäß mit der Einschränkung, dass ein anderes Handy mit einer installierten Automatic-App mitfährt, denn sonst hat der Adapter keine Verbindung zum Internet.
Kosten und Ausblick
Der Automatic-Stecker der aktuellen 2. Generation kostet bei der nur in den USA möglichen Anschaffung etwa 90 US-Dollar, die App kostet nichts und weitere Kosten für das Sammeln und Anzeigen der Daten fallen ebenfalls nicht an. Das Gerät arbeitete bei den absolvierten Fahrten ausgesprochen zuverlässig, manchmal dauert es allerdings eine Weile, bis ein Trip zum Server hochgeladen wird, falls das Handy mal keine Verbindung zum Internet oder Zugang zu GPS-Daten findet.
Denn der Stecker kann alleine wirklich nichts, außer OBD-Daten abgreifen und per Bluetooth ans mitfahrende Handy zu senden, das anschließend dann die Hauptarbeit erledigt. Gegen den Diebstahl des Fahrzeugs hilft er also nicht. Es existieren bereits etwa zwei Dutzend weitere Apps für iPhone oder Android und mit dem einfach zu handhabenden API sollte es nicht lange dauern, bis ein ganzes Ökosystem mit weiteren praktischen Anwendungen entsteht.
Online PLUS
Im Screencast demonstriert Michael Schilli das Beispiel: https://www.linux-magazin.de/Ausgaben/2016/10/plus
Infos
- Listings zu diesem Artikel:https://www.linux-magazin.de/pub/listings/magazin/2016/10/perl-snapshot
- “Automatic.com: Dieser Adapter macht Ihr Auto schlau”:http://www.computerbild.de/artikel/cb-Tests-App-Check-Automatic-com-Adapter-Connected-Car-11378727.html
- “Encoded Polyline Algorithm Format”: https://developers.google.com/maps/documentation/utilities/polylinealgorithm
- Skript »map-draw« aus Perl-Snapshot “Steighilfen”: Linux-Magazin 03/16;https://www.linux-magazin.de/pub/listings/magazin/2016/03/Perl
- Michael Schilli, “Klick-klack”: Linux-Magazin 07/16, S. 80; https://www.linux-magazin.de/Ausgaben/2016/07/Perl-Snapshot
















