├── MC7710-enable-gps.txt
├── README.md
├── gps-to-email
├── gps-to-url
├── mikrotik_genxml.php
├── mikrotikgps.php
├── mikrotiklocation.html
├── phpsqlajax_dbinfo.php
├── schedule-command
└── usb-reset
/MC7710-enable-gps.txt:
--------------------------------------------------------------------------------
1 | 1 - Turn off "DirectiIP" mode.
2 | /port firmware set ignore-directip-modem=yes
3 |
4 | 2 - Restart RouterOS.
5 | /system reboot
6 |
7 | 3 - Open a terminal to the modem on the 3 channel.
8 | /system serial-terminal usb1 channel=3
9 |
10 | 4 - Run the following AT commands.
11 | AT!ENTERCND="A710"
12 | AT!GPSAUTOSTART=1,1,255,1000,1
13 |
14 | 5 - Close the terminal session
15 | > Ctrl+A >>>> Q
16 |
17 | 6 - Turn on "DirectiIP" mode.
18 | /port firmware set ignore-directip-modem=no
19 |
20 | 7 - Restart RouterOS.
21 | /system reboot
22 |
23 | 8 - Enable GPS.
24 | /system gps set port=usb1 channel=0 enabled=yes
25 |
26 | 9 - Test the GPS is working.
27 | /system gps monitor
28 |
29 | [admin@MikroTik] > system gps monitor
30 | date-and-time: jan/01/2015 23:24:54
31 | latitude: N XX XX' XX.XXX''
32 | longitude: E XX XX' XX.XXX''
33 | altitude: 20.600000m
34 | speed: 0.000000 km/h
35 | destination-bearing: none
36 | true-bearing: 180.699997 deg. True
37 | magnetic-bearing: 180.699997 deg. Mag
38 | valid: yes
39 | satellites: 7
40 | -- [Q quit|D dump|C-z pause]
41 |
42 | If you see the above with latitude and longitude coordinates then GPS is working.
43 | Copy and paste these to Google maps to check the accuracy.
44 |
45 | NOTE: You will need a GPS antenna connected to the middle "GPS" u.fl connector and the GPS antenna will need to be outside
46 | (with a clear view of the sky) to work.
47 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | mikrotik-gps
2 | ============
3 |
4 | Scripts for tracking Mikrotik Routers by sending GPS coordinates to an e-mail address.
5 |
6 | Requires a Mikrotik RoutherBoard + USB GPS device or LTE modem with built-in GPS receiver.
7 |
8 | gps-to-email script originally from the Mikrotik Wiki:-
9 | http://wiki.mikrotik.com/wiki/GPS_text_file_converter_to_Google_Earth/Maps
10 |
11 | Testing done using a RB912UAG-2HPnD with Sierra Wireless MC7710 (FW version needs to be "03.05.24" and GPS autostart NMEA output needs to be enabled. See "MC7710-enable-gps.txt" for instructions.
12 |
13 | /!\ PLEASE NOTE /!\
14 | -------------
15 |
16 | The GPS package doesn't work correctly in the current firmware release (RouterOS v6.24) you'll need to upgrade to "RouterOS v6.25rc" once available and the final release as soon as that is available.
17 |
18 | gps-to-email
19 | ------------
20 |
21 | Script to send the GPS coordinated to an e-mail address.
22 | E-Mails are only sent when the position has changed.
23 | The script has to be scheduled to run using "system scheduler". Depending on your requirements this could be scheduled to run the gps-to-email script every 20 seconds, 5 minutes, 30 minutes, hour or daily.
24 |
25 | gps-to-url
26 | ----------
27 |
28 | This script is a modified version of the above gps-to-email script. Instead of sending an e-mail it uses fetch to request a URL. This URL is the "mikrotikgps.php" file which uses php GET to get the data from the URL and push it into a database. This makes it possible to then use this data to build a map using the coordinates and other data.
29 |
--------------------------------------------------------------------------------
/gps-to-email:
--------------------------------------------------------------------------------
1 | # CHANGE BELOW E-MAIL ADDRESS
2 | :local email "myuser@mydomain.com";
3 |
4 | :system gps monitor file="gps.txt";
5 | :global gpstext [/file get gps.txt contents];
6 | :local longstart [:find $gpstext "longitude" -1];
7 | :local longend [:find $gpstext "\n" $longstart];
8 | :local latstart [:find $gpstext "latitude" -1];
9 | :local latend [:find $gpstext "\n" $latstart];
10 | :local validstart [:find $gpstext "valid" -1];
11 | :local validend [:find $gpstext "\n" $validstart];
12 | :local valid false;
13 | :local zeros "";
14 |
15 | :if ([:find $gpstext "yes" $validstart] > 0) do={:set valid true;};
16 |
17 | :global longitude [:pick $gpstext ($longstart + 11) $longend];
18 | :local degreestart [:find $longitude " " -1];
19 | :local minutestart [:find $longitude " " $degreestart];
20 | :local secondstart [:find $longitude "'" $minutestart];
21 |
22 | :local secondend;
23 | :local secfract;
24 |
25 | :if ([:len [:find $longitude "." 0]] < 1) do={
26 | :set secondend [:find $longitude "'" $secondstart];
27 | :set secfract "0";
28 | } else={
29 | :set secondend [:find $longitude "." $secondstart];
30 | :set secfract [:pick $longitude ($secondend + 1) ($secondend + 2)];
31 | };
32 |
33 | :local longdegree;
34 | :local longdegreelink;
35 |
36 | :if ([:pick $longitude 0 1] = "W") do={
37 | :set longdegree "-";
38 | :set longdegreelink "W";
39 | } else={
40 | :set longdegree "+";
41 | :set longdegreelink "E";
42 | };
43 |
44 | :set longdegree ($longdegree . [:pick $longitude 2 $minutestart]);
45 | :set longdegreelink ($longdegreelink . [:pick $longitude 2 $minutestart]);
46 | :local longmin [:pick $longitude ($minutestart + 1) $secondstart];
47 | :local longsec [:pick $longitude ($secondstart + 2) $secondend];
48 | :local longfract ((([:tonum $longmin] * 6000) + ([:tonum $longsec] * 100) + ([:tonum $secfract] * 10) ) / 36);
49 |
50 | :while (([:len $zeros] + [:len $longfract]) < 4) do={
51 | :set zeros ($zeros . "0");
52 | };
53 |
54 | :global newlong ($longdegree . "." . $zeros . $longfract);
55 | :global newlonglink ($longdegreelink . "." . $zeros . $longfract);
56 |
57 | :global latitude [:pick $gpstext (latstart + 10) $latend];
58 | :set degreestart [:find $latitude " " -1];
59 | :set minutestart [:find $latitude " " $degreestart];
60 | :set secondstart [:find $latitude "'" $minutestart];
61 |
62 | :if ([:len [:find $latitude "." 0]] < 1) do={
63 | :set secondend [:find $latitude "'" $secondstart];
64 | :set secfract "0";
65 | } else={
66 | :set secondend [:find $latitude "." $secondstart];
67 | :set secfract [:pick $latitude ($secondend + 1) ($secondend +2)];
68 | };
69 |
70 | :local latdegree;
71 | :local latdegreelink;
72 |
73 | :if ([:pick $latitude 0 1] = "N") do={
74 | :set latdegree "+";
75 | :set latdegreelink "N";
76 | } else={
77 | :set latdegree "-";
78 | :set latdegreelink "S";
79 | };
80 |
81 | :set latdegree ($latdegree . [:pick $latitude 2 $minutestart]);
82 | :set latdegreelink ($latdegreelink . [:pick $latitude 2 $minutestart]);
83 | :local latmin [:pick $latitude ($minutestart + 1) $secondstart];
84 | :local latsec [:pick $latitude ($secondstart + 2) $secondend];
85 | :local latfract ((([:tonum $latmin] * 6000) + ([:tonum $latsec] * 100) +([:tonum $secfract] * 10)) / 36);
86 |
87 | :set zeros "";
88 |
89 | :while (([:len $zeros] + [:len $latfract]) < 4) do={
90 | :set zeros ($zeros . "0");
91 | };
92 |
93 | :global newlat ($latdegree . "." . $zeros . $latfract);
94 | :global newlatlink ($latdegreelink . "." . $zeros . $latfract);
95 |
96 | :global coordinates ($newlong . "," . $newlat);
97 |
98 | :global linkout "http://maps.google.com?q=$newlatlink+$newlonglink";
99 | :global SMlinkout "http://www.openstreetmap.org/?lat=$newlat&lon=$newlong&zoom=8&layers=M";
100 |
101 | :global kmlout "
102 |
103 |
104 | My router
105 | My router's location
106 |
107 | $coordinates
108 |
109 |
110 |
111 | ";
112 |
113 | :if (valid) do={
114 | :global oldpos;
115 |
116 | :if ($oldpos != $coordinates) do={
117 | /file set [/file find name=gps.kml] contents=$kmlout
118 | /tool e-mail
119 | send to=$email subject="Router move" body="Moved to $latitude $longitude\r\n$linkout\r\n$SMlinkout" file=gps.kml
120 | :set oldpos $coordinates;
121 | };
122 | } else={
123 | /tool e-mail
124 | send to=$email subject="Router gps position invalid" body="Router gps position invalid"
125 | };
126 |
--------------------------------------------------------------------------------
/gps-to-url:
--------------------------------------------------------------------------------
1 | # CHANGE BELOW SERVER BELOW TO YOUR SERVERS DOMAIN OR IP ADDRESS
2 | :local server "change.me.com";
3 |
4 | # Get GPS info and find variables
5 | :system gps monitor file="gps.txt";
6 | :global gpstext [/file get gps.txt contents];
7 | :local datestart [:find $gpstext "time: "];
8 | :local dateend [:find $gpstext "latitude"];
9 | :local date [:pick $gpstext ($datestart +6) ($dateend -14)]
10 | :local longstart [:find $gpstext "longitude" -1];
11 | :local longend [:find $gpstext "\n" $longstart];
12 | :local latstart [:find $gpstext "latitude" -1];
13 | :local latend [:find $gpstext "\n" $latstart];
14 | :local validstart [:find $gpstext "valid" -1];
15 | :local validend [:find $gpstext "\n" $validstart];
16 | :local speedstart [:find $gpstext "speed"];
17 | :local speedend [:find $gpstext "." $speedstart];
18 | :local speed [;pick $gpstext ($speedstart +7) ($speedend +3)];
19 | :local altitudestart [:find $gpstext "altitude"];
20 | :local altitudeend [:find $gpstext "." $altitudestart];
21 | :local altitude [;pick $gpstext ($altitudestart +10) ($altitudeend +3)];
22 | :local satellitesstart [:find $gpstext "satellites"];
23 | :local satellitesend [:find $gpstext "\n" $satellitesstart];
24 | :local satellites [;pick $gpstext ($satellitesstart +12) ($satellitesend)];
25 | :local valid false;
26 | :local zeros "";
27 |
28 | # Get Ethernet details and set mac variable
29 | :interface ethernet print detail from=ether1 file=eth1details.txt
30 | :global eth1details [/file get "eth1details.txt" contents];
31 | :local macstart [:find $eth1details "orig"];
32 | :local mac [:pick $eth1details ($macstart +17) ($macstart +34)];
33 |
34 | # Get identity variable
35 | :local identity [:system identity get value-name=name];
36 |
37 | # Get LTE1 info, set signal and technology variables
38 | :interface lte info lte1 file="lte1info.txt"
39 | :local lte1info [:file get lte1info.txt contents];
40 | :local sigstart [:find $lte1info "signal"];
41 | :local sigend [:find $lte1info "dBm" $sigstart];
42 | :local signal [:pick $lte1info ($sigstart +16) ($sigend -1)];
43 | :local techstart [:find $lte1info "access"];
44 | :local techend [:find $lte1info "\n" $techstart];
45 | :local techno [:pick $lte1info ($techstart +19) ($techend)];
46 |
47 | :local technology;
48 | :if ($techno ="GSM compact") do={[:set technology "GSM";]}
49 | :if ($techno ="3G") do={:set technology "UMTS";}
50 | :if ($techno ="Evolved 3G (LTE)") do={[:set technology "LTE";]}
51 |
52 | :if ([:find $gpstext "yes" $validstart] > 0) do={:set valid true;};
53 |
54 | :global longitude [:pick $gpstext ($longstart + 11) $longend];
55 | :local degreestart [:find $longitude " " -1];
56 | :local minutestart [:find $longitude " " $degreestart];
57 | :local secondstart [:find $longitude "'" $minutestart];
58 |
59 | :local secondend;
60 | :local secfract;
61 |
62 | :if ([:len [:find $longitude "." 0]] < 1) do={
63 | :set secondend [:find $longitude "'" $secondstart];
64 | :set secfract "0";
65 | } else={
66 | :set secondend [:find $longitude "." $secondstart];
67 | :set secfract [:pick $longitude ($secondend + 1) ($secondend + 2)];
68 | };
69 |
70 | :local longdegree;
71 | :local longdegreelink;
72 |
73 | :if ([:pick $longitude 0 1] = "W") do={
74 | :set longdegree "-";
75 | :set longdegreelink "W";
76 | } else={
77 | :set longdegree "+";
78 | :set longdegreelink "E";
79 | };
80 |
81 | :set longdegree ($longdegree . [:pick $longitude 2 $minutestart]);
82 | :set longdegreelink ($longdegreelink . [:pick $longitude 2 $minutestart]);
83 | :local longmin [:pick $longitude ($minutestart + 1) $secondstart];
84 | :local longsec [:pick $longitude ($secondstart + 2) $secondend];
85 | :local longfract ((([:tonum $longmin] * 6000) + ([:tonum $longsec] * 100) + ([:tonum $secfract] * 10) ) / 36);
86 |
87 | :while (([:len $zeros] + [:len $longfract]) < 4) do={
88 | :set zeros ($zeros . "0");
89 | };
90 |
91 | :global newlong ($longdegree . "." . $zeros . $longfract);
92 | :global newlonglink ($longdegreelink . "." . $zeros . $longfract);
93 |
94 | :global latitude [:pick $gpstext (latstart + 10) $latend];
95 | :set degreestart [:find $latitude " " -1];
96 | :set minutestart [:find $latitude " " $degreestart];
97 | :set secondstart [:find $latitude "'" $minutestart];
98 |
99 | :if ([:len [:find $latitude "." 0]] < 1) do={
100 | :set secondend [:find $latitude "'" $secondstart];
101 | :set secfract "0";
102 | } else={
103 | :set secondend [:find $latitude "." $secondstart];
104 | :set secfract [:pick $latitude ($secondend + 1) ($secondend +2)];
105 | };
106 |
107 | :local latdegree;
108 | :local latdegreelink;
109 |
110 | :if ([:pick $latitude 0 1] = "N") do={
111 | :set latdegree "+";
112 | :set latdegreelink "N";
113 | } else={
114 | :set latdegree "-";
115 | :set latdegreelink "S";
116 | };
117 |
118 | :set latdegree ($latdegree . [:pick $latitude 2 $minutestart]);
119 | :set latdegreelink ($latdegreelink . [:pick $latitude 2 $minutestart]);
120 | :local latmin [:pick $latitude ($minutestart + 1) $secondstart];
121 | :local latsec [:pick $latitude ($secondstart + 2) $secondend];
122 | :local latfract ((([:tonum $latmin] * 6000) + ([:tonum $latsec] * 100) +([:tonum $secfract] * 10)) / 36);
123 |
124 | :set zeros "";
125 |
126 | :while (([:len $zeros] + [:len $latfract]) < 4) do={
127 | :set zeros ($zeros . "0");
128 | };
129 |
130 | :global newlat ($latdegree . "." . $zeros . $latfract);
131 | :global newlatlink ($latdegreelink . "." . $zeros . $latfract);
132 |
133 | :global coordinates ($newlong . "," . $newlat);
134 |
135 | # SEND TO SERVER IF THE COORDINATES HAVE CHANGED
136 | :if (valid) do={
137 | :global oldpos;
138 |
139 | :if ($oldpos != $coordinates) do={
140 | {
141 | :local urlstring "http://$server/mikrotikgps.php\?identity=$identity&mac=$mac&latitude=$latitude&longitude=$longitude&lat=$newlat&lng=$newlong&date=$date&dbm=$signal&technology=$technology&speed=$speed&altitude=$altitude&satellites=$satellites";
142 | :local urlEncoded;
143 | :for i from=0 to=([:len $urlstring] - 1) do={
144 | :local char [:pick $urlstring $i]
145 | :if ($char = " ") do={
146 | :set $char "%20"
147 | }
148 | :if ($char = "-") do={
149 | :set $char "%2D"
150 | }
151 | :if ($char = "+") do={
152 | :set $char "%2B"
153 | }
154 | :set urlEncoded ($urlEncoded . $char)
155 | }
156 | :tool fetch url="$urlEncoded" mode=http dst-path=gps-to-url;
157 | }
158 | :set oldpos $coordinates;
159 | :global counter;
160 | :set counter 0;
161 | };
162 | } else={
163 | :global counter;
164 | :set counter ($counter + 1);
165 | :log info "GPS not valid, count = $counter";
166 | :if ($counter = 12) do={
167 | :system routerboard usb power-reset duration=1;
168 | :set counter 0;
169 | };
170 |
--------------------------------------------------------------------------------
/mikrotik_genxml.php:
--------------------------------------------------------------------------------
1 | createElement("markers");
9 | $parnode = $dom->appendChild($node);
10 |
11 | // Opens a connection to a MySQL server
12 |
13 | $connection=mysql_connect ('localhost', $username, $password);
14 | if (!$connection) { die('Not connected : ' . mysql_error());}
15 |
16 | // Set the active MySQL database
17 |
18 | $db_selected = mysql_select_db($database, $connection);
19 | if (!$db_selected) {
20 | die ('Can\'t use db : ' . mysql_error());
21 | }
22 |
23 | // Select only markers that are less than a day old
24 | $query = "SELECT * FROM `gps` WHERE `datetime` >= NOW() - INTERVAL 1 DAY";
25 |
26 | $result = mysql_query($query);
27 | if (!$result) {
28 | die('Invalid query: ' . mysql_error());
29 | }
30 |
31 | header("Content-type: text/xml");
32 |
33 | // Iterate through the rows, adding XML nodes for each
34 |
35 | while ($row = @mysql_fetch_assoc($result)){
36 | // ADD TO XML DOCUMENT NODE
37 | $node = $dom->createElement("marker");
38 | $newnode = $parnode->appendChild($node);
39 | $newnode->setAttribute("identity",$row['identity']);
40 | $newnode->setAttribute("mac", $row['mac']);
41 | $newnode->setAttribute("date", $row['datetime']);
42 | $newnode->setAttribute("lat", $row['lat']);
43 | $newnode->setAttribute("lng", $row['lng']);
44 | $newnode->setAttribute("dbm", $row['dbm']);
45 | $newnode->setAttribute("technology", $row['technology']);
46 | $newnode->setAttribute("speed", $row['speed']);
47 | $newnode->setAttribute("altitude", $row['altitude']);
48 | $newnode->setAttribute("satellites", $row['satellites']);
49 | }
50 |
51 | echo $dom->saveXML();
52 |
53 | ?>
54 |
--------------------------------------------------------------------------------
/mikrotikgps.php:
--------------------------------------------------------------------------------
1 |
37 |
--------------------------------------------------------------------------------
/mikrotiklocation.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Mikrotik Location
6 |
7 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |