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. Wenn gewünscht veröffentliche ich das dann gerne noch.

Kommentieren Sie den Artikel

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