Teltonika RUT955 NMEA HTTP Post + Parser

RUT955 is highly reliable and secure LTE Industrial router with I/O, GNSS and RS232/RS485 for professional applications. For a given application, several such devices were installed on buses and I was in charge of developing a positioning system using the Teltonika’s built in GPS capabilities. This was somewhat easy, as I worked with NMEA before.

RUT955 features a built in GNSS (GPS) module with external antenna

The RUT955 rich config panel has a section for GNSS positioning (Menu->System->GPS) . There you can enable HTTP Post to have the GPS data sent to a server via the Internet.

Once enabled, the data is sent via HTTP Post as a NMEA string containing most relevant NMEA verbs to the script indicated in the URL Box.

$GPGSA,A,2,05,13,14,15,17,24,28,30,,,,,1.3,0.9,0.8*3F
$GPGSV,5,1,17,05,16,216,21,07,05,088,19,11,,,29,13,81,257,36*40
$GPGSV,5,2,17,14,61,061,25,15,42,300,39,17,27,135,30,19,12,154,35*7B
$GPGSV,5,3,17,20,09,320,25,23,10,323,20,24,14,279,23,28,69,068,37*75
$GPGSV,5,4,17,30,36,081,27,08,02,025,,36,,,39,39,,,35*7A
$GPGSV,5,5,17,41,,,38*71
$GPGGA,112210.00,4538.902790,N,02536.288165,E,1,09,0.9,568.9,M,36.0,M,,*67
$GPVTG,53.9,T,50.2,M,9.4,N,17.4,K,A*14
$GPRMC,112210.00,A,4538.902790,N,02536.288165,E,9.4,53.9,260121,3.7,E,A*09

HOST: ...
ACCEPT: /

To handle the data, I wrote a simply NMEA Parser in PHP:

class ParserCoordinatesTeltonika extends Parser {
	
	protected $deviceData;

	function string2double($param) {
		$brk = strpos($param,".") - 2;
		if($brk < 0){ $brk = 0; }

		$minutes = substr($param, $brk);
		$degrees = substr($param, 0,$brk);

		return $degrees + $minutes/60;
	}

	// file is HTTP Post body content, id is router/device id
	public function __construct($file, $id) {
		if (!$file)
			throw new Exception('Invalid file');
		if (!$id)
			throw new Exception('Invalid id');
		
		$latitude = 0;
		$longitude = 0;
		$speed = 0;
		$altitude = 0;
	
		$rmc = strtok(strstr($file, '$GPRMC'), "\n");
		if ($rmc) { 
			//$GPRMC,121720.00,A,4538.815495,N,02535.423142,E,15.7,281.7,260121,3.7,E,A*02
			$params = explode(",", $rmc);
			//if ($params[2] != 'A') echo "Navigation warning error";

			$latitude = string2double($params[3]);
			if ($params[4] ==  'S') $latitude *= -1;

			$longitude = string2double($params[5]);
			if ($params[6] ==  'W') $longitude *= -1;

			$speed = floatval($params[7]) * 1.852;
		} else
			throw new Exception('Invalid RMC coordinates');

		$gga = strtok(strstr($file, '$GPGGA'), "\n");
		if ($gga) { 
			echo "<hr>".$gga;
			//$GPGGA,121706.00,4538.799605,N,02535.532694,E,1,09,0.9,579.1,M,36.0,M,,*60
			$params = explode(",", $gga);
			//if ($params[0] != '$GPRMC') echo "Strange error";
			
			$latitude = string2double($params[2]);
			if ($params[3] ==  'S') $latitude *= -1;

			$longitude = string2double($params[4]);
			if ($params[5] ==  'W') $longitude *= -1;

			$altitude = floatval($params[9]);
			//echo "GGA " . $latitude ."," . $longitutde. " alt:".$altitude;
		} else
			throw new Exception('Invalid GGA coordinates');

		//echo "lat:" . $latitude . " long:" .$longitude. " alt:".$altitude." speed:".$speed;
		

		
		
		$this->deviceData = new DeviceCoordinates($id);
		$this->deviceData->fields["time"] = time();
		$this->deviceData->fields["latitude"] = (string)$latitude;
		$this->deviceData->fields["longitude"] = (string)$longitude
        $this->deviceData->fields["altitude"] = (string)$altitude;
		$this->deviceData->fields["speed"] = (string)$speed;
	}

	public function getDeviceData() {
		return $this->deviceData;
	}
}

?>

The Router sends GPS data about every 18seconds , by default. With the code above, got the location data in no time:

1611669411> lat:45.616936433333 long:25.652437083333 alt:649.6 speed:28.8912

And the application result, real time #airquality monitoring in Brasov, with sensors installed on buses:

Leave a Reply