Nachdem ich so viele Anfragen bekommen habe, wie ich die technische Umsetzung gemacht habe, wollte ich meine Scripte hier mal veröffentlichen. Es gibt auch einige Anbieter, die Tracking usw für den RUT anbieten. Ich wollte aber eine eigene Lösung schaffen, da ich die Daten dann individuell verarbeiten möchte.

Vorbereitung

Zuerst einmal die Vorbereitungen, die nötig sind: Im ersten Schritt benötigt ihr eine Gegenstelle. Ein Webspace / Server im Internet oder eine lokale Variante (dann muss entweder der Port 443 weitergeleitet werden oder ein VPN eingerichtet werden). Ich habe einen Webspace für meine Homepage – die nutze ich auch für die GPS-Position. Da ich die Daten länger halten und auswerten möchte, benötige ich noch eine Datenbank. Bei meinem Paket ist eine MySQL Datenbank dabei, die ich für die Speicherung nutze.

Ich habe in meiner MySQL Datenbank eine Tabelle “position” mit folgenden Spalten und Typen angelegt:

Datenbanktabelle position für die Speicherung

Der RUT955 kann die GPS-Position auf mehrere Arten übermitteln. Ich habe mich für die Übertragung per HTTP/HTTPS entschieden. Um die Daten zu übermitteln im Bereich GPS unter dem Abschnitt HTTPS/HTTP Server Settings folgende Daten eingeben:

Enabled -> ON (sonst passiert gar nix)
URL -> Den Pfad, der aufgerufen wird um die GPS-Daten zu speichern
Delay-> Wie oft wird das Script aufgerufen? Hier 120 Sekunden. (im Prinzip ist der Wert völlig egal, da ich die Werte sowieso nur alle 5 Minuten einlese.)

Ihr müsst die URL natürlich an eure Bedürfnisse anpassen. Also eure Domain, Verzeichnis usw. Der RUT übermittelt die GPS-Daten dann als Datenstrom.

PHP-Teil

Ich habe keine Möglichkeit gefunden, die Daten direkt aus dem Datenstrom zu verarbeiten. Daher habe ich mir ein kleines PHP-Script geschrieben, dass die Daten als Textdatei ablegt. Das Script save_raw.php. Das Script muss auf einen Webserver mit PHP und MySQL in ein erreichbares Verzeichnis gelegt werden (bei mir gps-pos). Wenn ihr ein anderes Verzeichnis nehmt, dann muss der Pfad im RUT entsprechend angepasst werden.

<?php
// Datei: save_raw.php
// Speichert den Datenstrom in eine Textdatei
// Copyright: Kai Weible, 2022

$rawdata = file_get_contents("php://input"); 

$fp = fopen('vardump.txt', 'w');
fwrite($fp, print_r($rawdata, true));
fclose($fp);
	
?>

Immer wenn der RUT die Daten übermittelt, werden diese in die Textdatei vardump.txt gespeichert. Das kann man auch schon testen. Wenn der RUT an ist und eine Internetverbindung hat, müsste im 2 Minuten-Takt die Datei neu erstellt werden.

Die GPS Daten liegen nun im Rohformat vor. Mit dem Script gpsparsing.php, dass ich mit einem Cron-Job alle 5 Minuten laufen lasse, lese ich die benötigten Daten aus dem Textfile aus. Das Script kann so wie hier abgebildet verwendet werden. Ihr müsst es in denselben Ordner legen, wie das erste Script und mit einem Cronjob regelmäßig ausführen (das können die Hostinganbieter heute eigentlich alle).

Anpassen müsst ihr noch die Datenbank-Daten. Also Host, Datenbankname, Benutzer und Passwort. Sowie ggf. die einzelnen Werte (im mittleren Bereich des Scriptes (bei dem Kommentar #DEBUG seht ihr die einzelnen Werte, die es gibt), die ihr speichern wollt.

Ich speichere Längen und Breitengrad sowie akt. Geschwindigkeit, Kurs, Anzahl der Sateliten, Höhe über Null und das Datum.

<?php
// Datei: gpsparsing.php
// Extrahiert die nötigen Daten aus der Textdatei und speichert diese in eine Datenbank
// Copyright: Kai Weible, 2022

$file = 'vardump.txt';
$file_handle = fopen($file, 'r');
 
while (!feof($file_handle)) {
 
  $line = fgets($file_handle);
  
  #$GPRMC im Dump finden
  $pos = strpos($line, 'GPRMC');
  $pos2 = strpos($line, 'GPGGA');
  
  if ($pos == true) {
     $GPSDATA = $line;
   } 
  
  if ($pos2 == true) {
     $GPSDATA2 = $line;
   } 
  
  }
fclose($file_handle);


#String in Einzeldaten zerlegen 
$parts = explode(",", $GPSDATA);
$parts2 = explode(",", $GPSDATA2);


#DEBUG
/*
echo $parts[0].'<br>'; // RMC
echo $parts[1].'<br>'; // Zeit HHMMSS UTC
echo $parts[2].'<br>'; // Status (A für OK)
echo $parts[3].'<br>'; // Breitengrad
echo $parts[4].'<br>'; // Ausrichtung
echo $parts[5].'<br>'; // Längengrad
echo $parts[6].'<br>'; // Ausrichtung
echo $parts[7].'<br>'; // Geschwindigkeit in Knoten
echo $parts[8].'<br>'; // Kurs
echo $parts[9].'<br>'; // Datum
echo $parts[10].'<br>'; // Magn Abweichung
echo $parts[11].'<br>'; // Vorzeichen der Abweichung
echo $parts[12].'<br>'; // Modus und Prüfsumme
*/
#DEBUG

$numofsat = $parts2[7]; // Anzahl Sateliten
$heigh = $parts2[9]; // Anzahl Sateliten

$latitude = coordinatesToDecimal($parts[3], $parts[4]);
$longitude = coordinatesToDecimal($parts[5], $parts[6]);

$speed = speedtokmh($parts[7]);
$kurs = $parts[8];

list($day, $month, $year) = str_split((string) $parts[9], 2);
list($hour, $minute, $second) = str_split((string) $parts[1], 2);

$date = '20'.$year.'-'.$month.'-'.$day.' '.$hour.':'.$minute.':'.$second;


#Datenbank eintragen - Hier eure Werte eintragen:
$dbhost = "<DB Server>";
$dbuser = "<DB Benutzername>";
$dbpw = "<DB Passwort>";
$database = "<Datenbankname>";


 $db= mysqli_connect ("$dbhost","$dbuser","$dbpw") or die(mysqli_error()." - Serverzugriff gescheitert!");
 mysqli_select_db($db, $database) or die(mysqli_error()." - Datenbankzugriff gescheitert!");
 
$abfrage = "INSERT INTO position (pos_breitengrad, pos_laengengrad, pos_speed, pos_course, pos_date, pos_sat, pos_heigh) VALUES ('".$latitude."', '".$longitude."',".$speed.",".$kurs.",'".$date."',".$numofsat.",'".$heigh."');";
 
$ergebnis= mysqli_query ($db, $abfrage);

// Umwandlung der Koordinaten ins Dezimalsystem (das GoogleMaps dann versteht)
function coordinatesToDecimal($coordinate, $direction) 
    {
        $breakPoint = strpos($coordinate, '.') - 2;

        $minutes = (float) substr($coordinate, $breakPoint);
        $degrees = (int) substr($coordinate, 0, $breakPoint);

        $decimal = $degrees + ($minutes / 60);

        return in_array($direction, ['S', 'W']) ? -$decimal : $decimal;
    }

// Umrechnung von Knoten in KM/h
function speedtokmh($knots)
	{
		$kmh = $knots *1.852;
		return $kmh;
	}

?>

Ihr könnt das Script entweder über den Cron-Job ausführen lassen oder auch mal manuell im Browser eingeben und schauen, ob es ohne Fehler durchläuft. Wenn das Script korrekt läuft solltet ihr in danach der Datenbank die Einträge finden:

Datenbank mit GPS Daten

Damit ist Teil 1 der Arbeiten abgeschlossen. Die Werte werden nun regelmäßig vom RUT955 übermittelt und alle 5 Minuten in die Datenbank geschrieben.

Ausgabe der Position auf Google-Maps

Durch die oben veröffentlichten Scripte werden die GPS Daten sowie Geschwindigkeit, Kurs und Anz. Satelliten in die Datenbank gespeichert. Möchte man diese Daten nun in Google-Maps anzeigen, benötigt man eine Webseite zur Anzeige der Position. Das Script holt die letzten Datensatz aus der Datenbank und erzeugt damit die Rohdaten für Maps. Außerdem zeige ich am rechten Rand noch die Geschwindigkeit usw an. Das sind aber nur Spielereien und können beliebig angepasst werden.

Mein Script basiert auf einem Beispiel aus der Google-Maps Doku. Damit ihr es nutzen könnt, müsst ihr auf jeden Fall noch einen API-Key bei Google beantragen und in den Aufruf in Zeile 119 einfügen:

<script src=”https://maps.googleapis.com/maps/api/js?key=<GOOGLE MAPS API KEY>=initMap” async defer></script>


<?php

$dbhost = "<DB Server>";
$dbuser = "<DB User>";
$dbpw = "<DB Passwort";
$database = "<Datenbankname>";
 
$db= mysqli_connect ("$dbhost","$dbuser","$dbpw") or die(mysqli_error()." - Serverzugriff gescheitert!");
mysqli_select_db($db, $database) or die(mysqli_error()." - Datenbankzugriff gescheitert!");
 
 $abfrage = "SELECT * FROM `position` ORDER BY pos_date DESC LIMIT 1 ";

 $ergebnis= mysqli_query ($db, $abfrage);

 while ($zeile = mysqli_fetch_array( $ergebnis, MYSQLI_ASSOC))
 {
	$lat = $zeile['pos_breitengrad'];
	$long = $zeile['pos_laengengrad'];
	$geschw = $zeile['pos_speed'];
	$kurs = $zeile['pos_course'];
	$lastdate = $zeile['pos_date'];
	$hoehe = $zeile['pos_heigh'];
	$sat = $zeile['pos_sat'];
 }
 
$l10nDate = new DateTime($lastdate, new DateTimeZone('UTC'));
$l10nDate->setTimeZone(new DateTimeZone('Europe/Berlin'));
$dateInLocal= $l10nDate->format('d.m.Y H:i:s'); 


$abfrage2 = "SELECT * FROM `position` WHERE pos_speed > 2 ORDER BY pos_date DESC Limit 1";
 $ergebnis= mysqli_query ($db, $abfrage2);

 while ($zeile2 = mysqli_fetch_array( $ergebnis, MYSQLI_ASSOC))
 {
	$lastdate2 = $zeile2['pos_date'];
 }

$l10nDate2 = new DateTime($lastdate2, new DateTimeZone('UTC'));
$l10nDate2->setTimeZone(new DateTimeZone('Europe/Berlin'));
$dateInLocal2= $l10nDate2->format('d.m.Y H:i:s'); 

 ?>
 


<html>
  <head>
    <title>WoMoMap</title>
    <meta name="viewport" content="initial-scale=1.0">
    <meta charset="utf-8">
    <style>
      /* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
      #map {
        height: 100%;
		width: 75%;
		float:left;
      }
	  #info {
        height: 100%;
		width: 25%;
		float:left;
		
      }
	  
      /* Optional: Makes the sample page fill the window. */
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
		font-family: Arial;
		font-size:12px;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>
    <script>
      var map;
		function initMap() {
		  const map = new google.maps.Map(document.getElementById("map"), {
			zoom: 12,
			
			<?php
			echo "center: {lat: ".$lat.", lng: ".$long."},";
			?>
			
		  });
		  const image =
			"https://camper-holidays.de/static/womo.png";
		  const marker = new google.maps.Marker({
			
			<?php
			echo "position: {lat: ".$lat.", lng: ".$long."},";
			?>
			map,
			icon: image,
		  });
		   const infowindow = new google.maps.InfoWindow({
			
			<?php
			echo 'content: "<b>Wohnmobil</b><p>('.$geschw.' km/h)<br>Richtung: '.$kurs.'°<br>'.$dateInLocal.'",';
			?>
			});
			 marker.addListener("click", () => {
				infowindow.open({
				  anchor: marker,
				  map,
				  shouldFocus: false,
				});
			  });
			infowindow.open(map, marker);
		}
     
    </script>
    <script src="https://maps.googleapis.com/maps/api/js?key=<GOOGLE MAPS API KEY>=initMap" async defer></script>
 
	<div id="info">
	
	<?php
	
	if ($kurs > 338 OR $kurs <= 22.5) {
		$kursstrg = "Nord";
	}else if ($kurs > 22.5 AND $kurs <= 68) {
		$kursstrg = "Nord-Ost";
	}else if ($kurs > 68 AND $kurs <= 113) {
		$kursstrg = "Ost";
	}else if ($kurs > 113 AND $kurs <= 158) {
		$kursstrg = "Süd-Ost";
	}else if ($kurs > 158 AND $kurs <= 203) {
		$kursstrg = "Süd";
	}else if ($kurs > 103 AND $kurs <= 248) {
		$kursstrg = "Süd-West";	
	}else if ($kurs > 248 AND $kurs <= 293) {
		$kursstrg = "West";
	}else if ($kurs > 293 AND $kurs <= 338) {
		$kursstrg = "Nord-West";
	}
	
	echo "<div style='width:100%; font-size:64px; text-align:center;'>". $geschw . " km/h </div>";
	echo "<p>";
	
	echo "<div style='width:100%; font-size:64px; text-align:center;'>". $kursstrg . "</div>";
	
	echo "<p>";
	
	echo "<div style='width:100%; font-size:64px; text-align:center;'>". $hoehe . "</div>";
	
	echo "<p>";
	
	echo '<div style="width:300px; background-color:#dedede; padding:5px;margin-left:auto; margin-right:auto; border:solid 1px;">';
	echo "Anzahl Sateliten: ".$sat;
	echo "<br>";
	echo "Letzte Fahrt am: ".$dateInLocal2;
	echo '</div>';
	?>


	</div>

 </body>
</html>

Damit habt ihr eure Position immer auf der Google Karte. Ich arbeite gerade noch an einigen Funktionen, dass mir die Route ausgegeben wird. Da ich ja jede Position im 5 Minuten Takt habe, lässt sich das zu einer Linie kombinieren und somit die Route ausgeben. Hier erkläre ich, wie ich das gelöst habe: Ausgabe der GPS-Position als Route

8 Kommentare

  1. Hallo,

    sehr geile Idee! Leider hab ich Dein Script zu spät gefunden, der Urlaub ist gerade vorbei.
    Ich werde Deine Lösung mit einem Raspberry umsetzen, der kann dann im Camper verbleiben und die Daten sind sicher.
    Hast Du inzwischen ein Update bezüglich der Linienfunktion?

    Vielen Dank,
    Hari

  2. Hallo.
    Bin zufällig auf diese Seite gegoogelt und freue mich, dass auch jemand ein Script zum Sammeln der GPS Daten vom Rut955 geschrieben hat.
    Ich habe mir fast die gleiche Lösung letztes Jahr auch programmiert.
    Mein Ansatz ist etwas anders. Ich lasse dem RUT955 alle paar Sekunden die Position an meine Webseite senden. Dort nehme ich die Daten auch per PHP Script an.
    Hier habe ich aber noch eingebaut, dass diese URL nicht irgendwer aufrufen kann und mein Script dann Daten ablegt. Der RUT955 sendet die Daten ja in einem Format. U.a. die Seriennummer des RUT955. Diese kann man wie folgt ermitteln und ggf. im Script abfragen:

    ////////////////////////////////////////////////////////////////////////////////
    // kommen die Daten wirklich von einem RUT Router ?
    // Seriennummer ermitteln
    if(isset($_REQUEST[‘serial_num’])) $sernr = $_REQUEST[‘serial_num’];

    if (strlen($sernr) >>>>>>>>>>>>>>>>>>>>>>>>>>>>> $ipx Raus bei SerNr!”); }
    die($ipx . “Site Status: OK! Missing Data!”);
    exit();
    }

    Ich speichere die Daten nicht komplett immer in eine TXT Datei ab, sondern ich merke mir einfach die letzte gemeldete Position. Sendet der RUT955 nun neue Daten, dann vergleiche ich die neue Position mit der alten Position. Wenn sich das Fahrzeug mehr als 10 Meter vom letzten GPS Punkt weg bewegt hat, dann schreibe ich einen Satz in eine GPX Track Datei, damit der Track(Bewegung) aufgezeichnet wird. (<trkpt lat=…).
    Damit habe ich automatisch immer eine GPX Datei pro Tag (nur wenn sich das Fahrzeug bewegt hat) Diese GPX Dateien kann ich dann einfach später mit Kopf und Fuss versehen und z.B. im GPX-Viewer (einfach mal googeln) anzeigen lassen.
    Im RUT955 habe ich auch das GPS-Geofencing aktiviert auf meine zuhause Position. Wird diese verlassen oder erreicht, sendet der RUT955 automatisch (über das Event) eine SMS an mehrere Handy, mit dem jeweiligen Text, das mein Fahrzeug das zuhause verlassen hat, oder zuhause eingetroffen ist.
    Zur Zeit programmiere ich noch eine Lösung, wo ich Zeitnah per SMS informiert werden will, wenn mein Fahrzeug sich von einer Position weg bewegt.
    Also angenommen ich parke vorm Supermarkt und bin einkaufen. Jemand würde das Fahrzeug entwenden. Dann möchte ich sofort eine entsprechnende SMS bekommen.
    Das kann man natürlich auch direkt im RUT955 konfigurieren, jedoch hat man nicht immer Zeit, dass jedesmal in der Weboberfläche des RUT955 einzustellen.
    Von daher möchte ich meine zu aktuelle Position (also da wo ich grade stehe am Supermarktparkplatz) als Position zum überwachen einstellen. Das will ich dann über meine Webseite realisieren. Also einfach ein Button in meiner Webseite, wo dann ein Script läuft und die aktuelle Position speichert. Wenn dann der RUT955 neue Daten liefert, dann vergleiche ich die in meinem Script auf meiner Webseite. Bewegt sich das Fahrzeug, dann sende ich mir Mails und auch Mails an meinen Mail-To-SMS Gateway, so dass ich dann auch wieder sofort eine SMS bekommen würde.

  3. Vielen Dank für den Bericht. Ich wollte mal fragen, ob du das mit dem Route anzeigen gelöst hast, und ob du das angepasste Script zur Verfügung stellen könntest? Vielen Dank und lieben Gruss aus der Schweiz

  4. Hi Kai,
    danke super Sache.
    Folgende Fragen:
    Kannst du mir bitte mal einen Auszug der “vardump.txt” Datei schicken?
    Wie muss die vom Format aussehen?
    Noch habe ich keinen RUTX Router 🙂

    und ich hätte auf jeden Fall Interesse an deinen tollen Scripten, die die ganze Route anzeigen und nicht nur den einen Standort.
    Hast du die schon fertig?
    Liebe Grüße
    Olli

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein