Skip to content

Instantly share code, notes, and snippets.

Last active January 29, 2024 23:29
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save Surendrajat/ff3876fd2166dd86fb71180f4e9342d7 to your computer and use it in GitHub Desktop.
A Clean & Customizable Weather module for Waybar
"custom/weather": {
"exec": "python ~/.config/waybar/scripts/",
"restart-interval": 300,
"return-type": "json",
"on-click": "xdg-open$(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 & search your location.
# once you choose your location, you can see the location_id in the URL(64 chars long hex string)
# like this:
location_id = "c3e96d6cc4965fc54f88296b54449571c4107c73b9638c16aafc83575b4ddf2e" # TODO
# location_id = "8139363e05edb302e2d8be35101e400084eadcecdfce5507e77d832ac0fa57ae"
# priv_env_cmd = 'cat $PRIV_ENV_FILE | grep weather_location | cut -d "=" -f 2'
# location_id =
# priv_env_cmd, shell=True, capture_output=True).stdout.decode('utf8').strip()
# get html page
url = "" + 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 = (
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']"
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']")
temp_max = (
html_data("div[data-testid='wxData'] > span[data-testid='TemperatureValue']")
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"
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(
f'<span size="xx-large">{temp}</span>',
f"{visbility_text}\tAQI {air_quality_index}",
# print waybar module data
out_data = {
"text": f"{icon} {temp}",
"alt": status,
"tooltip": tooltip_text,
"class": status_code,
Copy link

k1tyoo commented Feb 2, 2023

Traceback (most recent call last):
File "/home/shabirk/.config/waybar/modules/", line 46, in
status_code = html_data("#regionHeader").attr("class").split(" ")[2].split("-")[2]
AttributeError: 'NoneType' object has no attribute 'split'

The new document of pyquery module shows the method below will no longer fetch the contents of the URL.

url = "" + location_id
html_data = PyQuery(url)

The right way

url_fetch = "" + location_id
html_data = PyQuery(url=url_fetch)

Copy link

Surendrajat commented Feb 2, 2023

Thanks @k1tyoo for tracking it down. I've updated the script to work with pyquery 1 & 2 now.

Copy link

ghost commented Feb 6, 2023

What are the default icons, as a lot of them are not showing for me, other than that I appreciate the work you have done and it's a great module :)

Copy link

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

Copy link

ghost commented Feb 7, 2023

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

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?

Copy link

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'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.

Copy link

Hello there! Thanks for this wonderful module. In the past few days, I've realized that the "Feels like" section inside the tooltip does not print out any value. I'm not sure why, as the values seem to align with the website its scrapes from. Any ideas about how to fix?

Copy link

Looks like they've added one more <span> wrapper around the temp value. Anyway I've fixed it for now. Cheers.

Copy link

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:

ie. missing location_id at that point.

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