Geschrieben von: Sven
Kategorie: Internet
Zugriffe: 2726

TK102 GPS Tracker

Vor Jahren schon habe ich mir einen solchen GPS Tracker gekauft und immer nur per SMS mit einer einfachen prepaid SIM-Karte betrieben.
Per GPRS wollte ich meine realen Standortdaten nicht einfach irgendwo hochladen. Daher habe ich den Entschluß gefasst die Daten auf meinem eigenen Server zu speichern.

1. Schritt das TK102 per SMS einstellen.

    begin123456apn123456
    internetadminip123456 xxx.xxx.xxx.xxx pppp  (damit hier nicht andere Daten eintreffen xxx ist die IP von dem Server wohin die Daten geschickt werden sollen. pppp ist der Port)
    t005m***n123456 (alle 5Minuten für eine unbestimmte Zeit werden die Standortdaten verschickt. t030sxxxn würde entsprechend alle 30Sekunden die Daten schicken)
Mehr Einstellung kann und braucht der Tracker selber auch nicht.

2. Daten auf dem Server xxx.xxx.xxx.xxx empfangen.

Dies erfolgt mittels eines kleinen Perl scriptes, welches ich im Internet gefunden (http://xmodulo.com/how-to-write-simple-tcp-server-and-client-in-perl.html) habe.
Damit das auf einem anderen Server läuft als die Webseite übergebe ich die gewonnen Daten per PHP, was dann wie folgt aussieht:

#!/usr/bin/perl
use IO::Socket::INET;
use URI;
use LWP::UserAgent;

# PHP page
my $browser = LWP::UserAgent->new;
my $url = URI->new('http://domain/tk102.php');
 
# auto-flush on socket
$| = 1;
 
# creating a listening socket
my $socket = new IO::Socket::INET (
    LocalHost => '0.0.0.0',
    LocalPort => 'pppp',
    Proto => 'tcp',
    Listen => 5,
    Reuse => 1
);
die "cannot create socket $!\n" unless $socket;
print "server waiting for client connection on port 7654\n";
 
while(1)
{
    # waiting for a new client connection
    my $client_socket = $socket->accept();
 
    # get information about a newly connected client
    my $client_address = $client_socket->peerhost();
    my $client_port = $client_socket->peerport();
    print "connection from $client_address:$client_port\n";
 
    # read up to 1024 characters from the connected client
    my $data = "";
    $client_socket->recv($data, 1024);
    print "received data: $data\n";
    $url->query_form('msg' => $data, );
    print $url, "\n"; # so sieht dir URL aus
    my $response = $browser->get($url);
    # write response data to the connected client
    $data = "ok";
    $client_socket->send($data);
 
    # notify client that response has been sent
    shutdown($client_socket, 1);
}
 
$socket->close();

Mit dem Script gibt es noch ein bekanntes Problem: Es muss noch ein Timeout eingebaut werden damit der Socket, sollte die Datenverbindung abbrechen auch wieder geschlossen wird.

Damit werden jetzt Daten empfangen die wie folgt aussehen:  
1609130840,<Rufnummer>,GPRMC,064021.000,A,5115.0305,N,00646.2574,E,16.41,240.51,130916,,,A*55,L,imei:123456789012345,107^Y=
       1         ,         2          ,    3      ,    4          ,5,       6      ,7,         8       ,9,   10 , 11     ,    12   ,,,   15 ,16,       17                     ,18

1. Datum und Uhrzeit yymmddHHMM
2. Rufnummer über die der Befehl eingesetzt wurde
3. GPRMC = Recomended minimum specific GPS data
4. Uhrzeit UTC daher weicht es hier um -2h zu Feld 1 ab.
5. Warnung A = OK , V = Warnung
6. Latitude: 51Grad 15.0305 min.
7. Hemisphäre (N) North / (S) South
8. Longitude: 6 Grad 46.2574 min.
9. (E) Ost, (W) West
10. Geschwindigkeit über Grund
11. Richtung in Grad
12. Datum ddmmyy
13. 
14.
15.
16. Batteriezustand
17. imei des Tk102
18. 

3. Daten in MySQL Tabelle schreiben:

Diese Daten werden per an den Webserver zur weiteren Verarbeitung übergeben:
http://domain//tk102.php?msg=%0A1609130840%2C<Rufnummer>%2CGPRMC%2C064021.000%2CA%2C5115.0305%2CN%2C00646.2574%2CE%2C16.41%2C240.51%2C130916%2C%2C%2CA*55%2CL%2Cimei%3A123456789012345%2C107%19

 

<?php
/*modified 08.08.2016 09:10 */
/* Config */
include_once("config.php");
include_once ("opendb.php");

function dec2grad($val) { 
    $rest = substr($val, -7);
    $grad = str_replace($rest,"",$val);
    $val = floatval($rest); 
    $grad = floor($grad); 
    $dec = floor($val / 0.00006);
    return($grad.'.'.$dec); 
}  
function date2unixtime($var) {
    $dateTime = \DateTime::createFromFormat('ymdHi|', $var);
    $timestamp2 = $dateTime->getTimestamp();
    //echo $timestamp2;
    return ($timestamp2);
}    
    
$msg = $_GET["msg"];
$teile = explode(",", $msg);
$LAT = dec2grad($teile[5]);
$HEMIPARESISLAT=$teile[6];
$LON = dec2grad($teile[7]);
$HEMIPARESISLON=$teile[8];
$pos   = strripos($msg, ','); //search the last comma to remove strange char
$DIRECTION = $teile[10];
$length = strlen($msg);       // length string
$smsg  = substr($msg, 0, ($length - $pos)*-1  ); //cut off char after the last comma
$RAW_MESSAGE = $smsg;
$SPEED = $teile[9];
$imei = 'imei:';
$imeipos16 = strpos($teile[16],$imei); //imei in array 16
$imeipos17 = strpos($teile[17],$imei); //imei in array 17
if (strpos($HEMIPARESISLAT, 'S') !== false){
  $LAT = ($LAT*-1);
}
if (strpos($HEMIPARESISLON, 'W') !== false){
  $LON = ($LON*-1);
}
if ($imeipos16 !== false){
  $DEVICE_ID = str_replace($imei,"",$teile[16]);
}
if ($imeipos17 !== false){
  $DEVICE_ID = str_replace($imei,"",$teile[17]);
}
$TYPE_EVENT = $teile[2];
$RECORDED_AT =  $teile[0];
$TIMESTAMP =  date2unixtime($teile[0]);
$eintrag = "INSERT INTO jos_hidnseek (lat, lon, speed, timestamp, device_id, recorded_at, type_event, direction, raw_message) VALUES ('$LAT', '$LON','$SPEED','$TIMESTAMP','$DEVICE_ID','$RECORDED_AT','$TYPE_EVENT','$DIRECTION','$RAW_MESSAGE')";
$eintragen = mysql_query($eintrag);

include_once 'closedb.php';

?>

Was passiert in dem Script:
In die opendb.php habe ich die Verbindungsdaten zu meinem MySql augelagert. 
Die Funktion dec2grad ändert das Format von Grad+Minuten (51Grad 15.0305) Minuten in ein Dezimales format (51.250508). Dies ist, wie ich finde, später einfacher zu verarbeiten.
Die Funktion date2unixtime ändert das eingehende Datum/Uhrzeit in einen UNIX timestamp um. 
Mit $_Get übernehme ich den String und speicher ihn in eine $msg. Da die einzelnen Daten schön kommasepariert sind kann ich sie mit explode(",", $msg) in ein Array umwandeln und somit jedes Feld für sich bearbeiten.

Geschrieben werden die Daten nun in eine Tabelle, die schon aus HidnSeek existiert.