#standwithukraine

Dynamische Benachrichtigungen für neue Geocaches mit Traccar und Project-GC

Dynamische Benachrichtigungen für neue Geocaches mit Traccar und Project-GC

Achtung, leicht technischer Nerd-Content!

Wenn du froh bist, dass du dein GPSr mit einer GPX befüllen oder Tradis mit einer App finden kannst, dann kannst du zwar gerne weiterlesen, wirst aber früher oder später nur noch Fragezeichen sehen. Wenn du aber bei Apache nicht direkt an Indianer denkst, weißt, dass es 10 Arten von Menschen gibt, über PICNIC und PEBKAC nur den Kopf schütteln kannst und Ping für dich nichts mit Tischtennis zu tun hat: Lies gerne weiter.

Um was gehts hier eigentlich?

Ja, die Überschrift klingt etwas sperrig. Um das Ganze mal etwas einfacher darzustellen: Viele Cacher haben Notifications auf Geocaching.com angestellt, um sich über die Veröffentlichung von neuen Caches oder Events informieren zu lassen.

Man gibt einen Punkt, meist die Homekoordinaten, einen Radius, einen Logtyp (normalerweise „Publish“) und eine Cacheart an und bekommt eine Email, sobald der Reviewer einen Cache freigegeben hat. Alternativ bietet Project-GC das auch für zahlende Mitglieder an.

So weit, so gut. Ein Großteil der Geocacher kann jetzt wahrscheinlich aufhören zu lesen, weil sie keine Notifications verwenden, keine FTF-Jäger sind oder zumindest außerhalb der Homezone erst gar keine FTFs versuchen. Der Teil, der übrig bleibt, erstellt sich vielleicht eine Benachrichtigung rund um seinen Urlaubsort und macht sich sonst keine weiteren Gedanken.

Und dann gibt es mich. Okay, gut, ich renne nicht grundsätzlich immer und überall einem FTF hinterher. Aber wenn ich die Chance dazu habe, sage ich selten nein. Bin ich ein paar Tage an einem Ort, ist das kein Problem, da erstelle ich mir meist auch nur eine normale Notification. Allerdings bin ich gerade mitten in der Planung für einen Roadtrip. Das bedeutet, dass man maximal 2 oder 3 Tage in derselben Gegend ist. Da wäre es super, wenn man quasi eine Benachrichtigung erstellen könnte, die sich immer auf den aktuellen Aufenthaltsort bezieht.

Einrichtung der Benachrichtigung auf Project-GC

Kann man. Von dieser Funktionalität auf Project-GC habe ich vor einigen Monaten erfahren und war sofort interessiert. Man kann eine Benachrichtigung mit „dynamischem Standort“ erstellen und sich so auch benachrichtigen lassen, wenn man nicht in der Homezone unterwegs ist.

Project-GC: Einrichtung von dynamischer Notification

Dazu erstellt man einfach über den Button „Neue Benachrichtigung hinzufügen“ einen neuen Eintrag. Man vergibt einen Namen und gibt einen Radius an. Ich habe hier 20 Kilometer genommen, schließlich will man ja meist schon „in der Nähe“ bleiben. Des Weiteren setzt man den Haken bei „Dynamischer Mittelpunkt“. Wenn man nicht bei jedem Publish, sondern nur einmal pro Tag, eine Mail bekommen will, hakt man „Tägliche Zusammenfassung“ an, der Haken bei „Logs verfolgen“ schickt einem jedes Log bis zum ersten Fundlog zu. Aktivieren braucht man die Benachrichtigung noch nicht.

Aktuellen Standort an Project-GC senden

Leider bezieht sich die Anleitung auf Project-GC auf eine Android-App, die nicht mehr weiterentwickelt wird, aber aktuell noch funktioniert. Das bringt mir allerdings überhaupt nichts, da ich ein iPhone verwende und es die App für iOS gar nicht gibt. Zwar fand ich eine ähnliche, letztendlich bietet sie aber nicht die ausreichende Funktionalität, um die API von Project-GC korrekt aufzurufen und die Standortdaten weiterzuleiten.

Ich hatte das Thema schon fast wieder vergessen, als ich in der c’t auf einen Server gestoßen bin, der GPS-Daten verwurstet und auf einer Karte anzeigt. Dachte ich zumindest. Letztendlich war das, was ich da gefunden habe, weit mächtiger, als ich annahm. Egal, die Software sieht interessant aus, ich hatte Urlaub und Lust mich damit zu beschäftigen.

    Traccar

    Traccar ist ein kostenloser Opensource GPS-Tracking-Server. Die Software kennt eine Vielzahl von Geräten (etwa 1500 verschiedene), die Updates an den Server senden können. Neben OBD-Dongles fürs Auto ist die einfachste Variante sicher, eine der Apps für iOS oder Android zu verwenden.

    Server in Docker installieren und konfigurieren

    Es gibt mehrere Möglichkeiten, den Traccar-Server zu installieren. Da ich ursprünglich ja nur etwas rumspielen wollte, habe ich die einfachste gewählt: Einen Docker-Container. Docker ist eine Virtualisierungssoftware, bei der man relativ einfach komplette Softwarepakete installieren kann.

    Mit dem folgenden Befehl wird der Container angelegt:

    mkdir -p /opt/traccar/logs
    
    docker run \
    --rm \
    --entrypoint cat \
    traccar/traccar:latest \
    /opt/traccar/conf/traccar.xml > /opt/traccar/traccar.xml

    Jetzt wäre ein guter Zeitpunkt, die vielen Optionen zumindest einmal zu überfliegen und ggf. die traccar.xml anzupassen.

    Auf der Shell sind es nur ein paar wenige Befehle:

    docker run \
    --name traccar \
    --hostname traccar \
    --detach --restart unless-stopped \
    --publish 81:8082 \
    --publish 5000-5150:5000-5150 \
    --publish 5000-5150:5000-5150/udp \
    --volume /opt/traccar/logs:/opt/traccar/logs:rw \
    --volume /opt/traccar/traccar.xml:/opt/traccar/conf/traccar.xml:ro \
    -v /var/docker/traccar/data:/opt/traccar/data:rw \
    traccar/traccar:latest

    Ich habe obigen Befehl etwas angepasst. Normalerweise wäre die Chance, dass sich nichts tut oder eine Fehlermeldung erscheint, relativ groß, wenn auf dem Server bereits ein Webserver auf Port 80 lauscht.
    Daher empfiehlt es sich, bei –publish 80:8082 die 80 durch einen anderen Port zu ersetzen. Da ich sowieso alles durch Nginx durchschleife, ist der Port egal. 81 lag nahe, letztendlich geht aber jeder freie Port. Des Weiteren habe ich das Daten-Verzeichnis installieren lassen, damit die Daten nicht verloren gehen, wenn man den Docker-Container löscht.

    Konfiguration von Nginx als Reverse Proxy

    Zur „normalen“ Konfiguration eines Virtual Hosts füge ich folgende Zeilen zum Server {}-Block hinzu:

    location /api/socket {
           include proxy_params;
           proxy_http_version 1.1;
           proxy_cache_bypass $http_upgrade;
           proxy_buffering off;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection "Upgrade";
           proxy_pass http://127.0.0.1:81/api/socket;
        }
    
    location / {
    	proxy_pass http://127.0.0.1:81;
            log_not_found off;
    	proxy_set_header  Host $host;
            proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header  X-Forwarded-Proto $scheme;
            proxy_set_header  X-Forwarded-Port $server_port;
            proxy_set_header  X-Forwarded-Host $host;
        }

    Damit ist die Weboberfläche von Traccar wie eine normale Website auf Port 443 (oder 80) erreichbar. Lässt man diesen Schritt aus, ist Traccar von extern unter Port 8082 aufrufbar. Gegebenenfalls muss dieser in der Firewall geöffnet werden.

    Ich habe die URL aufgerufen und einen Account registriert. Nach dem erfolgreichen Login habe ich unter Einstellungen -> Server die Geschwindigkeitseinheit auf km/h umgestellt, als Zeitzone „Europe/Berlin“ ausgewählt und bei Ort meinem momentanen Standort eingegeben. Dies funktioniert logischerweise erst, wenn die App einmal ihren Standort an den Server geschickt hat. Bei „Registrierung zulassen“ habe ich den Haken entfernt. Schließlich reicht es vollkommen aus, wenn ich einen Account habe.

    Auswahl der Datenbank

    Traccar verwendet die mitgelieferte H2-Datenbank. Benutzt man den Server nicht nur allein und etwas exzessiver, wird empfohlen bspw. auf MySQL bzw. MariaDB umzusteigen. Was man hier beachten muss: Läuft MySQL/MariaDB „normal“ auf dem Server, also nicht in einem Docker-Container, kann man den Datenbank-Server nicht über localhost aufrufen, sondern über die „externe“ IP-Adresse. Des Weiteren muss der User die Erlaubnis haben, von der IP des Docker-Containers auf die Datenbank zuzugreifen.

    Konfiguration der App

    Die App ist ein Selbstläufer, im wahrsten Sinne. Man kann gar nicht wahnsinnig viel einstellen, braucht man aber auch nicht. Man muss über die Weboberfläche ein neues Gerät anlegen. Dazu vergibt man einen Namen und eine ID. Diese Gerätekennung ist entweder die IMEI oder eine Nummer aus der App.

    Sobald diese auf beiden Seiten (Server und App) identisch ist, trägt man noch die URL des Servers (ggf. mit Port) ein und schaltet den Dienststatus auf an. Die Frequenz der Updates habe ich auf 300 (Sekunden, also 5 Minuten) eingestellt gelassen. Will man detailliertere Routen abrufen können, muss der Wert verkleinert werden.

    Standortdaten senden

    Ich habe die App geöffnet, konstanten Zugriff auf GPS auch im Hintergrund zugelassen, bin einmal durch die Stadt gefahren und habe mir danach die Strecke auf der Karte angeschaut. Gut, alle 5 Minuten updaten ergibt wie gesagt keine wirklich perfekte Strecke, zum Spielen (und für unsere Zwecke) ist das aber vollkommen ausreichend. Ich hatte den Server einige Tage laufen, habe mich durch die Aufbereitung der Daten geklickt und das Ganze für mich als nette Spielerei abgetan.

    Kontakt zu Project-GC

    Doch dann kam mir eine Idee: Kann der Server vielleicht die passend aufbereiteten Daten an Project-GC senden und ich komme doch noch zu dynamischen Benachrichtigungen? Jetzt wird die Sache interessant!

    Eine kurze Suche im Traccar-Forum und in der Dokumentation brachte ans Licht, dass man über die Optionen forward.enable und forward.url in der Konfigurationsdatei /opt/traccar/traccar.xml genau das einstellen kann, was ich will.

    <entry key='forward.enable'>true</entry>
    <entry key='forward.json'>false</entry>
    <entry key='forward.url'>https://URL</entry>

    Testweise habe ich mir ein PHP-Script geschrieben, um überprüfen zu können, ob die Weiterleitung fehlerfrei funktioniert. Als alles okay war, habe ich den Eintrag bei forward.url geändert und folgende URL eingetragen:

    https://project-gc.com/api/UserLocation/Update/?protocol=1&uid=UID&latitude={latitude}&longitude={longitude}&acc={accuracy}&ts={fixTime}&token=TOKEN&nid=NID&enable=1

    Die Werte für UID, TOKEN und NID holt man von Project-GC: Die User-ID und das Token findet man unter Einstellungen. Hier sollte auch eine Email-Adresse hinterlegt sein, an die die Benachrichtigungsmails gesendet werden. Die NID ist die ID der Benachrichtigung („NOTIFIER-ID“). Sie steht neben dem Namen der Benachrichtigung.

    Testen in freier Wildbahn

    Der Server läuft, die App schickt meinen Standort alle 5 Minuten, die Weiterleitung an Project-GC funktioniert auch. Zeit, das Ganze live zu testen.

    Ich war außerhalb meiner Homezone in der Nähe von Speyer cachen, als mich eine Mail von Project-GC erreichte. Der Cache, der gepublisht wurde, ist Luftlinie etwa 18 Kilometer von meinem Standort weg und weit genug entfernt zu meinen Homekoordinaten.

    Project-GC: Mail von dynamischer Notification

    Die Benachrichtigung passt! Somit scheint alles zu funktionieren, wie es soll. Dem nächsten FTF-Versuch steht also nichts mehr im Weg 🙂

    Fazit

    Ja, es ist ein bißchen wie mit den Kanonen und den Spatzen. Aber es ist eine nette Spielerei, die Ressourcen dafür sind da und es hat Spaß gemacht, den kompletten Prozess zu testen.

    Der Akku des Handys wird natürlich etwas beansprucht, allerdings funktioniert die Abfrage des Standortes im Hintergrund inzwischen einigermaßen schonend. Der Server verbraucht etwa 800 MByte RAM und unter 1% CPU.

    Nginx: Mehrere Hostnamen auf einen umleiten

    Nginx

    Das hier ist eher ein Memo für mich, als große Kunst 🙂 Ich stand vor folgendem kleinen Problem: Ich wollte mehrere Hostnamen auf einen einzigen finalen umleiten. Das wollte nicht so recht klappen.

    Nach der Umstellung auf SSL leitet http://subdomain.domain1.de auf https://subdomain.domain1.de um. Das läßt sich problemlos und einfach über folgenden Code in der Konfigurationsdatei des Vhosts einrichten.

    server {
    listen 80;
    server_name subdomain.domain1.de;
    return 301 https://$server_name$request_uri;
    }

    Als ich der Website eine eigene Domain spendiert habe, stieß ich auf ein kleines Problem:

    Ich wollte http://subdomain.domain1.de, http://www.domain2.de und https://subdomain.domain1.de auf https://www.domain2.de umleiten. Das versuchte ich wie folgt:

    server {
    listen 80;
    server_name subdomain.domain1.de www.domain2.de domain2.de;
    return 301 https://www.domain2.de$request_uri;
    }

    server {
    listen 443 ssl http2;
    server_name subdomain.domain1.de www.domain2.de domain2.de;
    […]
    }

    Soweit so gut. Oder auch nicht. Denn https://subdomain.domain1.de funktioniert zwar, leitet aber nicht auf https://www.domain2.de um. Nach etwas Knobelei hatte ich aber raus, wie das funktioniert:

    server {
    listen 80;
    server_name subdomain.domain1.de domain2.de www.domain2.de;
    return 301 https://www.domain2.de$request_uri;
    }

    server {
    listen 443 ssl http2;
    server_name subdomain.domain1.de;
    […]
    return 301 https://www.domain2.de$request_uri;
    }

    server {
    listen 443 ssl http2;
    server_name www.domain2.de domain2.de;
    […]
    }

    Man benötigt also pro SSL-Host einen eigenen server { } Abschnitt. Im Nachhinein eigentlich logisch.