mirror of
https://github.com/vincentbernat/i3wm-configuration.git
synced 2025-06-21 09:35:40 +02:00
weather: update to use met.no
This commit is contained in:
parent
dd885314b1
commit
c1e81df684
3 changed files with 58 additions and 60 deletions
113
bin/weather
113
bin/weather
|
@ -30,17 +30,17 @@ def get_location():
|
||||||
return ((data["location"]["latitude"], data["location"]["longitude"]), location)
|
return ((data["location"]["latitude"], data["location"]["longitude"]), location)
|
||||||
|
|
||||||
|
|
||||||
def get_weather(apikey, latitude, longitude):
|
def get_weather(latitude, longitude):
|
||||||
"""Return data from openweathermap."""
|
"""Return data from met.no."""
|
||||||
logger.debug("query openweathermap for %s, %s", latitude, longitude)
|
logger.debug("query met.no for %s, %s", latitude, longitude)
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
f"https://api.openweathermap.org/data/2.5/onecall",
|
"https://api.met.no/weatherapi/locationforecast/2.0/complete.json",
|
||||||
params={
|
params={
|
||||||
"appid": apikey,
|
"lat": f"{latitude:.4f}",
|
||||||
"lat": latitude,
|
"lon": f"{longitude:.4f}",
|
||||||
"lon": longitude,
|
},
|
||||||
"units": "metric",
|
headers={
|
||||||
"exclude": "minutely,hourly",
|
"user-agent": "WeatherWidget https://github.com/vincentbernat/i3wm-configuration"
|
||||||
},
|
},
|
||||||
timeout=10,
|
timeout=10,
|
||||||
)
|
)
|
||||||
|
@ -50,37 +50,43 @@ def get_weather(apikey, latitude, longitude):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def format_weather(data, show_temperature=True):
|
def format_icon(symbol_code):
|
||||||
"""Translate OWM icon to WeatherIcons."""
|
"""Translate met.no icon to Font Awesome."""
|
||||||
# https://erikflowers.github.io/weather-icons/
|
# See https://github.com/metno/weathericons/blob/main/weather/legend.csv
|
||||||
icon = data["weather"][0]["icon"]
|
symbol_code = symbol_code.removeprefix("light")
|
||||||
temperature = data["temp"] if show_temperature else 0
|
symbol_code = symbol_code.removeprefix("heavy")
|
||||||
if icon == "01d" and temperature > 32:
|
if symbol_code.startswith("ss"):
|
||||||
icon = ""
|
symbol_code = symbol_code[1:]
|
||||||
else:
|
icon = {
|
||||||
icon = {
|
"clearsky_day": "\uf00d",
|
||||||
"01d": "", # Clear sky - day
|
"clearsky_night": "\uf02e",
|
||||||
"01n": "⏾", # Clear sky - night
|
"cloudy": "\uf013",
|
||||||
"02d": "🌤", # Few clouds (11-25%) - day
|
"fair_day": "\uf002",
|
||||||
"02n": "", # Few clouds (11-25%) - night
|
"fair_night": "\uf086",
|
||||||
"03d": "⛅", # Scattered clouds (25-50%) - day/night
|
"fog": "\uf014",
|
||||||
"03n": "", # Scattered clouds (25-50%) - day/night
|
"partlycloudy_day": "\uf002",
|
||||||
"04d": "", # Broken / Overcast clouds (51-84% / 85-100%) - day/night
|
"partlycloudy_night": "\uf086",
|
||||||
"04n": "", # Broken / Overcast clouds (51-84% / 85-100%) - day/night
|
"rain": "\uf019",
|
||||||
"09d": "🌦", # Shower rain - day
|
"rainandthunder": "\uf01e",
|
||||||
"09n": "", # Shower rain - night
|
"rainshowers_day": "\uf009",
|
||||||
"10d": "", # Moderate / heavy rain - day
|
"rainshowers_night": "\uf037",
|
||||||
"10n": "", # Moderate / heavy rain - night
|
"rainshowersandthunder_day": "\uf010",
|
||||||
"11d": "", # Thunderstorm - day
|
"rainshowersandthunder_night": "\uf03b",
|
||||||
"11n": "", # Thunderstorm - night
|
"sleet": "\uf0b5",
|
||||||
"13d": "", # Snow - day
|
"sleetandthunder": "\uf01d",
|
||||||
"13n": "❄", # Snow - night
|
"sleetshowers_day": "\uf0b2",
|
||||||
"50d": "", # Fog - day
|
"sleetshowers_night": "\uf0b3",
|
||||||
"50n": "🌫", # Fog - night
|
"sleetshowersandthunder_day": "\uf068",
|
||||||
}.get(icon, "")
|
"sleetshowersandthunder_night": "\uf069",
|
||||||
|
"snow": "\uf01b",
|
||||||
|
"snowandthunder": "\uf06b",
|
||||||
|
"snowshowers_day": "\uf009",
|
||||||
|
"snowshowers_night": "\uf038",
|
||||||
|
"snowshowersandthunder_day": "\uf06b",
|
||||||
|
"snowshowersandthunder_night": "\uf06c",
|
||||||
|
}.get(symbol_code, "?")
|
||||||
|
logger.debug("symbol %s translated to %s (\\u%04x)", symbol_code, icon, ord(icon))
|
||||||
output = ["%{Tx}", icon, "%{T-}"]
|
output = ["%{Tx}", icon, "%{T-}"]
|
||||||
if show_temperature:
|
|
||||||
output += [" ", str(int(round(temperature))), "°C"]
|
|
||||||
return "".join(output)
|
return "".join(output)
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,12 +112,7 @@ if __name__ == "__main__":
|
||||||
help="enable debugging",
|
help="enable debugging",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--owm-api-key",
|
"--font-index", default=4, type=int, help="Polybar font 1-index"
|
||||||
default=os.environ.get("OWM_API_KEY"),
|
|
||||||
help="OpenWeatherMap API key",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--font-index", default=3, type=int, help="Font Awesome 1-index"
|
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--output",
|
"--output",
|
||||||
|
@ -156,25 +157,21 @@ if __name__ == "__main__":
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Grab current weather and daily forecast
|
# Grab current weather and daily forecast
|
||||||
weather = get_weather(options.owm_api_key, *location)
|
weather = get_weather(*location)
|
||||||
daily_weather_ts = time.strftime(
|
weather = weather["properties"]["timeseries"][0]["data"]
|
||||||
"%Y-%m-%d %H:%M %Z", time.gmtime(weather["daily"][0]["dt"])
|
|
||||||
)
|
|
||||||
description = weather["current"]["weather"][0]["description"]
|
|
||||||
logger.info(f"current weather at {city}: {description}")
|
|
||||||
logger.info(f"daily forecast: {daily_weather_ts}")
|
|
||||||
|
|
||||||
# Format output
|
# Format output
|
||||||
conditions = [format_weather(weather["current"])]
|
conditions = [
|
||||||
conditions += [
|
format_icon(weather["next_1_hours"]["summary"]["symbol_code"]),
|
||||||
format_weather(weather["daily"][0], False),
|
"{}°C".format(round(weather["instant"]["details"]["air_temperature"])),
|
||||||
|
format_icon(weather["next_6_hours"]["summary"]["symbol_code"]),
|
||||||
"{}—{}°C".format(
|
"{}—{}°C".format(
|
||||||
round(weather["daily"][0]["temp"]["min"]),
|
round(weather["next_6_hours"]["details"]["air_temperature_min"]),
|
||||||
round(weather["daily"][0]["temp"]["max"]),
|
round(weather["next_6_hours"]["details"]["air_temperature_max"]),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
city = city.replace("%", "%%")
|
city = city.replace("%", "%%")
|
||||||
conditions.insert(0, f"%{{F#888}}%{{Tx}}%{{T-}} {city}%{{F-}}")
|
conditions.insert(0, f"%{{F#888}}{city}%{{F-}}")
|
||||||
output = " ".join(conditions).replace("%{Tx}", "%%{T%d}" % options.font_index)
|
output = " ".join(conditions).replace("%{Tx}", "%%{T%d}" % options.font_index)
|
||||||
logger.debug("output: %s", output)
|
logger.debug("output: %s", output)
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ def on_overlay_draw(widget, cctx, ctx):
|
||||||
|
|
||||||
# Weather
|
# Weather
|
||||||
# We can have polybar markups in it. We assume %{Tx} means to use
|
# We can have polybar markups in it. We assume %{Tx} means to use
|
||||||
# Font Awesome 6 and we ignore font color change. The parsing is
|
# Weather Icons and we ignore font color change. The parsing is
|
||||||
# quite basic.
|
# quite basic.
|
||||||
if ctx.weather:
|
if ctx.weather:
|
||||||
data = re.sub(r"%{F[#\d+-]+?}", "", ctx.weather)
|
data = re.sub(r"%{F[#\d+-]+?}", "", ctx.weather)
|
||||||
|
@ -120,7 +120,7 @@ def on_overlay_draw(widget, cctx, ctx):
|
||||||
font = ctx.font_family
|
font = ctx.font_family
|
||||||
continue
|
continue
|
||||||
elif chunk.startswith("%{T"):
|
elif chunk.startswith("%{T"):
|
||||||
font = "Font Awesome 6 Pro"
|
font = "Weather Icons"
|
||||||
continue
|
continue
|
||||||
elif not chunk:
|
elif not chunk:
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -29,6 +29,7 @@ foreground = ${colors.foreground}
|
||||||
font-0 = Iosevka Term SS18:style=Regular:size=10;4
|
font-0 = Iosevka Term SS18:style=Regular:size=10;4
|
||||||
font-1 = Font Awesome 6 Pro:style=Solid:size=10;4
|
font-1 = Font Awesome 6 Pro:style=Solid:size=10;4
|
||||||
font-2 = Font Awesome 6 Brands:style=Regular:size=10;4
|
font-2 = Font Awesome 6 Brands:style=Regular:size=10;4
|
||||||
|
font-3 = Weather Icons:style=Regular:size=10;4
|
||||||
|
|
||||||
modules-left = i3
|
modules-left = i3
|
||||||
modules-center = date weather
|
modules-center = date weather
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue