From 96903a4d228fbd81b1d0e8c78e7169cb8968d324 Mon Sep 17 00:00:00 2001 From: Daniele Fucini Date: Thu, 12 Nov 2026 16:54:08 +0100 Subject: [PATCH] Show a weather condition icon in xmobar Replace the Weather plugin with weather.sh, which picks an icon from the METAR weather/sky and uses moon icons when the sun is down. --- .config/xmobar/weather.sh | 69 ++++++++++++++++++++++++++++++++++ .config/xmobar/xmobarrc_hdmi | 11 +----- .config/xmobar/xmobarrc_laptop | 11 +----- 3 files changed, 73 insertions(+), 18 deletions(-) create mode 100755 .config/xmobar/weather.sh diff --git a/.config/xmobar/weather.sh b/.config/xmobar/weather.sh new file mode 100755 index 0000000..0bb2748 --- /dev/null +++ b/.config/xmobar/weather.sh @@ -0,0 +1,69 @@ +#!/bin/bash +# Current weather for xmobar, e.g. " 7°C": NOAA's decoded METAR (the source of xmobar's Weather plugin) +# Icon from the weather, else the sky conditions; clear/partly/mostly cloudy get moon icons when the sun is down. +# Temperature colors match the plugin's -L 0 -H 30: low up to 0, high above 30. + +STATION=LZIB LAT=48.2 LON=17.2 + +declare -A ICON=( + [thermometer]=$'\xef\x8b\x89' [day_sunny]=$'\xee\x8c\x8d' [night_clear]=$'\xee\x8c\xab' + [day_cloudy]=$'\xee\x8c\x82' [night_partly_cloudy]=$'\xee\x8d\xb9' [day_sunny_overcast]=$'\xee\x8c\x8c' + [night_cloudy]=$'\xee\x8d\xbe' [cloudy]=$'\xee\x8c\x92' [cloud]=$'\xee\x8c\xbd' + [thunderstorm]=$'\xee\x8c\x9d' [rain_mix]=$'\xee\x8c\x96' [snow]=$'\xee\x8c\x9a' [showers]=$'\xee\x8c\x99' + [rain]=$'\xee\x8c\x98' [sprinkle]=$'\xee\x8c\x9b' [fog]=$'\xee\x8c\x93' [smoke]=$'\xee\x8d\x9c' + [dust]=$'\xee\x8d\x9d' +) + +report=$(curl -sf --max-time 20 https://tgftp.nws.noaa.gov/data/observations/metar/decoded/"$STATION".TXT) +temp=$(sed -n 's/^Temperature: .*(\([-0-9.]*\) C).*/\1/p' <<< "$report") +if [[ -z $temp ]]; then + echo "${ICON[thermometer]} N/A" + exit 0 +fi + +# Phenomena "in the vicinity" aren't at the station; the rest are e.g. "light drizzle; mist" +wx=$(sed -n 's/^Weather: //p' <<< "$report" | tr ';' '\n' | grep -v vicinity | tr '\n' ' ') +wx=${wx,,} +sky=$(sed -n 's/^Sky conditions: //p' <<< "$report") +sky=${sky,,} + +# Sun above the horizon (elevation > -0.833°, as for sunrise/sunset) right now, from the low-precision solar position +sun_up() { + awk -v t="$(date +%s)" -v lat="$LAT" -v lon="$LON" 'BEGIN { + r = atan2(0, -1) / 180; d = t / 86400 - 10957.5 + g = (357.529 + 0.98560028 * d) * r + l = (280.459 + 0.98564736 * d + 1.915 * sin(g) + 0.020 * sin(2 * g)) * r + e = (23.439 - 0.00000036 * d) * r + ra = atan2(cos(e) * sin(l), cos(l)); s = sin(e) * sin(l); dec = atan2(s, sqrt(1 - s * s)) + h = (280.46061837 + 360.98564736629 * d + lon) * r - ra + exit !(sin(lat * r) * sin(dec) + cos(lat * r) * cos(dec) * cos(h) > sin(-0.833 * r)) + }' +} + +case $wx in + *thunder*) icon=thunderstorm ;; + *freezing*|*sleet*|*ice\ pellets*|*hail*) icon=rain_mix ;; + *snow*rain*|*rain*snow*|*snow*drizzle*|*drizzle*snow*) icon=rain_mix ;; + *snow*) icon=snow ;; + *showers*) icon=showers ;; + *rain*) icon=rain ;; + *drizzle*) icon=sprinkle ;; + *fog*|*mist*) icon=fog ;; + *haze*|*smoke*) icon=smoke ;; + *dust*|*sand*) icon=dust ;; + *) + case $sky in + clear*) if sun_up; then icon=day_sunny; else icon=night_clear; fi ;; + "mostly clear"*|"partly cloudy"*) if sun_up; then icon=day_cloudy; else icon=night_partly_cloudy; fi ;; + "mostly cloudy"*) if sun_up; then icon=day_sunny_overcast; else icon=night_cloudy; fi ;; + overcast*|obscured*) icon=cloudy ;; + *) icon=cloud ;; + esac + ;; +esac + +if awk -v t="$temp" 'BEGIN { exit !(t > 30) }'; then color="#ffb86c" +elif awk -v t="$temp" 'BEGIN { exit !(t > 0) }'; then color="#50fa7b" +else color="#8be9fd" +fi +echo "${ICON[$icon]} $temp°C" diff --git a/.config/xmobar/xmobarrc_hdmi b/.config/xmobar/xmobarrc_hdmi index 4efef84..2984304 100644 --- a/.config/xmobar/xmobarrc_hdmi +++ b/.config/xmobar/xmobarrc_hdmi @@ -8,14 +8,7 @@ Config { overrideRedirect = True , borderColor = "#24283b" , allDesktops = True , pickBroadest = True - , commands = [ Run Weather "LZIB" - [ "--template", "\xf2c9 °C" - , "-L", "0" - , "-H", "30" - , "--low" , "#8be9fd" - , "--normal" , "#50fa7b" - , "--high" , "#ffb86c" - ] 9000 + , commands = [ Run Com "/home/fuxino/.config/xmobar/weather.sh" [] "weather" 9000 , Run MultiCpu [ "--template" , "\xf4bc %" , "--Low" , "25" @@ -55,5 +48,5 @@ Config { overrideRedirect = True ] , sepChar = "%" , alignSep = "}{" - , template = "  | %UnsafeXMonadLog% } %multicpu% %coretemp% | %memory% |  %kbd% { %calcurse%%backup%%updates%%LZIB% · %ens_brief% | %pactl_volume% | %date% " + , template = "  | %UnsafeXMonadLog% } %multicpu% %coretemp% | %memory% |  %kbd% { %calcurse%%backup%%updates%%weather% · %ens_brief% | %pactl_volume% | %date% " } diff --git a/.config/xmobar/xmobarrc_laptop b/.config/xmobar/xmobarrc_laptop index ce5665d..56a8b53 100644 --- a/.config/xmobar/xmobarrc_laptop +++ b/.config/xmobar/xmobarrc_laptop @@ -8,14 +8,7 @@ Config { overrideRedirect = True , borderColor = "#24283b" , allDesktops = True , pickBroadest = True - , commands = [ Run Weather "LZIB" - [ "--template", "\xf2c9 °C" - , "-L", "0" - , "-H", "30" - , "--low" , "#8be9fd" - , "--normal" , "#50fa7b" - , "--high" , "#ffb86c" - ] 9000 + , commands = [ Run Com "/home/fuxino/.config/xmobar/weather.sh" [] "weather" 9000 , Run MultiCpu [ "--template" , "\xf4bc %" , "--Low" , "25" @@ -56,5 +49,5 @@ Config { overrideRedirect = True ] , sepChar = "%" , alignSep = "}{" - , template = "  | %UnsafeXMonadLog% } %multicpu% %coretemp% | %memory% |  %kbd% { %calcurse%%backup%%updates%%LZIB% · %ens_brief% | %pactl_volume% | %date% %_XMONAD_TRAYPAD% " + , template = "  | %UnsafeXMonadLog% } %multicpu% %coretemp% | %memory% |  %kbd% { %calcurse%%backup%%updates%%weather% · %ens_brief% | %pactl_volume% | %date% %_XMONAD_TRAYPAD% " }