-
-
Save Surendrajat/ff3876fd2166dd86fb71180f4e9342d7 to your computer and use it in GitHub Desktop.
"custom/weather": { | |
"exec": "python ~/.config/waybar/scripts/weather.py", | |
"restart-interval": 300, | |
"return-type": "json", | |
"on-click": "xdg-open https://weather.com/en-IN/weather/today/l/$(location_id)" | |
// "format-alt": "{alt}", | |
}, |
#custom-weather.severe { | |
color: #eb937d; | |
} | |
#custom-weather.sunnyDay { | |
color: #c2ca76; | |
} | |
#custom-weather.clearNight { | |
color: #2b2b2a; | |
} | |
#custom-weather.cloudyFoggyDay, #custom-weather.cloudyFoggyNight { | |
color: #c2ddda; | |
} | |
#custom-weather.rainyDay, #custom-weather.rainyNight { | |
color: #5aaca5; | |
} | |
#custom-weather.showyIcyDay, #custom-weather.snowyIcyNight { | |
color: #d6e7e5; | |
} | |
#custom-weather.default { | |
color: #dbd9d8; | |
} |
#!/usr/bin/env python | |
import subprocess | |
from pyquery import PyQuery # install using `pip install pyquery` | |
import json | |
# weather icons | |
weather_icons = { | |
"sunnyDay": "滛", | |
"clearNight": "望", | |
"cloudyFoggyDay": "", | |
"cloudyFoggyNight": "", | |
"rainyDay": "", | |
"rainyNight": "", | |
"snowyIcyDay": "", | |
"snowyIcyNight": "", | |
"severe": "", | |
"default": "", | |
} | |
# get location_id | |
# to get your own location_id, go to https://weather.com & search your location. | |
# once you choose your location, you can see the location_id in the URL(64 chars long hex string) | |
# like this: https://weather.com/en-IN/weather/today/l/c3e96d6cc4965fc54f88296b54449571c4107c73b9638c16aafc83575b4ddf2e | |
location_id = "c3e96d6cc4965fc54f88296b54449571c4107c73b9638c16aafc83575b4ddf2e" # TODO | |
# location_id = "8139363e05edb302e2d8be35101e400084eadcecdfce5507e77d832ac0fa57ae" | |
# priv_env_cmd = 'cat $PRIV_ENV_FILE | grep weather_location | cut -d "=" -f 2' | |
# location_id = subprocess.run( | |
# priv_env_cmd, shell=True, capture_output=True).stdout.decode('utf8').strip() | |
# get html page | |
url = "https://weather.com/en-IN/weather/today/l/" + location_id | |
html_data = PyQuery(url=url) | |
# current temperature | |
temp = html_data("span[data-testid='TemperatureValue']").eq(0).text() | |
# print(temp) | |
# current status phrase | |
status = html_data("div[data-testid='wxPhrase']").text() | |
status = f"{status[:16]}.." if len(status) > 17 else status | |
# print(status) | |
# status code | |
status_code = html_data("#regionHeader").attr("class").split(" ")[2].split("-")[2] | |
# print(status_code) | |
# status icon | |
icon = ( | |
weather_icons[status_code] | |
if status_code in weather_icons | |
else weather_icons["default"] | |
) | |
# print(icon) | |
# temperature feels like | |
temp_feel = html_data( | |
"div[data-testid='FeelsLikeSection'] > span > span[data-testid='TemperatureValue']" | |
).text() | |
temp_feel_text = f"Feels like {temp_feel}c" | |
# print(temp_feel_text) | |
# min-max temperature | |
temp_min = ( | |
html_data("div[data-testid='wxData'] > span[data-testid='TemperatureValue']") | |
.eq(0) | |
.text() | |
) | |
temp_max = ( | |
html_data("div[data-testid='wxData'] > span[data-testid='TemperatureValue']") | |
.eq(1) | |
.text() | |
) | |
temp_min_max = f" {temp_min}\t\t {temp_max}" | |
# print(temp_min_max) | |
# wind speed | |
wind_speed = html_data("span[data-testid='Wind']").text().split("\n")[1] | |
wind_text = f"煮 {wind_speed}" | |
# print(wind_text) | |
# humidity | |
humidity = html_data("span[data-testid='PercentageValue']").text() | |
humidity_text = f" {humidity}" | |
# print(humidity_text) | |
# visibility | |
visbility = html_data("span[data-testid='VisibilityValue']").text() | |
visbility_text = f" {visbility}" | |
# print(visbility_text) | |
# air quality index | |
air_quality_index = html_data("text[data-testid='DonutChartValue']").text() | |
# print(air_quality_index) | |
# hourly rain prediction | |
prediction = html_data("section[aria-label='Hourly Forecast']")( | |
"div[data-testid='SegmentPrecipPercentage'] > span" | |
).text() | |
prediction = prediction.replace("Chance of Rain", "") | |
prediction = f"\n\n (hourly) {prediction}" if len(prediction) > 0 else prediction | |
# print(prediction) | |
# tooltip text | |
tooltip_text = str.format( | |
"\t\t{}\t\t\n{}\n{}\n{}\n\n{}\n{}\n{}{}", | |
f'<span size="xx-large">{temp}</span>', | |
f"<big>{icon}</big>", | |
f"<big>{status}</big>", | |
f"<small>{temp_feel_text}</small>", | |
f"<big>{temp_min_max}</big>", | |
f"{wind_text}\t{humidity_text}", | |
f"{visbility_text}\tAQI {air_quality_index}", | |
f"<i>{prediction}</i>", | |
) | |
# print waybar module data | |
out_data = { | |
"text": f"{icon} {temp}", | |
"alt": status, | |
"tooltip": tooltip_text, | |
"class": status_code, | |
} | |
print(json.dumps(out_data)) |
I got an update on the fetching logic, also discussed further above.
The correct synthax is now
# get html page
url = "https://weather.com/en-IN/weather/today/l/" + location_id
html_data = PyQuery(url=url)
Updates on what args PyQuery takes can be found here: https://pyquery.readthedocs.io/en/latest/scrap.html (as also posted further above by @cn-danieldev.)
As of date of this comment I can confirm that this script still works!
Is it possible to get Fahrenheit? I notice there is no separate URL for Fahrenheit on the website, guess some JS handling or something.
Possible to get 5-day?
When I click the popup/dropdown thing, goes to 404 page: https://weather.com/en-IN/weather/today/l/
ie. missing location_id at that point.
To get English/Imperial units append '?units=e' to the end of your location_id. My locations looks like this:
location_id = "ff02642ddd763393bf9158589c1b4804cc84c808136cc42554efce2a92fc47fb?unit=e" # appending '?unit=e' changes everything to English/Imperial units
Here is what my screen looks like, yes I made a few other minor mods to the file since I don't know/understand any Asian characters.
I hope you, and others, find this helpful.
Hello, while I did write my own CSS for this, I did notice a typo in your CSS. In your CSS you have:
#custom-weather.showyIcyDay, #custom-weather.snowyIcyNight { color: #d6e7e5; }
It should say:
#custom-weather.snowyIcyDay, #custom-weather.snowyIcyNight { color: #d6e7e5; }
I noticed it when I started with your CSS sheet and wanted to have different appearances for Day and Night. By the way, I love the script and the lack of need to sign up for any additional APIs. It is simple, looks great, and it works.
which font u use for weather icon