Mikrotik GPS

John hansen6 years ago

Can anybody help me connecting my mikrotik routers GPS signal to the traccar server.
Thanks guys

Luke Crooks6 years ago

Hi John,

If you take a look here:

https://wiki.mikrotik.com/wiki/Manual:GPS-tracking

It explains that you can create your own script to post whatever data you want (to any server), my suggestion would be to copy the structure of say the OSMAND protocol, which is very simple:

https://www.traccar.org/osmand/

You can the set a custom frequency for the connection (or any other features you might need).

Lukas Z.6 years ago

Hi John,
have You finished Mikrotik integration?

John hansen6 years ago

Not yet sorry

Ruben Vanhoutte6 years ago

Hi All,

I've created a script that updates a traccar server.
I've been running this in my own test env for a few days now.
It uploads timestamp, lat, lon, altitude, nr of satelites, speed and course (in degrees)

I've uploaded the script to Github @ https://github.com/CreasaBE/Mikrotik_Scripts/blob/master/GPS/Traccar/gps_traccar_updater

Any questions or comments, shoot!

grtz

Sasha6 years ago

That's amazing, Ruben! Thanks for that!

assimakopoulos5 years ago

hi!
I am trying to make it work but always i get wrong coordinates !!!
Anyone any suggestions ?
The script tha i am using is

:global fncJD do={
:local months [:toarray "jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec"];
:local jd
:local M [:pick $1 0 3];
:local D [:pick $1 4 6];
:local Y [:pick $1 7 11];
:for x from=0 to=([:len $months] - 1) do={
   :if ([:tostr [:pick $months $x]] = $M) do={:set M ($x + 1) } 
   }
:if ( $M = 1 || $M = 2) do={
    :set Y ($Y-1);
    :set M ($M+12);
}
:local A ($Y/100)
:local B ($A/4)
:local C (2-$A+$B)
:local E ((($Y+4716) * 36525)/100)
:local F ((306001*($M+1))/10000)
:local jd ($C+$D+$E+$F-1525)
:return $jd
};

:global timestamp do={
:global fncJD $fncJD
:local currtime [/system clock get time];
:local jdnow [$fncJD [/system clock get date]]
:local days ($jdnow - 2440587)
:local ore [:pick $currtime 0 2]
:local minute [:pick $currtime 3 5]
:local secunde [:pick $currtime 6 8]
:return (($days * 86400) + ($ore * 3600) + ($minute * 60) + $secunde - [/system clock get gmt-offset]);
}

:system gps monitor once file="gps.txt";
:interface lte info lte1 file="lte1info.txt";

:local gpstext [/file get gps.txt contents];

:local serverurl "10.71.148.112";
:local serverport "5055";


:local valid false;
:local zeros "";

# GPS Info
:local myspeed  [:find $gpstext "speed" -1];
:local myalt  [:find $gpstext "altitude" -1];
:local mytime [:find $gpstext "date-and-time" -1];
:local longstart [:find $gpstext "longitude" -1];
:local longend [:find $gpstext "\n" $longstart];
:local latstart [:find $gpstext "latitude" -1];
:local latend [:find $gpstext "\n" $latstart];
:local validstart [:find $gpstext "valid" -1];
:local validend [:find $gpstext "\n" $validstart];
:local speedstart [:find $gpstext "speed"];
:local speedend [:find $gpstext "." $speedstart];
:local speed [;pick $gpstext ($speedstart +7) ($speedend +3)];
:local altitudestart [:find $gpstext "altitude"];
:local altitudeend [:find $gpstext "." $altitudestart];
:local altitude [;pick $gpstext ($altitudestart +10) ($altitudeend +3)];
:local satellitesstart [:find $gpstext "satellites"];
:local satellitesend [:find $gpstext "\n" $satellitesstart];
:local satellites [;pick $gpstext ($satellitesstart +12) ($satellitesend)];

:local bearingstart [:find $gpstext "true-bearing"];
:local bearingend [:find $gpstext "\n" $bearingstart];
:local bearing [;pick $gpstext ($bearingstart +15) ($bearingend -10)];




