SolDoesTech / HyprV4

497 stars 142 forks source link

Problem (and solution) for the weather script showing the wrong weather #9

Open BetaQuasi opened 1 year ago

BetaQuasi commented 1 year ago

Hey Sol,

Love your work here - made it a lot easier for me to reverse engineer everything and start tinkering. I had a lot of false starts trying to play with Hyprland!

In any case, just wanted to drop a note - it seems wttr.in uses your IP address to identify your location. Unfortunately ip geolocation data is dodgy at best, so in my case it was pulling info for a city about 1500km north of me here in Australia! There's ways to force a specific location in the call to wttr.in though, and I found the easiest was using an airport code as I have one quite close to me.

In my case, I edited:

~/.config/HyprV/waybar/scripts/waybar-wttr-c.py and looked for the following line:

weather = requests.get("https://wttr.in/?format=j1").json()

Throwing in my airport code gets me a fixed result. Fortunately that works for my use case as my desktop doesn't travel.. no doubt for travelling laptop users, it might not be so great. Anyway, just thought I'd share my solution in case it helps anyone else.

The edit just involved dropping the three letter airport code in caps in place of the 3 XXX's below (you can google your local airport code.)

weather = requests.get("https://wttr.in/XXX?format=j1").json()

Thanks again for all your hard work, it's much appreciated!

JonasNapierski commented 1 year ago

I love that Feature Idea!

I currently working on a version of the script where you can set a few parameters via command line flags and this would be great for the AIRPORT Code problem. If you don't mind I will add it and reference your GitHub account for the idea.

milesje commented 1 year ago

You can also put the 5 digit zip code (for US anyway).

weather = requests.get("https://wttr.in/12345?format=j1").json()

milesje commented 1 year ago

also you could use a couple of APIs to get the approximate location based on IP address.

def get_ip():
    response = requests.get("https://api64.ipify.org?format=json").json()
    return response["ip"]

def get_zip():
    ip_address = get_ip()
    response = requests.get(f"https://ipapi.co/{ip_address}/json").json()
    return response["postal"]

postal = get_zip()
weather = requests.get(f"https://wttr.in/{postal}?format=j1").json()

But this is just an approximation based on the users current IP address. This can have some variation in data depending on the ISP and if the user is using VPN it will also show the weather based on the VPN's IP Address. Having this in conjunction with a user set variable would be the idea solution. If the user sets a value (ZipCode/PostalCode/AirPortCode) it uses it to get the weather if not set then use the approximation based on IP.

milesje commented 1 year ago

Here is an example of the solution I proposed above.

def get_ip():
    response = requests.get("https://api64.ipify.org?format=json").json()
    return response["ip"]

def get_zip():
    ip_address = get_ip()
    response = requests.get(f"https://ipapi.co/{ip_address}/json").json()
    return response["postal"]

if len(sys.argv) > 1:
    postal = sys.argv[1]
else:
    postal = get_zip()

weather = requests.get(f"https://wttr.in/{postal}?format=j1").json()

and then the user can edit the mesu.jsonc file add their postal code.

    "custom/weather": {
        //shows the current weather and forecast
        "tooltip" : true,
        "format" : "{}",
        "interval" : 30,
        "exec" : "~/.config/HyprV/waybar/scripts/waybar-wttr.py 12345",
        "return-type" : "json"
    },