Use GPSD server to retreive and save coordinates on handshake. Can use mutiple gps device (gps modules, USB dongle, phone, etc.)
Advantages with gpsd server:
- GPS configuration independant from pwnagotchi
- Early position polling
- No position lost on bettercap/pwnagotchi restarts
- High compatibility (device, protocol, vendor, version): NMEA/ublox modules (Serial), USB modules, Android/IPhone
- Non blocking access to GPS information
- GPS hotplugin
- Compatibility with other applications like chrony
- Compatible with NTRIP/RTK/RTCM
Exemple:
GPS module/dongle and/or Phone (IOS/Android) ------> GPSD ------> GPSD-ng ------> Pwnagotchi
- Client to GPSD server with multi device management
- Several customable UI modes and a Web UI
- Save position on handshake and fallback for pcap without position
- Unit option: metric or imperial
- Use open elevation and cache for 2D fix.
- Show completeness statistic (percentage of pcap files with a valid position file)
- Two hooks:
on_position_available(coords)
andon_position_lost()
- Non blocking plugin
- Install binaries:
- version 3.22: APT method:
apt-get install gpsd gpsd-clients python3-gps
- version 3.24:
- Download in a folder the following packages from https://archive.raspberrypi.org/debian/pool/untested/g/gpsd/:
- gpsd_3.24-1~rpt1_arm64.deb
- gpsd-clients_3.24-1~rpt1_arm64.deb
- gpsd-tools_3.24-1~rpt1_arm64.deb
- libgps29_3.24-1~rpt1_arm64.deb
- python3-gps_3.24-1~rpt1_arm64.deb
- Install with
dpkg -i *.deb
- Download in a folder the following packages from https://archive.raspberrypi.org/debian/pool/untested/g/gpsd/:
- version 3.25: Build from source (https://gpsd.gitlab.io/gpsd/building.html)
- version 3.22: APT method:
- Configure GPSD (/etc/default/gpsd) and uncomment one DEVICES:
# Default settings for the gpsd init script and the hotplug wrapper.
# Start the gpsd daemon automatically at boot time
START_DAEMON="true"
# Use USB hotplugging to add new USB devices automatically to the daemon
USBAUTO="false"
# Devices gpsd should collect to at boot time.
# They need to be read/writeable, either by user gpsd or the group dialout.
DEVICES=""
# Other options you want to pass to gpsd
GPSD_OPTIONS="-n" # add -D3 if you need to debug
- Check in raspi-config -> Interface Options -> Serial Port:
- Disable Serial Port login
- Enable Serial Port
- Check your gps baudrate.
- Set
DEVICES="-s BAUDRATE /dev/ttyS0"
in /etc/default/gpsd
- Set
USBAUTO="true"
in /etc/default/gpsd - No need to set DEVICES
- On your phone:
- Setup the plugin bt-tether and check you can ping your phone
- Install a GPS app:
- Android(not tested):
- BlueNMEA: https://github.com/MaxKellermann/BlueNMEA
- gpsdRelay: https://github.com/project-kaat/gpsdRelay
- IOS: GPS2IP (tested but paid app)
- Set "operate in background mode"
- Set "Connection Method" -> "Socket" -> "Port Number" -> 4352
- Set "Network selection" -> "Hotspot"
- Both cases activate GGA messages to have "3D fix"
- Android(not tested):
- Check your gpsd configuration with gpsmon or cgps
- Set
DEVICES="tcp://PHONEIP:4352"
in /etc/default/gpsd
You can configure several devices in DEVICES
Ex: DEVICES="-s BAUDRATE /dev/ttyS0 tcp://PHONEIP:4352"
- Install GEOPY:
apt-get install python3-geopy
- Copy gpsd-ng.py and gpsd-ng.html to your custom plugins directory
[main.plugins.gpsd]
enabled = true
# Options with default settings.
# Add only if you need customisation
gpsdhost = "127.0.0.1"
gpsdport = 2947
main_device = "/dev/ttyS0" # if not provided, the puglin will try to retreive the most accurate position
wifi_positioning = false # Onlly in AUTO mode, tries
update_timeout = 120 # default 120, Delay without update before deleting the position. 0 = no timeout
fix_timeout = 120 # default 120, Delay without fix before deleting the position. 0 = no timeout
use_open_elevation = true # if true, use open-elevation API to retreive missing altitudes. Use it if you have a poor GPS signal.
save_elevations = true # if true, elevations cache will be saved to disk. Be carefull as it can grow fast if move a lot.
view_mode = "compact" # "compact", "full", "status", "none"
fields = "info,speed,altitude" # list or string of fields to display
units = "metric" # "metric" or "imperial"
display_precision = 6 # display precision for latitude and longitude
position = "127,64"
show_faces = true # if false, doesn't show face. Ex if you use PNG faces
lost_face_1 = "(O_o )"
lost_face_2 = "( o_O)"
face_1 = "(•_• )"
face_2 = "( •_•)"
This plugin can be used for wardriving with the wigle plugin, for example.
- Outdoor: GPS module/dongle works fine.
- Indoor: is the GPS module/dongle doesn't work, you can use your phone.
If main_device is not set (default), the device with the most accurate (base on fix information) and most recent position, will be selected.
If main_device is set, the plugin will use that main device position, if available.
If the main device is not available, it will fallback to other devices.
If the device can only get 2D positions for some reason (poor signal, wrong device orientation, bad luck, etc.), the plugin can use open-elevation API to try to ask current altitude. To avoid many call to the API, each request asks for points every ~10m around you, in a diameter of 200m. This cache can be saved to disk.
After a delay (set by update_timeout) without data update for a device, the position will be deleted.
If update_timeout is set to 0, positions never expire.
After a delay (set by fix_timeout) without data fix for a device, the last position will be deleted.
If fix_timeout is set to 0, positions fix never expire. Usefull for keeping last position when goind indoor.
Only available with automode.
The plugin tries to guess the current position by calculation a median location of surrounding wifis.
This location is only used, if a gps module is not available and will only be saved on handshake, if the no previous position was saved.
If you have a GPs module or dongle with RTCM capabilities, you can activate with GPSD. Exemple with a Ublox (firmware 34.10) and GPSD 3.25:
- ublox setup:
- ubxtool -p MON-VER | grep PROT -> retreive ublox version XX.YY (34.10 for me)
- export UBXOPTS="-P XX.YY -v 2"
- ubxtool -e RTCM3
- GPSD setup:
- Find a local (< 30km) RTK provider (https://rtkdata.online/network)
- You need host/port and mountpoint information
- Check with the following command. It should stream binary data.
curl -v -H "Ntrip-Version: Ntrip/2.0" -H "User-Agent: NTRIP theSoftware/theRevision" http://[user:pwd@]host:2101/mountpoint -o - - Add "ntrip://[user:pwd@]host:2101/mountpoint" to DEVICES in GPSD configuration
- Now GPSD command should look like with ps: 'gpsd -n ntrip://host:2101/MOUNTPOINT -s 38400 /dev/ttyS0'
Of course, you can still append your phone 'gpsd -N -D3 ntrip://host:2101/MOUNTPOINT -s 38400 /dev/ttyS0 tcp://172.20.10.1:4352' More info on: https://gpsd.gitlab.io/gpsd/ubxtool-examples.html#_survey_in_and_rtcm
The "compact" view mode (default) option show gps informations, on one line, in rotation:
- Latitude,Longitude
- Info: Device source + Fix information
- Speed, Altitude
If you prefer a more traditionnal view, use "full" mode:
- Latitude
- Longitude
- Altitude
- Speed
You can show or not with the fields option. by default, it will display all. If you want a clear display, use "none", nothing will be display.
If you like it very brief, try the "status" mode, only 4 letters in status bar.
You should take a look at the Web UI with fancy graphs ;-)
You can use metric or imperial units for altitude(m or ft) and speed (m/s or ft/s). This only changes on display, not gps.json files, as Wigle needs metric units. Default is metric because it's the International System.
- Set gps position to bettercap (it's also done on internet_available() and on_unfiltered_ap_list())
- Saves position informations into "gps.json" (compatible with Wigle and webgpsmap)
Note: During on_unfiltered_ap_list(), if an access point whith pcap files but without gps file is detected, this plugin will save the current position for that AP. This is a fallback, if the position was not available during handshake().
Gps option is set to off. Position is update by the plugin to Bettercap, on handshake, internet_available and on_unfiltered_ap_list.
This plugin adds two plugin hooks, triggered every 10 seconds:
- If a position is available, the hook
on_position_available(coords)
is called with a dictionnary (see below) - If no position is available, the hook ```on_position_lost() is called
The coords dictionnary:
- Latitude, Longitude (float)
- Altitude (float): Sea elevation
- Speed (float): Horizontal speed
- Date, Updated (datetime): Last fix
- Mode (int 2 or 3), Fix (str): Fix mode (2D or 3D). 0 and 1 are removec
- Sats (int), Sats_used(int): Nb of seen satellites and used
- Device (str): GPS device (ex: /dev/ttyS0)
- Accuracy (int): default 50 All data are metric only.
matplotlib is not up to date in /home/pi/.pwn:
- su -
- cd /home/pi/.pwn
- source bin/activate
- pip install scipy numpy matplotlib --upgrade
gpsd-ng.html is missing, just copy :-)
The gpsd python library, called "gps", is old (around 2020).
An update will do the trick.
- GPSD server is not running:
- Try to restart gpsd: sudo systemctl restart gpsd
- Check status: sudo systemctl status gpsd
- Check logs
- GPSD server is not configured. Check install section.
- GPSD configuration is wrong:
- Try "cgps" or "gpsmon" to check if you have readings
- Check with "cgps" if gpsd can retreive data from gps modules
- The plugin filters data without fix. You can check on the plugin's webpage.
- Run around the World!
- Pwnagotchi:
- GPSD: https://gpsd.gitlab.io/gpsd/index.html
- Original plugin and fork:
- Polar graph: https://github.com/rai68/gpsd-easy/blob/main/gpsdeasy.py
Have fun !