# LTE Info
:local lte1info [:file get lte1info.txt contents];
:local imeistart [:find $lte1info "imei"];
:local imeiend [:find $lte1info "\n" $imeistart];
:local imei [:pick $lte1info ($imeistart +6) ($imeiend)];
:local techstart [:find $lte1info "access"];
:local techend [:find $lte1info "\n" $techstart];
:local techno [:pick $lte1info ($techstart +19) ($techend)];
:local technology;
:if ($techno ="GSM compact") do={[:set technology "GSM";]}
:if ($techno ="3G") do={:set technology "UMTS";}
:if ($techno ="Evolved 3G (LTE)") do={[:set technology "LTE";]}


:if ([:find $gpstext "yes" $validstart] > 0) do={:set valid true;};

:local longitude [:pick $gpstext ($longstart + 11) $longend];
:local degreestart [:find $longitude " " -1];
:local minutestart [:find $longitude " " $degreestart];
:local secondstart [:find $longitude "'" $minutestart];

:local secondend;
:local secfract;

:if ([:len [:find $longitude "." 0]] < 1) do={
    :set secondend [:find $longitude "'" $secondstart];
    :set secfract "0";
} else={
    :set secondend [:find $longitude "." $secondstart];
    :set secfract [:pick $longitude ($secondend + 1) ($secondend + 2)];
};

:local longdegree;
:local longdegreelink;

:if ([:pick $longitude 0 1] = "W") do={
    :set longdegree "-";
    :set longdegreelink "W";
} else={
    :set longdegree "+";
    :set longdegreelink "E";
};

:set longdegree ($longdegree . [:pick $longitude 2 $minutestart]);
:set longdegreelink ($longdegreelink . [:pick $longitude 2 $minutestart]);
:local longmin [:pick $longitude ($minutestart + 1) $secondstart];
:local longsec [:pick $longitude ($secondstart + 2) $secondend];
:local longfract ((([:tonum $longmin] * 6000) + ([:tonum $longsec] * 100) + ([:tonum $secfract] * 10) ) / 36);

:while (([:len $zeros] + [:len $longfract]) < 4) do={
    :set zeros ($zeros . "0");
};

:local newlong ($longdegree . "." . $zeros . $longfract);
:local newlonglink ($longdegreelink . "." . $zeros . $longfract);

:local latitude [:pick $gpstext (latstart + 10) $latend];
:set degreestart [:find $latitude " " -1];
:set minutestart [:find $latitude " " $degreestart];
:set secondstart [:find $latitude "'" $minutestart];

:if ([:len [:find $latitude "." 0]] < 1) do={
    :set secondend [:find $latitude "'" $secondstart];
    :set secfract "0";
} else={
    :set secondend [:find $latitude "." $secondstart];
    :set secfract [:pick $latitude ($secondend + 1) ($secondend +2)];
};

:local latdegree;
:local latdegreelink;

:if ([:pick $latitude 0 1] = "N") do={
    :set latdegree "+";
    :set latdegreelink "N";
} else={
    :set latdegree "-";
    :set latdegreelink "S";
};

:set latdegree ($latdegree . [:pick $latitude 2 $minutestart]);
:set latdegreelink ($latdegreelink . [:pick $latitude 2 $minutestart]);
:local latmin [:pick $latitude ($minutestart + 1) $secondstart];
:local latsec [:pick $latitude ($secondstart + 2) $secondend];
:local latfract ((([:tonum $latmin] * 6000) + ([:tonum $latsec] * 100) +([:tonum $secfract] * 10)) / 36);

:set zeros "";

:while (([:len $zeros] + [:len $latfract]) < 4) do={
    :set zeros ($zeros . "0");
};

:local newlat ($latdegree . "." . $zeros . $latfract);
:local newlatlink ($latdegreelink . "." . $zeros . $latfract);

:local coordinates ($newlong . "," . $newlat);

:global fncJD do={
:local months [:toarray "jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec"];
:local jd
:local M [:pick $1 0 3];
:local D [:pick $1 4 6];
:local Y [:pick $1 7 11];
:for x from=0 to=([:len $months] - 1) do={
   :if ([:tostr [:pick $months $x]] = $M) do={:set M ($x + 1) } 
   }
:if ( $M = 1 || $M = 2) do={
    :set Y ($Y-1);
    :set M ($M+12);
}
:local A ($Y/100)
:local B ($A/4)
:local C (2-$A+$B)
:local E ((($Y+4716) * 36525)/100)
:local F ((306001*($M+1))/10000)
:local jd ($C+$D+$E+$F-1525)
:return $jd
};

