Add a 13 pt additional font and use it for the weather icon only, so the rest of the bar and its height are unchanged.
82 lines
3.7 KiB
Bash
Executable File
82 lines
3.7 KiB
Bash
Executable File
#!/bin/bash
|
|
# Current weather for xmobar, e.g. "<icon> 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.
|
|
# With "notify": show the description (e.g. "Light drizzle, mist") and temperature in a notification instead.
|
|
|
|
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
|
|
if [[ $1 == notify ]]; then notify-send "Weather" "No report from $STATION"; else echo "<fn=1>${ICON[thermometer]}</fn> N/A"; fi
|
|
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' | sed 's/^ *//' | grep -v vicinity)
|
|
wx=${wx,,}
|
|
sky=$(sed -n 's/^Sky conditions: //p' <<< "$report")
|
|
# CAVOK/NSC (no cloud below 5000 ft) have no sky line in the decoded report
|
|
[[ -z $sky ]] && grep -qE '^ob: .* (CAVOK|NSC) ' <<< "$report" && sky=clear
|
|
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
|
|
|
|
if [[ $1 == notify ]]; then
|
|
if [[ -n $wx ]]; then desc=$(paste -sd, <<< "$wx" | sed 's/,/, /g')
|
|
elif [[ $icon == day_sunny ]]; then desc=sunny
|
|
else desc=${sky:-unknown}
|
|
fi
|
|
notify-send "${ICON[$icon]} Weather" "${desc^}, $temp°C"
|
|
exit 0
|
|
fi
|
|
echo "<fn=1>${ICON[$icon]}</fn> <fc=$color>$temp</fc>°C"
|