The weather widgets asked wttr.in to geolocate by IP, which lands on
whatever city the ISP registers its address block under -- Downey when
you're in Malibu. Now the location can be set explicitly:
* Click the location in the weather panel to search via open-meteo
geocoding, pick a suggestion (disambiguated by region), and it sticks.
The X next to the field returns to IP auto-detect, as does committing
an empty search.
* State lives in ~/.local/state/omarchy/settings/weather.json as
{name, latitude, longitude}, owned by the new omarchy-weather-location
command (bare call prints the current location, --set/--clear write).
The panel watches the file, so hand edits apply live.
* Stored coordinates make wttr.in and open-meteo exact. Open-meteo also
now supplies current conditions alongside the daily forecast it
already served, which fills the panel within a second of a location
change instead of waiting out wttr.in's multi-second responses; wttr
results still win once they land. Failed wttr fetches retry instead
of sitting stale until the next refresh cycle.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
46 lines
1.9 KiB
Bash
Executable File
46 lines
1.9 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# omarchy:summary=Returns a weather condition icon, adjusted for live sunrise and sunset.
|
|
|
|
# Only consult the helper when a location is stored: this runs every minute,
|
|
# and the helper's dynamic fallback would cost an extra wttr.in request when
|
|
# nothing is set — the bare j1 fetch already auto-detects by IP.
|
|
query=""
|
|
if [[ -s "$HOME/.local/state/omarchy/settings/weather.json" ]]; then
|
|
location=$(omarchy-weather-location 2>/dev/null)
|
|
[[ -n $location ]] && query=$(jq -rn --arg location "$location" '$location | @uri')
|
|
fi
|
|
|
|
weather_data=$(curl -fsS --max-time 3 "https://wttr.in/${query}?format=j1" 2>/dev/null | jq -er '[.current_condition[0].weatherCode, .weather[0].astronomy[0].sunrise, .weather[0].astronomy[0].sunset] | select(all(. != null and . != "")) | @tsv' 2>/dev/null) || exit 1
|
|
|
|
IFS=$'\t' read -r weather_code sunrise sunset <<< "$weather_data"
|
|
if [[ ! $weather_code =~ ^[0-9]+$ || ! $sunrise =~ ^[0-9]{1,2}:[0-9]{2}\ [AP]M$ || ! $sunset =~ ^[0-9]{1,2}:[0-9]{2}\ [AP]M$ ]]; then
|
|
exit 1
|
|
fi
|
|
|
|
now_epoch=$(date +%s)
|
|
sunrise_epoch=$(date -d "today $sunrise" +%s 2>/dev/null || echo 0)
|
|
sunset_epoch=$(date -d "today $sunset" +%s 2>/dev/null || echo 0)
|
|
|
|
if (( sunrise_epoch > 0 && sunset_epoch > 0 && (now_epoch < sunrise_epoch || now_epoch >= sunset_epoch) )); then
|
|
night=true
|
|
else
|
|
night=false
|
|
fi
|
|
|
|
case $weather_code in
|
|
113) [[ $night == "true" ]] && icon="" || icon="" ;;
|
|
116) [[ $night == "true" ]] && icon="" || icon="" ;;
|
|
119|122) icon="" ;;
|
|
143|248|260) icon="" ;;
|
|
176|263|353) [[ $night == "true" ]] && icon="" || icon="" ;;
|
|
179|227|230|323|326|368) [[ $night == "true" ]] && icon="" || icon="" ;;
|
|
182|185|281|284|311|314|317|320|350|362|365|374|377) icon="" ;;
|
|
200|386|389|392|395) icon="" ;;
|
|
266|293|296|299|302|305|308|356|359) icon="" ;;
|
|
329|332|335|338|371) icon="" ;;
|
|
*) icon="" ;;
|
|
esac
|
|
|
|
printf '%s\n' "$icon"
|