Files
dotfiles/ags/weather/openweathermap.sh
T
2024-09-03 12:22:09 +07:00

433 lines
13 KiB
Bash

#!/bin/sh
apiKey=""
defaultLocation=""
Ags=0
Debug=0
output=""
WindSpeedUnit="kph"
DegreeCharacter="°C"
HumidityUnit="%"
CloudCoverUnit="%"
RainUnit=" mm"
function debug_break() {
echo "-----"
}
function get_script_argument_options() {
if [[ $firstArgLetter == "a" ]]; then
Ags=1
fi
if [[ $firstArgLetter == "d" ]]; then
Debug=1
fi
}
function get_config_file_data() {
if [ -f "$ConfigFile" ]; then
readarray -t line < "$ConfigFile"
apiKey=${line[0]}
defaultLocation=${line[1]}
fi
if [ "$Debug" = "1" ]; then
# echo "apiKey: $apiKey"
echo "defaultLocation: $defaultLocation"
debug_break
fi
if [[ "$apiKey" == "" || "$defaultLocation" == "" ]]; then
echo "Wrong Config file."
exit 1
fi
}
function check_api_status() {
check=$(echo "$response" | grep -c -e '"cod":"40"' || true)
check2=$(echo "$response" | grep -c -e '"cod":"30"' || true)
sum=$(( check + check2 ))
if [ $sum -gt 0 ];then
exit 99
fi
}
function get_api_response() {
if [ "$Debug" = "1" ]; then
echo "API REQUEST TO GET DATA. URL: $URL"
fi
# Make the API request using curl
# Check if the request was successful
if ! response=$(curl -s "$URL"); then
echo "Error making API request"
exit 1
fi
# Save response to cache file
echo "$response" > "$CacheFile"
if [ "$Debug" = "1" ]; then
echo "$response"
debug_break
fi
check_api_status
}
function get_api_response_from_cache_file() {
if [ "$Debug" = "1" ]; then
echo 'DATA FROM CACHE'
fi
response=$(cat "$CacheFile")
if [ "$Debug" = "1" ]; then
echo "$response"
debug_break
fi
check_api_status
}
function get_response() {
# Check if cache file exists and is less than 5 minutes old
if [ -f "$CacheFile" ] && [ $(($(date +%s) - $(date -r "$CacheFile" +%s))) -lt 300 ]; then
get_api_response_from_cache_file
else
get_api_response
fi
}
function print_weather_output() {
if [ "$Debug" = "1" ]; then
echo "NOW: $nowTemperature"
fi
if [ -z "$output" ]; then
echo "No weather data to output."
exit 1
fi
if [ "${output: -1}" = "," ]; then
output="${output%,}"
fi
output="[$output]"
if [ "$Ags" == "1" ]; then
ags -r "weather.setTooltip($output)"
ags -r "weather.setTemperatureWeather(\"$nowTemperature\")"
else
echo "$output"
fi
}
function get_debug_info_sunset_and_sunrise_hours() {
if [ "$Debug" = "1" ]; then
echo "Now: $CurrentTime"
CurrentHour=$(date +"%-H" -d @"$CurrentTime")
echo "Current: $CurrentHour"
echo "SunsetHour: $SunsetHour"
echo "Sunrise: $SunriseHour"
debug_break
fi
}
#sunset information from the Current weather response
function get_current_sunset_and_sunrise_hours() {
SunsetTime=$(echo "$response" | jq -r .sys.sunset)
SunriseTime=$(echo "$response" | jq -r .sys.sunrise)
SunsetHour=$(date +"%-H" -d @"$SunsetTime")
SunriseHour=$(date +"%-H" -d @"$SunriseTime")
#current time
CurrentTime=$(date +%s)
get_debug_info_sunset_and_sunrise_hours
}
#sunset information from the weather Forecast response
function get_forecast_sunset_and_sunrise_hours() {
SunsetTime=$(echo "$response" | jq -r .city.sunset)
SunriseTime=$(echo "$response" | jq -r .city.sunrise)
SunsetHour=$(date +"%-H" -d @"$SunsetTime")
SunriseHour=$(date +"%-H" -d @"$SunriseTime")
#current time
CurrentTime=$(date +%s)
get_debug_info_sunset_and_sunrise_hours
}
#Updates provided weather icon with night icons and sunset/sunrise icons
function get_weather_icon() {
icon=$1
checkNewIcon="True"
if [[ "$icon" == "☀️" || "$icon" == "🌤" || "$icon" == "⛅" ]]; then
if [[ $WeatherHour -eq $SunriseHour ]]; then
checkNewIcon="False"
icon="🌄"
fi
if [[ $checkNewIcon == "True" && $WeatherHour -eq $SunsetHour ]]; then
checkNewIcon="False"
icon="🌇"
fi
fi
if [[ $checkNewIcon == "True" && ($WeatherHour -ge $SunsetHour || $WeatherHour -le $SunriseHour) ]]; then
case $1 in
"☀️") icon="🌑" ;;
"🌤") icon="🌑" ;;
"⛅") icon="" ;;
"☁") icon="" ;;
"🌦") icon="" ;;
"🌧️") icon="" ;;
"🌨") icon="" ;;
"") icon="" ;;
esac
if [[ "$icon" == "🌑" ]]; then
# Generate a random number between 1 and 5
random_number=$(( RANDOM % 5 + 1 ))
# Check the random number and provide different outputs
if [ $random_number -eq 1 ]; then
icon="🌕"
fi
fi
fi
}
function get_min_and_max_weather() {
# MinTemperature=$(echo "$response" | jq -r .list["$i"].main.temp_min | tr '\n' ' ')
# MaxTemperature=$(echo "$response" | jq -r .list["$i"].main.temp_max | tr '\n' ' ')
# Check if a new day has started
Day=$(date +"%Y-%m-%d" -d @"${WeatherDate}")
if [[ "$Day" != "$CurrentDay" ]]; then
# Reset variables for the new day
CurrentDay="$Day"
MinTemperature="$Temperature"
MaxTemperature="$Temperature"
fi
# Update min and max temperatures
if (( $(echo "$Temperature < $MinTemperature" | bc -l) )); then
MinTemperature="$Temperature"
fi
if (( $(echo "$Temperature > $MaxTemperature" | bc -l) )); then
MaxTemperature="$Temperature"
fi
MinTemp=$(printf '%.*f\n' 0 "$MinTemperature")
MaxTemp=$(printf '%.*f\n' 0 "$MaxTemperature")
}
function clear_defaults() {
WeatherDate=""
WeatherHour=""
FormattedDate=""
Temperature=""
Temperature=""
# ShortWeather=""
LongWeather=""
Humidity=""
CloudCover=""
WindSpeed=""
MinTemperature=""
MaxTemperature=""
MinTemp=""
MaxTemp=""
icons=""
Rain1h="null"
Rain3h="null"
}
function weather_data() {
forecast=$1
if [ "$forecast" = "f" ]; then
FormattedDate=$(date -d @"${WeatherDate}" +"%A, %B %d, %Y")
# ShortWeather=$(echo "$response" | jq -r .list["$i"].weather[] | jq -r .main | tr '\n' ' '| awk '{$1=$1};1' )
LongWeather=$(echo "$response" | jq -r .list["$i"].weather[] | jq -r .description | sed -E 's/\S+/\u&/g' | tr '\n' ' '| awk '{$1=$1};1' )
Humidity=$(echo "$response" | jq -r .list["$i"].main.humidity | tr '\n' ' '| awk '{$1=$1};1' )
CloudCover=$(echo "$response" | jq -r .list["$i"].clouds.all | tr '\n' ' '| awk '{$1=$1};1' )
WindSpeed=$(echo "$response" | jq -r .list["$i"].wind.speed | tr '\n' ' ' | awk '{$1=$1};1' )
WindSpeed=$(printf '%.*f\n' 1 "$WindSpeed")
Rain1h=$(echo "$response" | jq -r .list["$i"] | jq -r '.rain."1h"')
Rain3h=$(echo "$response" | jq -r .list["$i"] | jq -r '.rain."3h"')
icons=$(echo "$response" | jq -r .list["$i"].weather[] | jq -r .icon | tr '\n' ' ' )
else
#current weather
WeatherDate=$(echo "$response" | jq -r .dt | tr '\n' ' ')
WeatherHour=$(date +"%-H" -d @"${WeatherDate}")
FormattedDate=$(date -d @"${WeatherDate}" +"%A, %B %d, %Y")
# Extracting and formatting the temperature
Temperature=$(echo "$response" | jq -r .main.temp | tr '\n' ' ')
# Use bc to format the temperature to 0 decimal places
Temperature=$(echo "$Temperature" | bc -l | awk '{printf "%.0f", $1}')
# ShortWeather=$(echo "$response" | jq -r .weather[0].main | tr '\n' ' '| awk '{$1=$1};1' )
LongWeather=$(echo "$response" | jq -r .weather[0].description | sed -E 's/\S+/\u&/g' | tr '\n' ' '| awk '{$1=$1};1' )
Humidity=$(echo "$response" | jq -r .main.humidity | tr '\n' ' '| awk '{$1=$1};1' )
CloudCover=$(echo "$response" | jq -r .clouds.all | tr '\n' ' '| awk '{$1=$1};1' )
WindSpeed=$(echo "$response" | jq -r .wind.speed | tr '\n' ' ' | awk '{$1=$1};1' )
WindSpeed=$(printf '%.*f\n' 1 "$WindSpeed")
Rain1h=$(echo "$response" | jq -r '.rain."1h"')
Rain3h=$(echo "$response" | jq -r '.rain."3h"')
MinTemperature=$(echo "$response" | jq -r .main.temp_min | tr '\n' ' ')
MaxTemperature=$(echo "$response" | jq -r .main.temp_max | tr '\n' ' ')
MinTemp=$(echo "$MinTemperature" | bc -l | awk '{printf "%.0f", $1}')
MaxTemp=$(echo "$MaxTemperature" | bc -l | awk '{printf "%.0f", $1}')
icons=$(echo "$response" | jq -r .weather[0].icon | tr '\n' ' ')
fi
Rain="0"
if [[ "$Rain3h" != "null" ]]; then
Rain="$Rain3h"
fi
if [[ "$Rain1h" != "null" ]]; then
Rain="$Rain1h"
fi
iconval=${icons%?}
case $iconval in
01*) get_weather_icon "☀️";;
02*) get_weather_icon "🌤";;
03*) get_weather_icon "⛅";;
04*) get_weather_icon "☁";;
09*) get_weather_icon "🌦";;
10*) get_weather_icon "🌧️";;
11*) get_weather_icon "🌩";;
13*) get_weather_icon "🌨";;
50*) get_weather_icon "";;
esac
if [ "$Debug" = "1" ]; then
echo "WeatherDate: $FormattedDate, Hour: $WeatherHour"
# echo "ShortWeather: $ShortWeather"
echo "LongWeather: $LongWeather"
echo "Humidity: $Humidity$HumidityUnit"
echo "CloudCover: $CloudCover$CloudCoverUnit"
echo "WindSpeed: $WindSpeed $WindSpeedUnit"
echo "Temperature: $Temperature$DegreeCharacter"
echo "icon: $icon"
echo "MinTemp: $MinTemp$DegreeCharacter"
echo "MaxTemp: $MaxTemp$DegreeCharacter"
echo "rain_1h: $Rain1h"
echo "rain_3h: $Rain3h"
debug_break
fi
if [ "$forecast" != "f" ]; then
nowTemperature="$icon $Temperature$DegreeCharacter"
fi
output+="{\"date\":\"$FormattedDate\",\"hour\":\"$WeatherHour\",\"temperature\":\"${Temperature}°C\",\"icon\":\"$icon\",\"wind\":\"$WindSpeed$WindSpeedUnit\",\"rain\":\"$Rain$RainUnit\",\"humidity\":\"$Humidity$HumidityUnit\",\"minTemp\":\"$MinTemp$DegreeCharacter\",\"maxTemp\":\"$MaxTemp$DegreeCharacter\"},"
}
function get_weather_forecast_data() {
CurrentDay=""
# PreviousDay=""
TomorrowDate=$(date -d '+1 day' +"%s")
clear_defaults
i=0
# NumEntries=$(echo "$response" |jq -r .cnt)
# while [ $i -lt $NumEntries ]; do
while [ $i -lt 40 ]; do
WeatherDate=$(echo "$response" | jq -r .list[$i].dt | tr '\n' ' ')
WeatherHour=$(date +"%-H" -d @"${WeatherDate}")
CastDate=$(date +"%s" -d @"${WeatherDate}")
Temperature=$(echo "$response" | jq -r .list[$i].main.temp | tr '\n' ' ')
Temperature=$(echo "$Temperature" | bc -l | awk '{printf "%.0f", $1}')
get_min_and_max_weather
#show the weather forecast hourly until it reaches tomorrow date, then only 1 hour
if [ "$CastDate" -le "$TomorrowDate" ]; then
weather_data "f"
else
if [ "$WeatherHour" -ge "17" ] && [ "$WeatherHour" -le "18" ] ||
[ "$WeatherHour" -ge "18" ] && [ "$WeatherHour" -le "19" ]; then
# if [[ "$CurrentDay" != "$PreviousDay" ]]; then
weather_data "f"
# fi
# PreviousDay=$CurrentDay
fi
fi
i=$((i + 1))
done
}
function call_weather_current_api() {
# API endpoint URL Current Weather
URL="http://api.openweathermap.org/data/2.5/weather?id=$defaultLocation&units=metric&appid=$apiKey"
# Current Weather API cache file path based on defaultLocation
CacheFile="/tmp/weather_cache_${defaultLocation}_current.json"
get_response
# get_api_response_from_cache_file
get_current_sunset_and_sunrise_hours
weather_data "c"
}
function call_weather_forecast_api() {
# API endpoint URL Forecast
URL="http://api.openweathermap.org/data/2.5/forecast?id=$defaultLocation&units=metric&appid=$apiKey"
# Forecast API cache file path based on defaultLocation
CacheFile="/tmp/weather_cache_${defaultLocation}_forecast.json"
get_response
# get_api_response_from_cache_file
#used to retrieve forecast data
get_forecast_sunset_and_sunrise_hours
get_weather_forecast_data
}
#get this scripts arguments => (ags, debug or none)
#checks the first letter of the argument provided to the script
if [[ $# -ge 1 ]]; then
firstArgLetter="$(echo "$1" | head -c 1)"
else
firstArgLetter=
fi
get_script_argument_options
#call to get config file data => (apiKey and defaultLocation)
ConfigFile="$HOME/.config/scripts/weather.rc"
get_config_file_data
call_weather_current_api
call_weather_forecast_api
#prints out final output / sends over the data
print_weather_output