Skip to content

Instantly share code, notes, and snippets.

@Surendrajat
Last active March 14, 2023 21:08
Embed
What would you like to do?
A Clean & Customizable Weather module for Waybar
"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[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))
@CerealKiller-John
Copy link

@CerealKiller-John thanks. I've mostly used font-awesome icons and few icons from nerd-fonts. This is my setup:

https://github.com/Surendrajat/dotfiles/blob/f3b2deef20fac21285dcefe52ed8eccdcb13fa73/.config/waybar/style.css#L48

Thank you, I also was wondering is there a way to incorporate current location into this? As I am using it on a laptop, I wouldn't really need to know my home forecast if I am not at home. I know I could update the key, but I was wondering if there was an easier way?

@Surendrajat
Copy link
Author

I also was wondering is there a way to incorporate current location into this?

I guess you can get your lat-long from laptop's GPS and submit it to weather.com's HTML form (using a similar script) and get location id from redirection URL. It'll a bit complicated and will depend on the accuracy of your GPS. Anyway, you might be better off with some API from weather providers at that point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment