Aloa,
Ich habe heute mal ein GPS an meinen TL-MR3020 Mobilrouter gehängt.
@MrMM hatte mal nach sowas gefragt.
Somit ist es möglich die Location dynamisch und automatisiert auf einen neuen Stand zu bringen.
##Was wird benötigt?
- USB-GPS (Hier Navilock NL-302U)
- Freifunk Router
##Konfiguration
Als erstes muss man dem Freifunkrouter beibringen, was USB-Geräte sind. Dafür habe ich mich an die Anleitung im openWRT-Wiki gehalten:
Nachinstalliert wurden die folgenden Module:
opkg install kmod-usb-core
opkg install kmod-usb-ohci
opkg install kmod-usb2
opkg install kmod-usb-serial-pl2303
Außerdem gibts noch das tool stty dazu:
opkg install coreutils-stty
Das angeschlossene GPS ist nun unter /dev/ttyUSB0 zu finden
mit stty stellt man die Baudrate passend ein, dass muss nach jedem Neustart erneut geschehen:
stty -F /dev/ttyUSB0 raw 4800 cs8 clocal -parenb crtscts -cstopb
nun lässt sich das GPS auslesen:
cat /dev/ttyUSB0
Das GPS spuckt nun NMEA Sätze aus. Das folgende Skript liest diese aus und schreibt diese in die config, es validiert anhand der GPS-Daten ob die Position korrekt ist, und schreibt auch nur in diesem Fall.
# Configure GPS
stty -F /dev/ttyUSB0 raw 4800 cs8 clocal -parenb crtscts -cstopb;
# Use GPS as Stream
exec 4</dev/ttyUSB0;
while true
do
read this_line;
nc=`echo $this_line | cut -d',' -f 1`;
if [ "$nc" = '$GPRMC' ];
then
valid=`echo $this_line | cut -d',' -f 3`;
if [ "$valid" = "A" ];
then
#First: Retrieve coordinate
lat=`echo $this_line | cut -d',' -f 4`;
lon=`echo $this_line | cut -d',' -f 6`;
# Second: Determine if coordinate is oriented North/South or East/West
latdir=`echo $this_line | cut -d',' -f 5`;
londir=`echo $this_line | cut -d',' -f 7`;
# Split DEGREES from coordinate
latdeg="$(echo ${lat:0:2} | sed 's/^0*//')";
londeg="$(echo ${lon:0:3} | sed 's/^0*//')";
# Split MINUTES.SECONDS from coordinate
latmin=`echo ${lat:2}`;
lonmin=`echo ${lon:3}`;
#Convert from Degree-Minutes to Decimal-Minutes
latdec=$(awk -v l="$latmin" 'BEGIN {printf "%f", l/60}' | sed 's/^0*//')
londec=$(awk -v l="$lonmin" 'BEGIN {printf "%f", l/60}' | sed 's/^0*//')
#Use negative notation instead of North/South or East/West
if [ $latdir = 'S' ];
then
latdeg="-"$latdeg;
fi
if [ $londir = 'W' ];
then
londeg="-"$londeg;
fi
echo "Position is valid Lat/Lon: "$latdeg$latdec $londeg$londec;
# Write to config
uci set gluon-node-info.@location[0].share_location=1;
uci set gluon-node-info.@location[0].latitude=$latdeg$latdec;
uci set gluon-node-info.@location[0].longitude=$londeg$londec;
# uci commit gluon-node-info; See Phip's comment below why this should not be done here.
break;
else
echo "Position is Invalid..." $valid;
break;
fi
fi
done <&4;
exit 0;
Das Skript kommt ohne Garantie auf Richtigkeit, für Fehler oder Schäden die durch dieses Entstehen übernehme ich keine Haftung. Es gelten die Lizenzbedingungen der MIT-License.
##Weiteres vorgehen
Nun ließe sich natürlich das Skript per Cronjob alle X Minuten ausführen. Das habe ich nicht weiter getestet.
##Edit 2015-01-07:
Wer die Serielle Schnitstelle die im Router verbaut ist nutzen möchte verwendet folgende Config für das Skript:
# Configure GPS
stty -F /dev/ttyATH0 raw 9600 cs8 clocal -parenb crtscts -cstopb;
# Use GPS as Stream
exec 4</dev/ttyATH0;
VG
xelo