:global timestamp do={
:global fncJD $fncJD
:local currtime [/system clock get time];
:local jdnow [$fncJD [/system clock get date]]
:local days ($jdnow - 2440587)
:local ore [:pick $currtime 0 2]
:local minute [:pick $currtime 3 5]
:local secunde [:pick $currtime 6 8]
:return (($days * 86400) + ($ore * 3600) + ($minute * 60) + $secunde - [/system clock get gmt-offset]);
}

# :log info message="GPS Script: Posting update";

:local mystamp [$timestamp];

:do {/tool fetch keep-result=no url=("http://" . $serverurl . ":" . $serverport ."/\?id=$imei&lat=$newlat&lon=$newlong×tamp=$mystamp&altitude=$altitude&speed=$speed&course=$bearing&satelites=$satellites&gps=$satellites")
} on-error={:log error message="Fetch failed..."}

# :log info message="GPS Script: Posting update DONE";
Maia Lenart5 years ago

Hi...it does not post lat/long data to the sqlite database. I get data in the db for "time" and "added" but do not get lat/long data. I noticed in the PHP script for index,php, the data values are "TEXT". Does leafy require text values? I would think you would want to use "FLOAT". Tried all parameters (NUMERIC, INTEGER) etc. Just cant get lat/long info into sqlite3.

Maksim4 years ago

Hi,

I rewrote the script without using intermediate files.
Intermediate files can "kill" flash inside Mikrotik.

My working version (please change serverurl, serverport and id):

:local serverurl "SERVER";
:local serverport "5055";
:local id "IMEI";

:global Lat
:global Lon
:global Altitude
:global Bearing
:global Speed
:global Satellites

/system gps monitor once do={
:set $Lat $("latitude")
:set $Lon $("longitude")
:local altitudetxt $("altitude")
:set $Altitude [:pick $altitudetxt 0 5]
:local bearinval $("true-bearing")
:set $Bearing [:pick $bearinval 0 9]
:local speedtxt $("speed")
:set $Speed [:pick $speedtxt 0 8]
:set $Satellites $("satellites")
}

:local longdegree;
:set longdegree "+";
:local latdegree;
:set latdegree "+";

:set Lon ($longdegree . $Lon);
:set Lat ($latdegree . $Lat);

:global fncJD do={
:local months [:toarray "jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec"];
:local jd
:local M [:pick $1 0 3];
:local D [:pick $1 4 6];
:local Y [:pick $1 7 11];
:for x from=0 to=([:len $months] - 1) do={
   :if ([:tostr [:pick $months $x]] = $M) do={:set M ($x + 1) }
   }
:if ( $M = 1 || $M = 2) do={
    :set Y ($Y-1);
    :set M ($M+12);
}
:local A ($Y/100)
:local B ($A/4)
:local C (2-$A+$B)
:local E ((($Y+4716) * 36525)/100)
:local F ((306001*($M+1))/10000)
:local jd ($C+$D+$E+$F-1525)
:return $jd
};

:global timestamp do={
:global fncJD $fncJD
:local currtime [/system clock get time];
:local jdnow [$fncJD [/system clock get date]]
:local days ($jdnow - 2440587)
:local ore [:pick $currtime 0 2]
:local minute [:pick $currtime 3 5]
:local secunde [:pick $currtime 6 8]
:return (($days * 86400) + ($ore * 3600) + ($minute * 60) + $secunde - [/system clock get gmt-offset]);
}

:local mystamp [$timestamp];

:log info message="GPS Script: Posting update. lt=$Lat, lon=$Lon timestamp=$mystamp altitude=$Altitude speed=$Speed course=$Bearing satelites=$Satellites gps=$Satellites";

:do {/tool fetch keep-result=no check-certificate=no url=("http://" . $serverurl . ":" . $serverport ."/\?id=$id&lat=$Lat&lon=$Lon×tamp=$mystamp&altitude=$Altitude&speed=$Speed&course=$Bearing&satelites=$Satellites&gps=$Satellites")
} on-error={:log error message="Fetch failed..."}

:log info message="GPS Script: Posting update DONE";
Maksim4 years ago

