I’m travelling a lot with my laptop, and having an accurate weather forecast on-the-go is very convenient.
I’m using Fedora as my main (and only) OS, along with i3wm and polybar. Previously I used GNOME 3 which had a few weather widgets. The most feature-rich was OpenWeather, which worked pretty well.
polybar doesn’t have a native weather widget and the one’s at x70b1/polybar-scripts suffered from the same drawbacks that OpenWeather did: location had to be manually specified or was ip-geolocation based (which is not accurate enough)
How do I get an accurate location without a GPS? WiPS to the rescue!
Wi-Fi Positioning System
Did you ever notice that you can get accurate location data when your GPS is turned off? The trick is to measure Wi-Fi signal intensity in order to triangulate your location.
Google, for instance, tracks open access points when you walk around and upload these along with your GPS location. When your GPS is turned off, they can use the access points around you to calculate your GPS coordinates. Cool right?
Lifewire published an explanation about Wi-Fi triangulation a few months ago, and Wikipedia has a nice article on the subject as well.
Getting Accurate Geolocation
Google Maps has a neat Geolocation API that gives accurate location data if supplied with the MAC addresses of surrounding access points.
I can use iw to extract these by running:
$ iw <iface> scan | grep -io "[0-9A-F]\{2\}\(:[0-9A-F]\{2\}\)\{5\}" | uniq |
But how the heck do I get the wireless interfaces? well, there’s /proc/net/wireless
for that -
import re |
Now, I need to to run iw
. Running system commands from python is a pain in the ass.
unless you use the mighty sh package, that is!
import sh |
And now all that’s left is to kindly ask google to give us our location.urllib
is a pain, so I’m using requests instead.
import requests |
Getting Weather Forecast
OpenWeather widget used OpenWeatherMap API to get up-to-date weather forecast, so I used it as well.
import requests |
And viola!
longitude, latitude = get_geolocation() |