Some changes (added "valid"), new version:

:local serverurl "SERVER";
:local serverport "5055";
:local id "IMEI";

:global Lat
:global Lon
:global Altitude
:global Bearing
:global Speed
:global Satellites
:global Valid

/system gps monitor once do={
:set $Lat $("latitude")
:set $Lon $("longitude")
:local altitudetxt $("altitude")
:set $Altitude [:pick $altitudetxt 0 5]
:local bearinval $("true-bearing")
:set $Bearing [:pick $bearinval 0 9]
:local speedtxt $("speed")
:set $Speed [:pick $speedtxt 0 8]
:set $Satellites $("satellites")
:set $Valid $("valid")
}

:local longdegree;
:set longdegree "+";
:local latdegree;
:set latdegree "+";

:set Lon ($longdegree . $Lon);
:set Lat ($latdegree . $Lat);

:global fncJD do={
:local months [:toarray "jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec"];
:local jd
:local M [:pick $1 0 3];
:local D [:pick $1 4 6];
:local Y [:pick $1 7 11];
:for x from=0 to=([:len $months] - 1) do={
   :if ([:tostr [:pick $months $x]] = $M) do={:set M ($x + 1) }
   }
:if ( $M = 1 || $M = 2) do={
    :set Y ($Y-1);
    :set M ($M+12);
}
:local A ($Y/100)
:local B ($A/4)
:local C (2-$A+$B)
:local E ((($Y+4716) * 36525)/100)
:local F ((306001*($M+1))/10000)
:local jd ($C+$D+$E+$F-1525)
:return $jd
};

:global timestamp do={
:global fncJD $fncJD
:local currtime [/system clock get time];
:local jdnow [$fncJD [/system clock get date]]
:local days ($jdnow - 2440587)
:local ore [:pick $currtime 0 2]
:local minute [:pick $currtime 3 5]
:local secunde [:pick $currtime 6 8]
:return (($days * 86400) + ($ore * 3600) + ($minute * 60) + $secunde - [/system clock get gmt-offset]);
}

:local mystamp [$timestamp];

:log info message="GPS Script: Posting update. lt=$Lat, lon=$Lon timestamp=$mystamp altitude=$Altitude speed=$Speed course=$Bearing satelites=$Satellites gps=$Satellites valid=$Valid";

:do {/tool fetch keep-result=no check-certificate=no url=("http://" . $serverurl . ":" . $serverport ."/\?id=$id&lat=$Lat&lon=$Lon×tamp=$mystamp&altitude=$Altitude&speed=$Speed&course=$Bearing&satelites=$Satellites&gps=$Satellites&valid=$Valid")
} on-error={:log error message="Fetch failed..."}

:log info message="GPS Script: Posting update DONE";
Sasha4 years ago

Hey Maksim, thank you for the great work!
I'll give it a try very soon as well.
Just one question, what do you put as IMEI?

Maksim4 years ago

Hi Sasha Japaridze,
It is used by the IMEI from LTE modem, But in fact it does not matter at all what is written there - this is an identifier, it must match what is set in the Traccer.

Liviu Zaharia4 years ago

Hi @Maksim,

Thanks for your the support.
Your script works but there are some typos in there, maybe the copy-paste did induce some weird characters.

Eg:

“$Lat&lon=$Lon×tamp“
“ lt=$Lat”

Maybe there are others but it was late. ;)

Do you have the git version for this script?

Thanks

Maksim4 years ago

Dear Liviu Zaharia,

Apparently the code is distorted, I try again:

:log info message="GPS Script: Posting update. lt=$Lat, lon=$Lon timestamp=$mystamp altitude=$Altitude speed=$Speed course=$Bearing satelites=$Satellites gps=$Satellites valid=$Valid";

:do {/tool fetch keep-result=no check-certificate=no url=("http://" . $serverurl . ":" . $serverport ."/\?id=$id&lat=$Lat&lon=$Lon×tamp=$mystamp&altitude=$Altitude&speed=$Speed&course=$Bearing&satelites=$Satellites&gps=$Satellites&valid=$Valid")
} on-error={:log error message="Fetch failed..."}
Sasha4 years ago

Hi @Maksim,

Can you please paste the final working code. Thank you!
Will hook up LTAP mini tomorrow, see if it works ;)