diff --git a/DESIGN.md b/DESIGN.md index 9388859..c09b412 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -7,24 +7,58 @@ Nous vous conseillons d'utiliser le logiciel PlantUML pour générer vos diagram ## Schéma général -Décrivez ici le schéma général de votre programme. Quels sont les composants principaux et comment interagissent-ils? +Décrivez ici le schéma général de votre programme. Quels sont les composants principaux et comment interagissent-ils ? + +On a 2 principaux composants : + +* WeatherDataAPI +* WeatherDisplay + +WeatherDisplay contient un ensemble d'instances de WeatherDisplay. Chacune de ces instances retournent des données ayant l'interface WeatherData, ce qui permet au WeatherDisplay de les afficher. ## Utilisation du polymorphisme -Comment utilisez-vous le polymorphisme dans votre programme? +Comment utilisez-vous le polymorphisme dans votre programme ? -## Utilisation de la déléguation +Nous utilisons les interfaces suivantes servant à définir les parties publiques de nos Classes : -Comment utilisez-vous la délégation dans votre programme? +* WeatherDataAPI +* WeatherDisplay + +## Utilisation de la délégation + +Comment utilisez-vous la délégation dans votre programme ? + +Nous avons essayé de mettre en oeuvre un maximum de forme de délégation dans le projet. + +Voici les principales formes de délégations qui se trouvent dans le projet : + +### JSONFetcher + +Les requêtes HTTP(S) et la transformation de la réponse en JSONObject est abstraite grâce à la classe JSONFetcher + +### City + +Nous utilisons une classe City afin de stocker le nom d'une ville, et de faire le lien avec ses coordonnées. + +Cela permet d'abstraire un appel à l'API api-adresse.data.gouv.fr pour obtenir les coordonnées depuis le nom de la ville. ## Utilisation de l'héritage -Comment utilisez-vous l'héritage dans votre programme? +Comment utilisez-vous l'héritage dans votre programme ? + +Nous avons limité au maximum l'héritage dans le projet et nous sommes concentrés sur des relations de composition. + +Au final, pour permettre un système de cache, les trois classes WeatherAPI, OpenMeteo et OpenWeatherMap héritent d'une classe WeatherDataCachedAPI. ## Utilisation de la généricité -Comment utilisez-vous la généricité dans votre programme? +Comment utilisez-vous la généricité dans votre programme ? + +Nous n'avons pas eu besoin de généricité dans notre programme. ## Utilisation des exceptions -Comment utilisez-vous les exceptions dans votre programme? \ No newline at end of file +Comment utilisez-vous les exceptions dans votre programme ? + +Nous utilisons WeatherFetchingException qui est une Exception qui est envoyée lorsqu' diff --git a/src/main/java/eirb/pg203/Main.java b/src/main/java/eirb/pg203/Main.java index dfd4a0b..9d1fb1d 100644 --- a/src/main/java/eirb/pg203/Main.java +++ b/src/main/java/eirb/pg203/Main.java @@ -4,12 +4,26 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.time.Instant; +import eirb.pg203.weather.display.WeatherDisplay; +import eirb.pg203.weather.display.WeatherDisplayBasic; +import eirb.pg203.weather.data.api.OpenMeteo; +import eirb.pg203.weather.data.api.OpenWeatherMap; +import eirb.pg203.weather.data.api.WeatherAPI; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Scanner; +/** + * Main class + */ public class Main { + + /** + * Default constructor (private) + */ + private Main() {}; + private static class Option { String flag, value; public Option(String flag, String value){ @@ -31,6 +45,11 @@ public class Main { } } + /** + * Main loop + * @param args list of arguments + * @throws IllegalArgumentException if arguments are not provided or in a wrong way + */ public static void main(String[] args) throws IOException, IllegalArgumentException{ HashMap options = new HashMap<>(); List argsList = new ArrayList<>(); @@ -69,8 +88,6 @@ public class Main { openWeatherMap.loadCacheFromFile("owm.cache.json"); openMeteo.loadCacheFromFile("om.cache.json"); - System.out.println(weatherAPI.toJSON().toString()); - WeatherDisplay display = new WeatherDisplayBasic(); display.addAPI(weatherAPI); diff --git a/src/main/java/eirb/pg203/Temperature.java b/src/main/java/eirb/pg203/Temperature.java deleted file mode 100644 index e37efe1..0000000 --- a/src/main/java/eirb/pg203/Temperature.java +++ /dev/null @@ -1,42 +0,0 @@ -package eirb.pg203; - -import java.time.Instant; - -/** - * Representation of a temperature in a city at a specific date - */ -public class Temperature { - private City city; - private Instant date; - private float temp; - - Temperature(float temp, City city, Instant date) { - this.temp = temp; - this.city = city; - this.date = date; - } - - /** - * Get the name of the city from where the temperature come from - * @return city - */ - public String getCity() { - return this.city.getCityName(); - } - - /** - * Get the date - * @return date - */ - public Instant getDate() { - return date; - } - - /** - * Get the temperature - * @return temperature - */ - public float getTemp() { - return temp; - } -} diff --git a/src/main/java/eirb/pg203/WeatherDataAPI.java b/src/main/java/eirb/pg203/WeatherDataAPI.java deleted file mode 100644 index ccea000..0000000 --- a/src/main/java/eirb/pg203/WeatherDataAPI.java +++ /dev/null @@ -1,34 +0,0 @@ -package eirb.pg203; - -import java.io.IOException; -import java.util.ArrayList; - -public interface WeatherDataAPI { - - /** - * Fetch the temperature for a specific day in a city - * @param day Since D+0 - * @param city Localisation - * @return Temperature of the day from the city - * @throws IOException when request failed - */ - WeatherData getTemperature(int day, String city) throws IOException; - - /** - * - * @param day Since D+0 - * @param hour Since H+0 - * @param city Localisation - * @return Temperature of the day for a hour from the city - * @throws IOException when request failed - */ - WeatherData getTemperature(int day, int hour, String city) throws IOException; - - ArrayList getTemperatures(int days, String city) throws IOException; - - /*** - * Name of the API - * @return Name of the API - */ - String getAPIName(); -} diff --git a/src/main/java/eirb/pg203/exceptions/WeatherFetchingException.java b/src/main/java/eirb/pg203/exceptions/WeatherFetchingException.java deleted file mode 100644 index 4e21982..0000000 --- a/src/main/java/eirb/pg203/exceptions/WeatherFetchingException.java +++ /dev/null @@ -1,7 +0,0 @@ -package eirb.pg203.exceptions; - -public class WeatherFetchingException extends Exception { - public WeatherFetchingException(String message) { - super(message); - } -} diff --git a/src/main/java/eirb/pg203/utils/Coords.java b/src/main/java/eirb/pg203/utils/Coords.java deleted file mode 100644 index 9f58cb7..0000000 --- a/src/main/java/eirb/pg203/utils/Coords.java +++ /dev/null @@ -1,27 +0,0 @@ -package eirb.pg203.utils; - -public class Coords { - private float lat; - private float lon; - - public Coords(float lat, float lon) { - this.lat = lat; - this.lon = lon; - } - - public float getLat() { - return lat; - } - - public float getLon() { - return lon; - } - - public void setLat(float lat) { - this.lat = lat; - } - - public void setLon(float lon) { - this.lon = lon; - } -} diff --git a/src/main/java/eirb/pg203/WeatherData.java b/src/main/java/eirb/pg203/weather/data/WeatherData.java similarity index 94% rename from src/main/java/eirb/pg203/WeatherData.java rename to src/main/java/eirb/pg203/weather/data/WeatherData.java index 03762f7..e5b4abe 100644 --- a/src/main/java/eirb/pg203/WeatherData.java +++ b/src/main/java/eirb/pg203/weather/data/WeatherData.java @@ -1,14 +1,12 @@ -package eirb.pg203; +package eirb.pg203.weather.data; import java.time.Instant; -import java.util.concurrent.locks.Condition; - import org.json.JSONObject; -import com.sun.net.httpserver.Authenticator.Retry; +import eirb.pg203.weather.utils.City; -class WeatherData { - enum Condition { +public class WeatherData { + public enum Condition { SUNNY("☀️"), PARTIAL("🌤"), CLOUDY("☁️"), @@ -115,7 +113,8 @@ class WeatherData { return WindDirection.ERROR; } - WeatherData(City city, Instant date, float temp, float windSpeed, float windDirectionAngle, Condition condition) { + + public WeatherData(City city, Instant date, float temp, float windSpeed, float windDirectionAngle, Condition condition) { this.city = city; this.date = date; this.temp = temp; diff --git a/src/main/java/eirb/pg203/weather/data/WeatherData.java.tmp b/src/main/java/eirb/pg203/weather/data/WeatherData.java.tmp new file mode 100644 index 0000000..b728906 --- /dev/null +++ b/src/main/java/eirb/pg203/weather/data/WeatherData.java.tmp @@ -0,0 +1,263 @@ +package eirb.pg203.weather.data; + +import eirb.pg203.weather.utils.City; + +import java.time.Instant; +import java.util.Locale; + +/** + * Weather Data representation + * A weather data is a Temperature, on a date, in a city, with a weather condition and wind speed + direction + * The representation of the data is managed in this class. + */ +public class WeatherData { + + /** + * Representation of a weather condition (with a smiley for String representation) + */ + public enum Condition { + /** + * Sunny condition + */ + SUNNY("☀️"), + /** + * A little a bit of sun and a little bit of clouds + */ + PARTIAL("🌤"), + /** + * Cloudy weather + */ + CLOUDY("☁️"), + /** + * Rainy weather -> like most of the time in Bordeaux + */ + RAINY("🌧"), + /** + * Impossible to determine a Weather Condition + */ + ERROR("E"); + + private final String desc; + Condition(String desc) { this.desc = desc; } + + @Override + public String toString() { + return this.desc; + } + } + + /** + * Representation of the wind direction with an arrow + */ + public enum WindDirection { + /** + * North direction + */ + N("🡩"), + /** + * North East direction + */ + NE("🡭"), + /** + * East direction + */ + E("🡪"), + /** + * South East direction + */ + SE("🡮"), + /** + * South direction + */ + S("🡫"), + /** + * South West direction + */ + SW("🡯"), + /** + * West direction + */ + W("🡨"), + /** + * North West direction + */ + NW("🡬"), + + /** + * Error wind direction + */ + ERROR("E"); + + private final String desc; + WindDirection(String desc) {this.desc = desc;} + + @Override + public String toString(){ return this.desc;}; + } + + + private City city; + private Instant date; + private float temp; + private Condition condition; // cloudly, sunny ... + private float windSpeed; + private float windDirectionAngle; + private WindDirection windDirection; + + + /** + * Get wind direction representation based on the angle + * @param windDirectionAngle float representation of the wind direction + * @return wind direction representation + */ + private WindDirection getWindDirection(float windDirectionAngle) { + if ((windDirectionAngle >= 337.5 && windDirectionAngle <= 360) || (windDirectionAngle >= 0 && windDirectionAngle <= 22.5)) + return WindDirection.N; + if (windDirectionAngle > 22.5 && windDirectionAngle <= 67.5) + return WindDirection.NE; + if (windDirectionAngle > 67.5 && windDirectionAngle <= 112.5) + return WindDirection.E; + if (windDirectionAngle > 112.5 && windDirectionAngle <= 157.5) + return WindDirection.SE; + if (windDirectionAngle > 157.5 && windDirectionAngle <= 202.5) + return WindDirection.S; + if (windDirectionAngle > 202.5 && windDirectionAngle <= 247.5) + return WindDirection.SW; + if (windDirectionAngle > 247.5 && windDirectionAngle <= 292.5) + return WindDirection.W; + if (windDirectionAngle > 292.5 && windDirectionAngle <= 337.5) + return WindDirection.NW; + + return WindDirection.ERROR; + + } + + public WeatherData(City city, Instant date, float temp, float windSpeed, float windDirectionAngle, Condition condition) { + this.city = city; + this.date = date; + this.temp = temp; + this.condition = condition; + this.windSpeed = windSpeed; + this.windDirectionAngle = windDirectionAngle; + this.windDirection = this.getWindDirection(windDirectionAngle); + } + + /** + * Get city from where the weather data come from + * @return city + */ + public City getCity() { + return city; + } + + /** + * Get date of the weather data + * @return date of the Weather data + */ + public Instant getDate() { + return date; + } + + /** + * Get weather condition representation + * @return Weather Condition representation + */ + public Condition getCondition() { + return condition; + } + + /** + * Get temperature value + * @return float temperature + */ + public float getTemp() { + return temp; + } + + /** + * Get wind speed value + * @return wind speed + */ + public float getWindSpeed() { + return windSpeed; + } + + /** + * Get wind direction angle value + * @return Wind direction angle + */ + public float getWindDirectionAngle() {return this.windDirectionAngle;} + + /** + * Get wind direction representation + * @return wind direction representation + */ + public WindDirection getWindDirection() { + return windDirection; + } + + /** + * Set city + * @param city city of the weather representation + */ + public void setCity(City city) { + this.city = city; + } + + /** + * Set date of the weather data + * @param date date + */ + public void setDate(Instant date) { + this.date = date; + } + + /** + * Set weather data representation + * @param condition weather data representation + */ + public void setCondition(Condition condition) { + this.condition = condition; + } + + /** + * Set temperature value + * @param temp Weather data temperature + */ + public void setTemp(float temp) { + this.temp = temp; + } + + /** + * Set wind speed value + * @param windSpeed Wind speed + */ + public void setWindSpeed(float windSpeed) { + this.windSpeed = windSpeed; + } + + /** + * Set wind direction angle value + * @param windDirectionAngle wind direction angle + */ + public void setWindDirectionAngle(float windDirectionAngle) { + this.windDirectionAngle = windDirectionAngle; + this.windDirection = this.getWindDirection(windDirectionAngle); + } + + /** + * WeatherData representation + * 10,70° 🌧 25,80km/h 243,00° 🡯 + * @return String representation of the WeatherData + */ + @Override + public String toString() { + return String.format(Locale.ENGLISH, "%05.2f° %s %05.2fkm/h %06.2f° %s", + this.getTemp(), + this.getCondition().toString(), + this.getWindSpeed(), + this.getWindDirectionAngle(), + this.getWindDirection().toString() + ); + } +} diff --git a/src/main/java/eirb/pg203/OpenMeteo.java b/src/main/java/eirb/pg203/weather/data/api/OpenMeteo.java similarity index 50% rename from src/main/java/eirb/pg203/OpenMeteo.java rename to src/main/java/eirb/pg203/weather/data/api/OpenMeteo.java index f764e12..676837a 100644 --- a/src/main/java/eirb/pg203/OpenMeteo.java +++ b/src/main/java/eirb/pg203/weather/data/api/OpenMeteo.java @@ -1,45 +1,77 @@ -package eirb.pg203; +package eirb.pg203.weather.data.api; -import org.json.JSONArray; +import eirb.pg203.weather.exceptions.WeatherFetchingExceptionCityCoords; +import eirb.pg203.weather.utils.City; +import eirb.pg203.weather.exceptions.WeatherFetchingException; +import eirb.pg203.weather.exceptions.WeatherFetchingExceptionApi; +import eirb.pg203.weather.data.WeatherData; import org.json.JSONObject; -import eirb.pg203.utils.JSONFetcher; +import eirb.pg203.weather.utils.JSONFetcher; import java.io.IOException; import java.net.URI; import java.net.URL; +import java.time.Clock; import java.time.Instant; import java.util.ArrayList; -import eirb.pg203.WeatherData.Condition; +import java.util.Locale; + +import eirb.pg203.weather.data.WeatherData.Condition; // https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41&hourly=temperature_2m +/** + * OpenMeteo implementation + */ public class OpenMeteo extends WeatherCachedAPI { private static final String forecastBaseURL = "https://api.open-meteo.com/v1/forecast"; private static final String dailyQuery = "weather_code,temperature_2m_max,temperature_2m_min,wind_speed_10m_max,wind_direction_10m_dominant"; + JSONFetcher JSONFetcher = new JSONFetcher(); + Clock clock = Clock.systemUTC(); + + /** + * Default constructor + */ + public OpenMeteo() {} + // https://www.nodc.noaa.gov/archive/arc0021/0002199/1.1/data/0-data/HTML/WMO-CODE/WMO4677.HTM - private JSONObject fetchWeather(int days, City city) throws IOException { - URL url = URI.create( - String.format(forecastBaseURL + "?latitude=%.2f&longitude=%.2f&forecast_days=%d&daily=" + dailyQuery, - city.getCityCoords().getLat(), - city.getCityCoords().getLon(), - days - ) - ).toURL(); + private JSONObject fetchWeather(int days, City city) throws WeatherFetchingException{ + URL url = null; + try { + url = URI.create( + String.format(Locale.ENGLISH, forecastBaseURL + "?latitude=%.2f&longitude=%.2f&forecast_days=%d&daily=" + dailyQuery, + city.getCityCoords().getLat(), + city.getCityCoords().getLon(), + days + ) + ).toURL(); + } catch (IOException e) { + throw new WeatherFetchingExceptionCityCoords(); + } - return JSONFetcher.fetch(url); + try { + return JSONFetcher.fetch(url); + } catch (IOException e) { + throw new WeatherFetchingExceptionApi(); + } } + /** + * return condition based on the WMOCode + * table can be found here : https://open-meteo.com/en/docs (at the end) + * @param WMOCode id code + * @return weather condition + */ private static Condition getConditionFromCode(int WMOCode) { - if (WMOCode < 20) - return Condition.SUNNY; - else if (WMOCode < 30) - return Condition.RAINY; - else if (WMOCode < 50) - return Condition.CLOUDY; - else - return Condition.RAINY; + return switch (WMOCode) { + case 0, 1 -> Condition.SUNNY; + case 2 -> Condition.PARTIAL; + case 3 -> Condition.CLOUDY; + case 61, 63, 65, 80, 81, 82 -> Condition.RAINY; + default -> Condition.ERROR; + }; } @@ -53,32 +85,32 @@ public class OpenMeteo extends WeatherCachedAPI { float windDirection = daily.getJSONArray("wind_direction_10m_dominant").getFloat(day); int conditionCode = daily.getJSONArray("weather_code").getInt(day); - return new WeatherData( - new City(cityName), - Instant.now(), - temp_c, - windSpeed, - windDirection, - getConditionFromCode(conditionCode) - ); + return new WeatherData( + new City(cityName), + Instant.now(), + temp_c, + windSpeed, + windDirection, + getConditionFromCode(conditionCode) + ); } /** * @param day Day, 0 ≤ day ≤ 14 */ @Override - public WeatherData getTemperature(int day, String cityName) throws IOException { + public WeatherData getTemperature(int day, String cityName) throws WeatherFetchingException { JSONObject result = fetchWeather(day + 1, new City(cityName)); return getWeatherDataFromForecast(result, day, cityName); } @Override - public WeatherData getTemperature(int day, int hour, String cityName) throws IOException{ + public WeatherData getTemperature(int day, int hour, String cityName) throws WeatherFetchingException { return getTemperature(day, cityName); } - public ArrayList fetchTemperatures(int days, String cityName) throws IOException { + public ArrayList fetchTemperatures(int days, String cityName) throws WeatherFetchingException { JSONObject result = fetchWeather(days, new City(cityName)); ArrayList weatherDatas = new ArrayList<>(); @@ -95,4 +127,9 @@ public class OpenMeteo extends WeatherCachedAPI { public String getAPIName() { return "OpenMeteo"; } + + @Override + public String toString() { + return this.getAPIName(); + } } diff --git a/src/main/java/eirb/pg203/OpenWeatherMap.java b/src/main/java/eirb/pg203/weather/data/api/OpenWeatherMap.java similarity index 61% rename from src/main/java/eirb/pg203/OpenWeatherMap.java rename to src/main/java/eirb/pg203/weather/data/api/OpenWeatherMap.java index f6faa95..f99314b 100644 --- a/src/main/java/eirb/pg203/OpenWeatherMap.java +++ b/src/main/java/eirb/pg203/weather/data/api/OpenWeatherMap.java @@ -1,46 +1,65 @@ -package eirb.pg203; +package eirb.pg203.weather.data.api; +import eirb.pg203.weather.utils.City; +import eirb.pg203.weather.exceptions.WeatherFetchingException; +import eirb.pg203.weather.exceptions.WeatherFetchingExceptionApi; +import eirb.pg203.weather.exceptions.WeatherFetchingExceptionCityCoords; +import eirb.pg203.weather.data.WeatherData; import org.json.JSONObject; import org.json.JSONArray; -import eirb.pg203.utils.JSONFetcher; +import eirb.pg203.weather.utils.JSONFetcher; import java.io.IOException; import java.net.URI; import java.net.URL; +import java.time.Clock; import java.time.DayOfWeek; import java.time.Instant; import java.time.ZoneId; import java.util.ArrayList; -import eirb.pg203.WeatherData.Condition; +import java.util.Locale; -// https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41&hourly=temperature_2m +import eirb.pg203.weather.data.WeatherData.Condition; +/** + * OpenWeatherMap api implementation + */ public class OpenWeatherMap extends WeatherCachedAPI { private static final String forecastBaseURL = "https://api.openweathermap.org/data/2.5/forecast"; private String APIKey; + private static Clock clock = Clock.systemUTC(); + JSONFetcher JSONFetcher = new JSONFetcher(); - OpenWeatherMap(String APIKey) { + public OpenWeatherMap(String APIKey) { this.APIKey = APIKey; } - private JSONObject fetchWeather(int days, City city) throws IOException { - URL url = URI.create( - String.format(forecastBaseURL + "?appid=%s&lat=%.2f&lon=%.2f&units=metric", - APIKey, - city.getCityCoords().getLat(), - city.getCityCoords().getLon(), - days - ) - ).toURL(); + private JSONObject fetchWeather(int day, City city) throws WeatherFetchingException { + URL url = null; + try { + url = URI.create( + String.format(Locale.ENGLISH, forecastBaseURL + "?appid=%s&lat=%.2f&lon=%.2f&units=metric", + APIKey, + city.getCityCoords().getLat(), + city.getCityCoords().getLon() + ) + ).toURL(); + } catch (IOException e) { + throw new WeatherFetchingExceptionCityCoords(); + } - return JSONFetcher.fetch(url); + try { + return JSONFetcher.fetch(url); + } catch (IOException e) { + throw new WeatherFetchingExceptionApi(); + } } private static WeatherData getWeatherDataFromForecast(JSONObject response, int day, String cityName) { JSONArray list = response.getJSONArray("list"); - DayOfWeek targetedDay = Instant.now().plusSeconds(day * 24 * 3600).atZone(ZoneId.systemDefault()).getDayOfWeek(); + DayOfWeek targetedDay = Instant.now(clock).plusSeconds(day * 24 * 3600).atZone(ZoneId.systemDefault()).getDayOfWeek(); DayOfWeek dayOfWeek; int dataCount = 0; float temp_c = 0; @@ -84,7 +103,7 @@ public class OpenWeatherMap extends WeatherCachedAPI { condition = Condition.PARTIAL; - return new WeatherData( + return new WeatherData( new City(cityName), Instant.now().plusSeconds(day * 24 * 3600), temp_c, @@ -98,18 +117,18 @@ public class OpenWeatherMap extends WeatherCachedAPI { * @param day Day, 0 ≤ day ≤ 14 */ @Override - public WeatherData getTemperature(int day, String cityName) throws IOException { + public WeatherData getTemperature(int day, String cityName) throws WeatherFetchingException { JSONObject result = fetchWeather(day+1, new City(cityName)); return getWeatherDataFromForecast(result, day, cityName); } @Override - public WeatherData getTemperature(int day, int hour, String cityname) throws IOException{ + public WeatherData getTemperature(int day, int hour, String cityname) throws WeatherFetchingException { return getTemperature(day, cityname); } - public ArrayList fetchTemperatures(int days, String cityName) throws IOException { + public ArrayList fetchTemperatures(int days, String cityName) throws WeatherFetchingException { JSONObject result = fetchWeather(days, new City(cityName)); ArrayList weatherDatas = new ArrayList<>(); @@ -126,4 +145,9 @@ public class OpenWeatherMap extends WeatherCachedAPI { public String getAPIName() { return "OpenWeatherMap"; } + + @Override + public String toString() { + return this.getAPIName(); + } } diff --git a/src/main/java/eirb/pg203/WeatherAPI.java b/src/main/java/eirb/pg203/weather/data/api/WeatherAPI.java similarity index 59% rename from src/main/java/eirb/pg203/WeatherAPI.java rename to src/main/java/eirb/pg203/weather/data/api/WeatherAPI.java index 0bd0ed9..de7cfaf 100644 --- a/src/main/java/eirb/pg203/WeatherAPI.java +++ b/src/main/java/eirb/pg203/weather/data/api/WeatherAPI.java @@ -1,41 +1,57 @@ -package eirb.pg203; +package eirb.pg203.weather.data.api; +import eirb.pg203.weather.utils.City; +import eirb.pg203.weather.exceptions.WeatherFetchingException; +import eirb.pg203.weather.exceptions.WeatherFetchingExceptionApi; +import eirb.pg203.weather.data.WeatherData; import org.json.JSONArray; import org.json.JSONObject; -import eirb.pg203.WeatherData.Condition; -import eirb.pg203.utils.JSONFetcher; +import eirb.pg203.weather.data.WeatherData.Condition; +import eirb.pg203.weather.utils.JSONFetcher; import java.io.IOException; +import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.time.Instant; import java.util.ArrayList; +import java.util.Locale; /** * WeatherAPI implementation */ public class WeatherAPI extends WeatherCachedAPI { private final String weatherAPIKey; - private static final String forecastBaseURL = "https://api.weatherapi.com/v1/forecast.json"; + JSONFetcher JSONFetcher = new JSONFetcher(); + private static final String forecastBaseURL = "https://api.weatherapi.com/v1/forecast.json"; - WeatherAPI(String weatherAPIKey) { + public WeatherAPI(String weatherAPIKey) { this.weatherAPIKey = weatherAPIKey; } - private JSONObject fetchWeather(int days, String city) throws IOException { - URL url = URI.create( - String.format(forecastBaseURL + "?key=%s&q=%s&days=%d", - this.weatherAPIKey, - city, - days - ) - ).toURL(); + private JSONObject fetchWeather(int days, String city) throws WeatherFetchingException { + URL url = null; + try { + url = URI.create( + String.format(Locale.ENGLISH, forecastBaseURL + "?key=%s&q=%s&days=%d", + this.weatherAPIKey, + city, + days + ) + ).toURL(); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } - return JSONFetcher.fetch(url); + try { + return JSONFetcher.fetch(url); + } catch (IOException e) { + throw new WeatherFetchingExceptionApi(); + } } - private static WeatherData.Condition getConditionFromString(String str) { + private static Condition getConditionFromString(String str) { if (str.toLowerCase().contains("rain")) return Condition.RAINY; @@ -66,31 +82,31 @@ public class WeatherAPI extends WeatherCachedAPI { String conditionStr = forecastDay.getJSONObject("day").getJSONObject("condition").getString("text"); - return new WeatherData( - new City(city), - Instant.now(), - temp_c, - windSpeed, - windDirection, - getConditionFromString(conditionStr) - ); + return new WeatherData( + new City(city), + Instant.now(), + temp_c, + windSpeed, + windDirection, + getConditionFromString(conditionStr) + ); } /** * @param day Day, 0 ≤ day ≤ 14 */ @Override - public WeatherData getTemperature(int day, String cityName) throws IOException { + public WeatherData getTemperature(int day, String cityName) throws WeatherFetchingException { JSONObject result = fetchWeather(day+1, cityName); return getWeatherDataFromForecast(result, day, cityName); } @Override - public WeatherData getTemperature(int day, int hour, String cityName) throws IOException{ + public WeatherData getTemperature(int day, int hour, String cityName) throws WeatherFetchingException { return getTemperature(day, cityName); } - public ArrayList fetchTemperatures(int days, String cityName) throws IOException { + public ArrayList fetchTemperatures(int days, String cityName) throws WeatherFetchingException { JSONObject result = fetchWeather(days, cityName); ArrayList weatherDatas = new ArrayList<>(); @@ -107,4 +123,9 @@ public class WeatherAPI extends WeatherCachedAPI { public String getAPIName() { return "WeatherAPI"; } + + @Override + public String toString() { + return this.getAPIName(); + } } diff --git a/src/main/java/eirb/pg203/WeatherCachedAPI.java b/src/main/java/eirb/pg203/weather/data/api/WeatherCachedAPI.java similarity index 79% rename from src/main/java/eirb/pg203/WeatherCachedAPI.java rename to src/main/java/eirb/pg203/weather/data/api/WeatherCachedAPI.java index ce85d79..9aec6d2 100644 --- a/src/main/java/eirb/pg203/WeatherCachedAPI.java +++ b/src/main/java/eirb/pg203/weather/data/api/WeatherCachedAPI.java @@ -1,4 +1,6 @@ -package eirb.pg203; +package eirb.pg203.weather.data.api; +import eirb.pg203.weather.data.WeatherData; +import eirb.pg203.weather.exceptions.WeatherFetchingException; import java.io.File; import java.io.FileNotFoundException; @@ -11,16 +13,17 @@ import java.util.Scanner; import org.json.JSONArray; -abstract class WeatherCachedAPI implements WeatherDataAPI { + +public abstract class WeatherCachedAPI implements WeatherDataAPI { private final WeatherDataCache cache = new WeatherDataCache(); - abstract ArrayList fetchTemperatures(int days, String cityName) throws IOException; + abstract ArrayList fetchTemperatures(int days, String cityName) throws WeatherFetchingException; public void loadCache(JSONArray data) { this.cache.fromJSON(data, this.getAPIName()); } - private void updateCache(int days, String cityName) throws IOException { + private void updateCache(int days, String cityName) throws WeatherFetchingException { ArrayList data = fetchTemperatures(days, cityName); Instant timestamp = Instant.now(); @@ -28,7 +31,7 @@ abstract class WeatherCachedAPI implements WeatherDataAPI { this.cache.set(cityName, i, data.get(i), timestamp); } - public ArrayList getTemperatures(int days, String cityName) throws IOException + public ArrayList getTemperatures(int days, String cityName) throws WeatherFetchingException { ArrayList result = new ArrayList<>(); @@ -36,7 +39,9 @@ abstract class WeatherCachedAPI implements WeatherDataAPI { { if (this.cache.needsUpdate(cityName, i)) { - updateCache(days, cityName); + try { + updateCache(days, cityName); + } catch(Exception e) {} } } diff --git a/src/main/java/eirb/pg203/weather/data/api/WeatherDataAPI.java b/src/main/java/eirb/pg203/weather/data/api/WeatherDataAPI.java new file mode 100644 index 0000000..7c922ec --- /dev/null +++ b/src/main/java/eirb/pg203/weather/data/api/WeatherDataAPI.java @@ -0,0 +1,46 @@ +package eirb.pg203.weather.data.api; + +import eirb.pg203.weather.exceptions.WeatherFetchingException; +import eirb.pg203.weather.data.WeatherData; + +import java.util.ArrayList; + +/** + * Interface to discuss with a weather API + */ +public interface WeatherDataAPI { + + /** + * Fetch the temperature for a specific day in a city + * @param day Since D+0 + * @param city Localisation + * @return Temperature of the day from the city + * @throws WeatherFetchingException when request failed + */ + WeatherData getTemperature(int day, String city) throws WeatherFetchingException; + + /** + * Get WeatherData for a specific day + * @param day Since D+0 + * @param hour Since H+0 + * @param city Localisation + * @return Temperature of the day for a hour from the city + * @throws WeatherFetchingException when request failed + */ + WeatherData getTemperature(int day, int hour, String city) throws WeatherFetchingException; + + /** + * Fetch the temperature for multiple day since today + * @param days number of days to fetch + * @param city name of te city + * @return List of WeatherData + * @throws WeatherFetchingException when request failed + */ + ArrayList getTemperatures(int days, String city) throws WeatherFetchingException; + + /*** + * Name of the API + * @return Name of the API + */ + String getAPIName(); +} diff --git a/src/main/java/eirb/pg203/WeatherDataCache.java b/src/main/java/eirb/pg203/weather/data/api/WeatherDataCache.java similarity index 97% rename from src/main/java/eirb/pg203/WeatherDataCache.java rename to src/main/java/eirb/pg203/weather/data/api/WeatherDataCache.java index 89d306c..23309c8 100644 --- a/src/main/java/eirb/pg203/WeatherDataCache.java +++ b/src/main/java/eirb/pg203/weather/data/api/WeatherDataCache.java @@ -1,4 +1,5 @@ -package eirb.pg203; +package eirb.pg203.weather.data.api; +import eirb.pg203.weather.data.WeatherData; import java.time.Instant; import java.util.ArrayList; @@ -8,6 +9,7 @@ import java.util.Locale; import org.json.JSONArray; import org.json.JSONObject; + public class WeatherDataCache { private static class CacheValue { private WeatherData value; diff --git a/src/main/java/eirb/pg203/WeatherDisplay.java b/src/main/java/eirb/pg203/weather/display/WeatherDisplay.java similarity index 84% rename from src/main/java/eirb/pg203/WeatherDisplay.java rename to src/main/java/eirb/pg203/weather/display/WeatherDisplay.java index d6adc3d..6aaf15c 100644 --- a/src/main/java/eirb/pg203/WeatherDisplay.java +++ b/src/main/java/eirb/pg203/weather/display/WeatherDisplay.java @@ -1,4 +1,6 @@ -package eirb.pg203; +package eirb.pg203.weather.display; + +import eirb.pg203.weather.data.api.WeatherDataAPI; /** * How to display weather information, make the API calls based on the collection of WheatherDataAPI diff --git a/src/main/java/eirb/pg203/WeatherDisplayBasic.java b/src/main/java/eirb/pg203/weather/display/WeatherDisplayBasic.java similarity index 52% rename from src/main/java/eirb/pg203/WeatherDisplayBasic.java rename to src/main/java/eirb/pg203/weather/display/WeatherDisplayBasic.java index 4ee2fca..8a7d807 100644 --- a/src/main/java/eirb/pg203/WeatherDisplayBasic.java +++ b/src/main/java/eirb/pg203/weather/display/WeatherDisplayBasic.java @@ -1,15 +1,25 @@ -package eirb.pg203; +package eirb.pg203.weather.display; + +import eirb.pg203.weather.exceptions.WeatherFetchingException; +import eirb.pg203.weather.data.WeatherData; +import eirb.pg203.weather.data.api.WeatherDataAPI; import java.util.ArrayList; import java.util.HashMap; -class WeatherDisplayBasic implements WeatherDisplay { - private ArrayList apis; - - WeatherDisplayBasic() { - this.apis = new ArrayList(); - } +public class WeatherDisplayBasic implements eirb.pg203.weather.display.WeatherDisplay { + /** + * List of apis + */ + private final ArrayList apis = new ArrayList<>(); + /** + * Display header + * Source J + 0 J + 1 J + 2 + * @param days number of columns + * @param sourceColumnSize size of the first column + * @param dayColumnSize day column size + */ private void displayHeader(int days, double sourceColumnSize, double dayColumnSize) { StringBuilder line = new StringBuilder(); line.append("Source\t"); @@ -26,6 +36,13 @@ class WeatherDisplayBasic implements WeatherDisplay { System.out.println(line); } + /** + * Calculate column size based on the WeatherData + * Check the size of the string of the weather data and return the max for the column + * WARNING : Special chars in the WeatherData string will introduce an offset + * @param weatherDataAPIArrayListHashMap list of Weather data for every WeatherDataApi + * @return day column size + */ private double getColumnSize(HashMap> weatherDataAPIArrayListHashMap) { double max = 0; for (WeatherDataAPI api: weatherDataAPIArrayListHashMap.keySet()) { @@ -39,6 +56,15 @@ class WeatherDisplayBasic implements WeatherDisplay { return max; } + /** + * Display a line of data with a column separator + * OpenWeatherMap | 14,49° ☁️ 07,71km/h 254,25° 🡨 | 11,29° ☁️ 04,33km/h 296,00° 🡬 | 12,06° ☁️ 07,53km/h 188,88° 🡫 | + * @param apiName Name of the api if the first column + * @param weatherDatas List of Weather data to display + * @param startColumnString Separator between column + * @param sourceColumnSize Size of the first column + * @param dayColumnSize Size for day columns + */ private void displayWeatherDatas(String apiName, ArrayList weatherDatas, String startColumnString, double sourceColumnSize, double dayColumnSize) { StringBuilder line = new StringBuilder(); String weatherDataString; @@ -61,6 +87,13 @@ class WeatherDisplayBasic implements WeatherDisplay { } + /** + * Display in stdout the line between apis + * -------------------------------+------------------------------+------------------------------+------------------------------+ + * @param days number of days to display + * @param sourceColumnSize size for the first column (where the name of the api is display) + * @param dayColumnSize column size for the days (where the temperature is displayed) + */ private void displaySeparatorLine(int days, double sourceColumnSize, double dayColumnSize) { String mainSeparator = "-"; String secondSeparator = "+"; @@ -77,6 +110,20 @@ class WeatherDisplayBasic implements WeatherDisplay { System.out.println(line); } + /** + * Display an array like this in stdout + * Source J + 0 J + 1 J + 2 + * -------------------------------+------------------------------+------------------------------+------------------------------+ + * OpenWeatherMap | 14,49° ☁️ 07,71km/h 254,25° 🡨 | 11,29° ☁️ 04,33km/h 296,00° 🡬 | 12,06° ☁️ 07,53km/h 188,88° 🡫 | + * -------------------------------+------------------------------+------------------------------+------------------------------+ + * WeatherAPI | 12,50° 🌧 20,31km/h 238,67° 🡯 | 11,20° 🌧 17,23km/h 291,92° 🡨 | 11,00° 🌧 25,59km/h 256,88° 🡨 | + * -------------------------------+------------------------------+------------------------------+------------------------------+ + * OpenMeteo | 10,70° 🌧 25,80km/h 243,00° 🡯 | 11,35° 🌧 24,30km/h 276,00° 🡨 | 11,00° 🌧 31,50km/h 238,00° 🡯 | + * -------------------------------+------------------------------+------------------------------+------------------------------+ + * + * @param weatherDataAPIArrayListHashMap Hashmap with WeatherData array for each api + * @param days number of days to display + */ private void displayAllWeatherDatas(HashMap> weatherDataAPIArrayListHashMap, int days) { double dayColumnSize = this.getColumnSize(weatherDataAPIArrayListHashMap); @@ -105,7 +152,10 @@ class WeatherDisplayBasic implements WeatherDisplay { for (WeatherDataAPI w: apis) { try { weatherDatasMap.put(w, w.getTemperatures(days, city)); - } catch (Exception e) { + } catch (WeatherFetchingException e) { + System.err.println(w.getAPIName() + " failed to fetch meteo"); + } + catch (Exception e) { System.err.println(e); } } diff --git a/src/main/java/eirb/pg203/weather/exceptions/WeatherFetchingException.java b/src/main/java/eirb/pg203/weather/exceptions/WeatherFetchingException.java new file mode 100644 index 0000000..bd6ff28 --- /dev/null +++ b/src/main/java/eirb/pg203/weather/exceptions/WeatherFetchingException.java @@ -0,0 +1,14 @@ +package eirb.pg203.weather.exceptions; + +/** + * Exception when an error during the api call + */ +public class WeatherFetchingException extends Exception { + /** + * Weather Fetching exception + * @param message message of the exception + */ + public WeatherFetchingException(String message) { + super(message); + } +} diff --git a/src/main/java/eirb/pg203/weather/exceptions/WeatherFetchingExceptionApi.java b/src/main/java/eirb/pg203/weather/exceptions/WeatherFetchingExceptionApi.java new file mode 100644 index 0000000..16bdf62 --- /dev/null +++ b/src/main/java/eirb/pg203/weather/exceptions/WeatherFetchingExceptionApi.java @@ -0,0 +1,7 @@ +package eirb.pg203.weather.exceptions; + +public class WeatherFetchingExceptionApi extends eirb.pg203.weather.exceptions.WeatherFetchingException { + public WeatherFetchingExceptionApi() { + super("An error occurred during API fetching"); + } +} diff --git a/src/main/java/eirb/pg203/weather/exceptions/WeatherFetchingExceptionCityCoords.java b/src/main/java/eirb/pg203/weather/exceptions/WeatherFetchingExceptionCityCoords.java new file mode 100644 index 0000000..0a71eda --- /dev/null +++ b/src/main/java/eirb/pg203/weather/exceptions/WeatherFetchingExceptionCityCoords.java @@ -0,0 +1,7 @@ +package eirb.pg203.weather.exceptions; + +public class WeatherFetchingExceptionCityCoords extends eirb.pg203.weather.exceptions.WeatherFetchingException { + public WeatherFetchingExceptionCityCoords() { + super("Impossible to get city coords"); + } +} diff --git a/src/main/java/eirb/pg203/Cache.java b/src/main/java/eirb/pg203/weather/utils/Cache.java similarity index 100% rename from src/main/java/eirb/pg203/Cache.java rename to src/main/java/eirb/pg203/weather/utils/Cache.java diff --git a/src/main/java/eirb/pg203/City.java b/src/main/java/eirb/pg203/weather/utils/City.java similarity index 56% rename from src/main/java/eirb/pg203/City.java rename to src/main/java/eirb/pg203/weather/utils/City.java index af20548..7d76044 100644 --- a/src/main/java/eirb/pg203/City.java +++ b/src/main/java/eirb/pg203/weather/utils/City.java @@ -1,52 +1,51 @@ -package eirb.pg203; +package eirb.pg203.weather.utils; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; import java.net.URI; import java.net.URL; +import java.util.Locale; +import eirb.pg203.weather.utils.Coords; +import eirb.pg203.weather.utils.JSONFetcher; import org.json.JSONArray; +import org.json.JSONException; import org.json.JSONObject; -import eirb.pg203.utils.Coords; - -class City { +/** + * Representation of a city + * Possibility to get city coordinates based on the name + */ +public class City { private String cityName; private Coords cityCoords; + JSONFetcher JSONFetcher = new JSONFetcher(); /** * Fetch data from adresse.data.gouv.fr * @throws IOException if the request fails */ - private static JSONObject getDataFromName(String cityName) throws IOException { + private JSONObject getDataFromName(String cityName) throws IOException { StringBuilder result = new StringBuilder(); URL url = URI.create( - String.format("https://api-adresse.data.gouv.fr/search/?q=%s&autocomplete=0&limit=1", + String.format(Locale.ENGLISH, "https://api-adresse.data.gouv.fr/search/?q=%s&autocomplete=0&limit=1", cityName ) ).toURL(); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod("GET"); - - try (BufferedReader reader = new BufferedReader( - new InputStreamReader(conn.getInputStream()))) { - for (String line; (line = reader.readLine()) != null; ) { - result.append(line); - } - } - - return new JSONObject(result.toString()); + return JSONFetcher.fetch(url); } - private static Coords getCoordsFromName(String cityName) throws IOException { + private Coords getCoordsFromName(String cityName) throws IOException { JSONObject data = getDataFromName(cityName); - JSONArray rawCoords = data.getJSONArray("features") - .getJSONObject(0) - .getJSONObject("geometry") - .getJSONArray("coordinates"); + JSONArray rawCoords; + try { + rawCoords = data.getJSONArray("features") + .getJSONObject(0) + .getJSONObject("geometry") + .getJSONArray("coordinates"); + } catch (JSONException e) { + throw new IOException(); + } final float lon = rawCoords.getFloat(0); final float lat = rawCoords.getFloat(1); @@ -54,10 +53,14 @@ class City { return new Coords(lat, lon); } - City (String cityName) { + public City (String cityName) { this.cityName = cityName; } + /** + * Get city name + * @return city name string + */ public String getCityName() { return cityName; } @@ -80,7 +83,7 @@ class City { public String toString() { try { Coords coords = this.getCityCoords(); - return String.format( + return String.format(Locale.ENGLISH, "City(%s, lat: %f, lon: %f)", this.cityName, coords.getLat(), @@ -88,7 +91,7 @@ class City { ); } catch (IOException e) { - return String.format( + return String.format(Locale.ENGLISH, "City(%s, lat: Request failed, lon: Request Failed)", this.cityName ); diff --git a/src/main/java/eirb/pg203/weather/utils/Coords.java b/src/main/java/eirb/pg203/weather/utils/Coords.java new file mode 100644 index 0000000..c78effc --- /dev/null +++ b/src/main/java/eirb/pg203/weather/utils/Coords.java @@ -0,0 +1,51 @@ +package eirb.pg203.weather.utils; + +/** + * Coordinates representation + */ +public class Coords { + private float lat; + private float lon; + + /** + * Coordinates representation + * @param lat latitude + * @param lon longitude + */ + public Coords(float lat, float lon) { + this.lat = lat; + this.lon = lon; + } + + /** + * Get latitude + * @return latitude + */ + public float getLat() { + return lat; + } + + /** + * Get longitude + * @return longitude + */ + public float getLon() { + return lon; + } + + /** + * Set latitude + * @param lat latitude + */ + public void setLat(float lat) { + this.lat = lat; + } + + /** + * Set longitude + * @param lon longitude + */ + public void setLon(float lon) { + this.lon = lon; + } +} diff --git a/src/main/java/eirb/pg203/utils/JSONCachable.java b/src/main/java/eirb/pg203/weather/utils/JSONCachable.java similarity index 100% rename from src/main/java/eirb/pg203/utils/JSONCachable.java rename to src/main/java/eirb/pg203/weather/utils/JSONCachable.java diff --git a/src/main/java/eirb/pg203/utils/JSONFetcher.java b/src/main/java/eirb/pg203/weather/utils/JSONFetcher.java similarity index 63% rename from src/main/java/eirb/pg203/utils/JSONFetcher.java rename to src/main/java/eirb/pg203/weather/utils/JSONFetcher.java index b0a2c15..1d5fb97 100644 --- a/src/main/java/eirb/pg203/utils/JSONFetcher.java +++ b/src/main/java/eirb/pg203/weather/utils/JSONFetcher.java @@ -1,4 +1,4 @@ -package eirb.pg203.utils; +package eirb.pg203.weather.utils; import java.io.BufferedReader; import java.io.IOException; @@ -9,8 +9,21 @@ import java.net.URL; import org.json.JSONArray; import org.json.JSONObject; +/** + * Util for http calls + */ public class JSONFetcher { + /** + * No need for constructor + */ + public JSONFetcher() {}; + /** + * Make the request + * @param url url to fetch + * @return String of the response + * @throws IOException if the request failed + */ private static String fetchString(URL url) throws IOException{ System.err.println("Requesting " + url); StringBuilder result = new StringBuilder(); @@ -22,20 +35,19 @@ public class JSONFetcher { result.append(line); } } - System.out.println(url); return result.toString(); } - - public static JSONObject fetch(URL url) throws IOException { + + /** + * Fetch an url + * @param url url + * @return Json object of the response + * @throws IOException if the request failed + */ + public JSONObject fetch(URL url) throws IOException { String result = fetchString(url); return new JSONObject(result); } - - public static JSONArray fetchArray(URL url) throws IOException { - String result = fetchString(url); - - return new JSONArray(result); - } } diff --git a/src/test/java/eirb/pg203/SampleTest.java b/src/test/java/eirb/pg203/SampleTest.java deleted file mode 100644 index ea913e4..0000000 --- a/src/test/java/eirb/pg203/SampleTest.java +++ /dev/null @@ -1,11 +0,0 @@ -package eirb.pg203; - -import org.json.JSONObject; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.io.IOException; - -public class SampleTest { - -} diff --git a/src/test/java/eirb/pg203/WeatherAPITest.java b/src/test/java/eirb/pg203/WeatherAPITest.java deleted file mode 100644 index af23ba3..0000000 --- a/src/test/java/eirb/pg203/WeatherAPITest.java +++ /dev/null @@ -1,71 +0,0 @@ -package eirb.pg203; - -import org.json.JSONObject; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.io.IOException; - -public class WeatherAPITest { - private static String APIKey = "cef8e1b6ea364994b5072423240111"; - - @Test - public void testRightAPIKey() { - WeatherAPI weatherAPI = new WeatherAPI(WeatherAPITest.APIKey); - int day = 0; - // int hour = 10; - int days = 7; - String city = "Bordeaux"; - - Assertions.assertAll( - () -> weatherAPI.getTemperature(day, city), - // () -> weatherAPI.getTemperature(day, hour, city), - () -> weatherAPI.getTemperatures(days, city) - ); - } - - @Test - public void testWrongAPIKey() { - WeatherAPI weatherAPI = new WeatherAPI(""); - int day = 0; - // int hour = 10; - int days = 7; - String city = "Bordeaux"; - - Assertions.assertThrows(IOException.class, () -> weatherAPI.getTemperature(day, city)); - Assertions.assertThrows(IOException.class, () -> weatherAPI.getTemperatures(days, city)); - } - - @Test - public void testWrongDay() { - WeatherAPI weatherAPI = new WeatherAPI(WeatherAPITest.APIKey); - String city = "Bordeaux"; - - Assertions.assertThrows(IOException.class, () -> weatherAPI.getTemperature(-1, city)); - Assertions.assertThrows(IOException.class, () -> weatherAPI.getTemperature(15, city)); - Assertions.assertThrows(IOException.class, () -> weatherAPI.getTemperatures(15, city)); - Assertions.assertThrows(IOException.class, () -> weatherAPI.getTemperatures(-1, city)); - } - - @Test - public void testRightDay() { - WeatherAPI weatherAPI = new WeatherAPI(WeatherAPITest.APIKey); - String city = "Bordeaux"; - - Assertions.assertAll( - () -> weatherAPI.getTemperature(0, city), - () -> weatherAPI.getTemperature(5, city), - () -> weatherAPI.getTemperature(14, city), - () -> weatherAPI.getTemperatures(0, city), - () -> weatherAPI.getTemperatures(8, city), - () -> weatherAPI.getTemperatures(14, city) - ); - } - - @Test - public void testGetAPIName() { - WeatherAPI weatherAPI = new WeatherAPI(WeatherAPITest.APIKey); - Assertions.assertTrue(weatherAPI.getAPIName().equals("WeatherAPI")); - } - -} diff --git a/src/test/java/eirb/pg203/weather/WeatherDisplayBasicTest.java b/src/test/java/eirb/pg203/weather/WeatherDisplayBasicTest.java new file mode 100644 index 0000000..69c2ea2 --- /dev/null +++ b/src/test/java/eirb/pg203/weather/WeatherDisplayBasicTest.java @@ -0,0 +1,84 @@ +package eirb.pg203.weather; + +import eirb.pg203.weather.display.WeatherDisplayBasic; +import eirb.pg203.weather.data.api.OpenMeteo; +import eirb.pg203.weather.data.api.OpenWeatherMap; +import eirb.pg203.weather.data.api.WeatherAPI; +import org.junit.jupiter.api.*; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.stream.Stream; + +import static eirb.pg203.weather.data.api.WeatherDataAPITest.*; + +public class WeatherDisplayBasicTest { + private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + private final ByteArrayOutputStream errContent = new ByteArrayOutputStream(); + private final PrintStream originalOut = System.out; + private final PrintStream originalErr = System.err; + + @BeforeEach + public void setUpStreams() { + System.setOut(new PrintStream(outContent)); + System.setErr(new PrintStream(errContent)); + } + + @AfterEach + public void restoreStreams() { + System.setOut(originalOut); + System.setErr(originalErr); + } + + private WeatherDisplayBasic weatherDisplayBasic; + + private WeatherDisplayBasic setWeatherDisplayBasic() { + /* Fake apis */ + OpenMeteo openMeteo = openMeteo(); + OpenWeatherMap openWeatherMap = openWeatherMap(); + WeatherAPI weatherAPI = weatherAPI(); + + WeatherDisplayBasic weatherDisplay = new WeatherDisplayBasic(); + weatherDisplay.addAPI(openMeteo); + weatherDisplay.addAPI(openWeatherMap); + weatherDisplay.addAPI(weatherAPI); + + return weatherDisplay; + } + + private static Stream display() { + return Stream.of( + Arguments.arguments(1, new StringBuilder() + .append("Source J + 0 \n") + .append("------------------------------+-----------------------------+\n") + .append("OpenMeteo | 07.60° 🌤 17.60km/h 151.00° 🡮| \n") + .append("------------------------------+-----------------------------+\n") + .append("WeatherAPI | 08.10° 🌤 17.45km/h 142.08° 🡮| \n") + .append("------------------------------+-----------------------------+\n") + .append("OpenWeatherMap | 13.41° 🌤 05.74km/h 142.13° 🡮| \n") + .append("------------------------------+-----------------------------+\n") + .toString() + ) + ); + + } + + @ParameterizedTest + @MethodSource + void display(int days, String expectedDisplay) { + String city = "Bordeaux"; + WeatherDisplayBasic weatherDisplayBasic = setWeatherDisplayBasic(); + weatherDisplayBasic.display(days, city); + + Assertions.assertEquals(expectedDisplay, outContent.toString()); + + } + + @Test + void addAPI() { + + } +} diff --git a/src/test/java/eirb/pg203/weather/data/WeatherDataTest.java b/src/test/java/eirb/pg203/weather/data/WeatherDataTest.java new file mode 100644 index 0000000..bbf7a5c --- /dev/null +++ b/src/test/java/eirb/pg203/weather/data/WeatherDataTest.java @@ -0,0 +1,109 @@ +package eirb.pg203.weather.data; + +import eirb.pg203.weather.utils.City; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; + +import java.time.Instant; +import java.util.stream.Stream; + +public class WeatherDataTest { + private static final float epsilon = 0.01F; + private WeatherData weatherData; + + @BeforeEach + public void setWeatherData() { + this.weatherData = new WeatherData(new City("f"), Instant.now(), 0f, 0, 0, WeatherData.Condition.SUNNY); + } + + @Test + void city() { + String cityName = "Paris"; + City city = new City(cityName); + this.weatherData.setCity(city); + + /* check if the setter works */ + Assertions.assertEquals(weatherData.getCity(), city); + } + + @Test + void temp() { + float temp = 69.69f; + this.weatherData.setTemp(temp); + + /* check if the setter works */ + Assertions.assertEquals(temp, weatherData.getTemp(), epsilon); + } + + @ParameterizedTest(name = "Set {0}") + @EnumSource + void condition(WeatherData.Condition condition) { + this.weatherData.setCondition(condition); + + /* check if the setter works */ + Assertions.assertEquals(condition, weatherData.getCondition()); + } + + @Test + void windSpeed() { + float windSpeed = 69.69f; + this.weatherData.setWindSpeed(windSpeed); + + /* check if the setter works */ + Assertions.assertEquals(windSpeed, weatherData.getWindSpeed()); + } + + @Test + void windAngle() { + float windAngle = 69.69f; + this.weatherData.setWindDirectionAngle(windAngle); + + /* check if the setter works */ + Assertions.assertEquals(windAngle, weatherData.getWindDirectionAngle()); + } + + @Test + void date() { + Instant instant = Instant.now(); + + this.weatherData.setDate(instant); + + /* check if the setter works */ + Assertions.assertEquals(instant, weatherData.getDate()); + + } + + @Test + void stringRepresentation() { + this.weatherData = new WeatherData(new City("f"), Instant.now(), 0f, 0, 0, WeatherData.Condition.SUNNY); + + Assertions.assertEquals("00.00° ☀️ 00.00km/h 000.00° 🡩", weatherData.toString()); + } + + private static Stream windDirectionRepresentation() { + return Stream.of( + Arguments.arguments(0f, WeatherData.WindDirection.N), + Arguments.arguments(45f, WeatherData.WindDirection.NE), + Arguments.arguments(90f, WeatherData.WindDirection.E), + Arguments.arguments(135f, WeatherData.WindDirection.SE), + Arguments.arguments(180f, WeatherData.WindDirection.S), + Arguments.arguments(225f, WeatherData.WindDirection.SW), + Arguments.arguments(270f, WeatherData.WindDirection.W), + Arguments.arguments(315f, WeatherData.WindDirection.NW), + Arguments.arguments(999f, WeatherData.WindDirection.ERROR) + ); + + } + + @ParameterizedTest + @MethodSource + void windDirectionRepresentation(float windDirection, WeatherData.WindDirection expectedWindDirection){ + weatherData.setWindDirectionAngle(windDirection); + Assertions.assertEquals(expectedWindDirection, weatherData.getWindDirection()); + } +} diff --git a/src/test/java/eirb/pg203/weather/data/api/WeatherAPITest.java b/src/test/java/eirb/pg203/weather/data/api/WeatherAPITest.java new file mode 100644 index 0000000..3ecaeb0 --- /dev/null +++ b/src/test/java/eirb/pg203/weather/data/api/WeatherAPITest.java @@ -0,0 +1,23 @@ +package eirb.pg203.weather.data.api; + +import eirb.pg203.weather.fakeJSONFetcher.FakeJSONFetcherWeatherAPI; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class WeatherAPITest { + private static final String APIKey = "realKey"; + private WeatherAPI weatherAPI; + + @BeforeEach + public void setupWeatherApi() { + this.weatherAPI = new WeatherAPI(WeatherAPITest.APIKey); + this.weatherAPI.JSONFetcher = new FakeJSONFetcherWeatherAPI(); + } + + @Test + public void testGetAPIName() { + Assertions.assertEquals("WeatherAPI", weatherAPI.getAPIName()); + } + +} diff --git a/src/test/java/eirb/pg203/weather/data/api/WeatherDataAPITest.java b/src/test/java/eirb/pg203/weather/data/api/WeatherDataAPITest.java new file mode 100644 index 0000000..3c53967 --- /dev/null +++ b/src/test/java/eirb/pg203/weather/data/api/WeatherDataAPITest.java @@ -0,0 +1,213 @@ +package eirb.pg203.weather.data.api; + +import eirb.pg203.weather.exceptions.WeatherFetchingExceptionApi; +import eirb.pg203.weather.exceptions.WeatherFetchingExceptionCityCoords; +import eirb.pg203.weather.fakeJSONFetcher.FakeJSONFetcherOpenMeteo; +import eirb.pg203.weather.fakeJSONFetcher.FakeJSONFetcherOpenWeatherMap; +import eirb.pg203.weather.fakeJSONFetcher.FakeJSONFetcherWeatherAPI; +import eirb.pg203.weather.exceptions.WeatherFetchingException; +import eirb.pg203.weather.data.WeatherData; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.stream.Stream; + +public class WeatherDataAPITest { + private static final float epsilon = 0.01F; + private static final String APIKey = "realKey"; + private static final String wrongAPIKey = "wrongKey"; + + private static WeatherAPI wrongWeatherAPI() { + WeatherAPI weatherAPI = new WeatherAPI(wrongAPIKey); + weatherAPI.JSONFetcher = new FakeJSONFetcherWeatherAPI(); + return weatherAPI; + } + private static OpenWeatherMap wrongOpenWeatherMap() { + OpenWeatherMap weatherAPI = new OpenWeatherMap(wrongAPIKey); + weatherAPI.JSONFetcher = new FakeJSONFetcherOpenWeatherMap(); + return weatherAPI; + } + + public static WeatherAPI weatherAPI(){ + WeatherAPI weatherAPI = new WeatherAPI(APIKey); + weatherAPI.JSONFetcher = new FakeJSONFetcherWeatherAPI(); + return weatherAPI; + } + + public static OpenWeatherMap openWeatherMap(){ + // Fix clock for testing + String instantExpected = "2024-11-24T00:00:00.00Z"; + Clock clock = Clock.fixed(Instant.parse(instantExpected), ZoneId.systemDefault()); + + OpenWeatherMap openWeatherMap= new OpenWeatherMap(APIKey); + openWeatherMap.JSONFetcher = new FakeJSONFetcherOpenWeatherMap(); + openWeatherMap.clock = clock; + return openWeatherMap; + } + + public static OpenMeteo openMeteo() { + // Fix clock for testing + String instantExpected = "2024-11-24T00:00:00.00Z"; + Clock clock = Clock.fixed(Instant.parse(instantExpected), ZoneId.systemDefault()); + + OpenMeteo openMeteo = new OpenMeteo(); + openMeteo.clock = clock; + openMeteo.JSONFetcher = new FakeJSONFetcherOpenMeteo(); + return openMeteo; + } + + + /** + * List of args for Temperature testing + * @return Args for testing + */ + private static Stream testGetTemperature(){ + + return Stream.of( + /* WeatherAPI */ + Arguments.arguments(weatherAPI(), 0, 8.1F, WeatherData.Condition.PARTIAL, 17.45F, 142.08F), + Arguments.arguments(weatherAPI(), 1, 13F, WeatherData.Condition.SUNNY, 23.03F, 142.58F), + Arguments.arguments(weatherAPI(), 2, 12.7F, WeatherData.Condition.RAINY, 13.19F, 222.92F), + Arguments.arguments(weatherAPI(), 3, 8.1F,WeatherData.Condition.CLOUDY, 17.45F, 142.08F), + /* Open Weather Map */ + Arguments.arguments(openWeatherMap(), 0, 13.41F,WeatherData.Condition.PARTIAL, 5.74F, 142.13F), + Arguments.arguments(openWeatherMap(), 1, 13.29F,WeatherData.Condition.CLOUDY, 3.62F, 225.25F), + Arguments.arguments(openWeatherMap(), 2, 10.06F,WeatherData.Condition.RAINY, 2.22F, 191.75F), + Arguments.arguments(openWeatherMap(), 3, 9.88F,WeatherData.Condition.SUNNY, 2.00F, 160.00F), + /* Open Meteo */ + Arguments.arguments(openMeteo(), 0, 7.6F,WeatherData.Condition.PARTIAL, 17.6F, 151F), + Arguments.arguments(openMeteo(), 1, 13.20F,WeatherData.Condition.CLOUDY, 20.6F, 149F), + Arguments.arguments(openMeteo(), 2, 12.3F,WeatherData.Condition.RAINY, 21.70F, 187F), + Arguments.arguments(openMeteo(), 3, 10.80F,WeatherData.Condition.SUNNY, 9.4F, 177F) + ); + } + + @ParameterizedTest(name="[{0}] Temperature fetch at Bordeaux D+{1}") + @MethodSource + public void testGetTemperature(WeatherDataAPI weatherDataAPI, int day, float expectedTemp, WeatherData.Condition expectedCond, float expectedWindSpeed, float expectedWindAngle) throws WeatherFetchingException { + String city = "Bordeaux"; + WeatherData weatherData; + weatherData = weatherDataAPI.getTemperature(day, city); + + /* Temperatures */ + Assertions.assertEquals(expectedTemp, weatherData.getTemp(), epsilon); + /* Condition */ + Assertions.assertEquals(expectedCond, weatherData.getCondition()); + /* Wind */ + Assertions.assertEquals(expectedWindSpeed, weatherData.getWindSpeed(), epsilon); + Assertions.assertEquals(expectedWindAngle, weatherData.getWindDirectionAngle(),epsilon); + } + + private static Stream testGetTemperatures() { + float[] weatherAPIExpectedTemperatures = {8.1F, 13F, 12.7F, 8.1F}; + WeatherData.Condition[] weatherAPIExpectedConditions = {WeatherData.Condition.PARTIAL, WeatherData.Condition.SUNNY, WeatherData.Condition.RAINY, WeatherData.Condition.CLOUDY}; + float[] weatherAPIExpectedWindSpeed = {17.45F, 23.03F, 13.19F, 17.45F}; + float[] weatherAPIExpectedWindDirection = {142.08F, 142.58F, 222.92F, 142.08F}; + + float[] openWeatherMapExpectedTemperatures = {13.41F, 13.29F, 10.06F, 9.88F}; + WeatherData.Condition[] openWeatherMapExpectedConditions = {WeatherData.Condition.PARTIAL, WeatherData.Condition.CLOUDY, WeatherData.Condition.RAINY, WeatherData.Condition.SUNNY}; + float[] openWeatherMapExpectedWindSpeed = {5.74F, 3.62F, 2.22F, 2.00F}; + float[] openWeatherMapExpectedWindDirection = {142.13F, 225.25F, 191.75F, 160F}; + + float[] openMeteoExpectedTemperatures = {7.6F, 13.2F, 12.3F, 10.80F}; + WeatherData.Condition[] openMeteoExpectedConditions = {WeatherData.Condition.PARTIAL, WeatherData.Condition.CLOUDY, WeatherData.Condition.RAINY, WeatherData.Condition.SUNNY}; + float[] openMeteoExpectedWindSpeed = {17.6F, 20.6F, 21.7F, 9.40F}; + float[] openMeteoExpectedWindDirection = {151.00F, 149F, 187F, 177F}; + + return Stream.of( + Arguments.arguments(weatherAPI(), 4, weatherAPIExpectedTemperatures, weatherAPIExpectedConditions, weatherAPIExpectedWindSpeed, weatherAPIExpectedWindDirection), + Arguments.arguments(openWeatherMap(), 4, openWeatherMapExpectedTemperatures, openWeatherMapExpectedConditions, openWeatherMapExpectedWindSpeed, openWeatherMapExpectedWindDirection), + Arguments.arguments(openMeteo(), 4, openMeteoExpectedTemperatures, openMeteoExpectedConditions, openMeteoExpectedWindSpeed, openMeteoExpectedWindDirection) + ); + + } + @ParameterizedTest(name = "[{0}] Fetch temperatures for {1} days") + @MethodSource + public void testGetTemperatures(WeatherDataAPI weatherDataAPI, int days, float[] expectedTemperatures, WeatherData.Condition[] expectedConditions, float[] expectedWindSpeed, float[] expectedWindDirection) throws WeatherFetchingException{ + String city = "Bordeaux"; + + ArrayList weatherDatas; + WeatherData weatherData; + weatherDatas = weatherDataAPI.getTemperatures(days, city); + + for (int index = 0; index < days; index++) { + weatherData = weatherDatas.get(index); + + /* Temperatures */ + Assertions.assertEquals(expectedTemperatures[index], weatherData.getTemp(), epsilon); + /* Weather condition */ + Assertions.assertEquals(expectedConditions[index], weatherData.getCondition()); + /* Wind */ + Assertions.assertEquals(expectedWindSpeed[index],weatherData.getWindSpeed(), epsilon); + Assertions.assertEquals(expectedWindDirection[index], weatherData.getWindDirectionAngle(), epsilon); + } + } + + private static Stream testGetTemperatureByHours() { + + return Stream.of( + Arguments.arguments(weatherAPI()), + Arguments.arguments(openWeatherMap()), + Arguments.arguments(openMeteo()) + ); + } + + /** + * For coverage, not yet implemented + * @param weatherDataAPI api to test + */ + @ParameterizedTest(name = "[{0}] Get temperature for a specific hour") + @MethodSource + public void testGetTemperatureByHours(WeatherDataAPI weatherDataAPI) { + String city = "Bordeaux"; + Assertions.assertAll( + () -> weatherDataAPI.getTemperature(0,1, city) + ); + } + + private static Stream testUnkowncity() { + return Stream.of( + Arguments.arguments(openWeatherMap()), + Arguments.arguments(openMeteo()) + ); + } + + @ParameterizedTest(name = "[{0}] Get temperature from missing city") + @MethodSource + public void testUnkowncity(WeatherDataAPI weatherDataAPI) { + String unknownCity = "jlkfreajflkj"; + Assertions.assertThrows(WeatherFetchingExceptionCityCoords.class, + () -> weatherDataAPI.getTemperature(3, unknownCity) + ); + Assertions.assertThrows(WeatherFetchingExceptionCityCoords.class, + () -> weatherDataAPI.getTemperatures(3, unknownCity) + ); + } + + private static Stream testWrongApiKey() { + return Stream.of( + Arguments.arguments(wrongWeatherAPI()), + Arguments.arguments(wrongOpenWeatherMap()) + ); + } + + @ParameterizedTest(name = "[{0}] Wrong API Key throws exception") + @MethodSource + public void testWrongApiKey(WeatherDataAPI weatherDataAPI) { + String city = "Bordeaux"; + Assertions.assertThrows(WeatherFetchingExceptionApi.class, + () -> weatherDataAPI.getTemperatures(3, city) + ); + + Assertions.assertThrows(WeatherFetchingExceptionApi.class, + () -> weatherDataAPI.getTemperature(3, city) + ); + + } +} diff --git a/src/test/java/eirb/pg203/weather/fakeJSONFetcher/FakeJSONFetcherCity.java b/src/test/java/eirb/pg203/weather/fakeJSONFetcher/FakeJSONFetcherCity.java new file mode 100644 index 0000000..80d00b4 --- /dev/null +++ b/src/test/java/eirb/pg203/weather/fakeJSONFetcher/FakeJSONFetcherCity.java @@ -0,0 +1,34 @@ +package eirb.pg203.weather.fakeJSONFetcher; + +import eirb.pg203.weather.utils.FileResourcesUtils; +import eirb.pg203.weather.utils.SplitQueryUrl; +import eirb.pg203.weather.utils.JSONFetcher; +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.IOException; +import java.net.URL; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +public class FakeJSONFetcherCity extends JSONFetcher{ + JSONObject unknownCity = FileResourcesUtils.getFileFromResourceAsJson("City/fakeCity.json"); + + private static HashMap cities(){ + HashMap cities = new HashMap<>(); + cities.put("bordeaux", eirb.pg203.weather.utils.FileResourcesUtils.getFileFromResourceAsJson("City/bordeaux.json")); + cities.put("paris", eirb.pg203.weather.utils.FileResourcesUtils.getFileFromResourceAsJson("City/paris.json")); + cities.put("unknown", eirb.pg203.weather.utils.FileResourcesUtils.getFileFromResourceAsJson("City/fakeCity.json")); + return cities; + } + + + @Override + public JSONObject fetch(URL url) throws IOException { + Map params = SplitQueryUrl.splitQuery(url); + + String city = params.get("q").toLowerCase(Locale.ENGLISH); + return cities().getOrDefault(city, unknownCity); + } +} \ No newline at end of file diff --git a/src/test/java/eirb/pg203/weather/fakeJSONFetcher/FakeJSONFetcherOpenMeteo.java b/src/test/java/eirb/pg203/weather/fakeJSONFetcher/FakeJSONFetcherOpenMeteo.java new file mode 100644 index 0000000..0a3ae20 --- /dev/null +++ b/src/test/java/eirb/pg203/weather/fakeJSONFetcher/FakeJSONFetcherOpenMeteo.java @@ -0,0 +1,21 @@ +package eirb.pg203.weather.fakeJSONFetcher; + +import eirb.pg203.weather.utils.FileResourcesUtils; +import eirb.pg203.weather.utils.JSONFetcher; +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.IOException; +import java.net.URL; + +public class FakeJSONFetcherOpenMeteo extends JSONFetcher { + private JSONObject responseExample() { + return FileResourcesUtils.getFileFromResourceAsJson("OpenMeteo/Bordeaux-partial-cloudy-rain-sunny.json"); + } + + @Override + public JSONObject fetch(URL url) throws IOException { + return responseExample(); + } + +} diff --git a/src/test/java/eirb/pg203/weather/fakeJSONFetcher/FakeJSONFetcherOpenWeatherMap.java b/src/test/java/eirb/pg203/weather/fakeJSONFetcher/FakeJSONFetcherOpenWeatherMap.java new file mode 100644 index 0000000..bcf5336 --- /dev/null +++ b/src/test/java/eirb/pg203/weather/fakeJSONFetcher/FakeJSONFetcherOpenWeatherMap.java @@ -0,0 +1,27 @@ +package eirb.pg203.weather.fakeJSONFetcher; + +import eirb.pg203.weather.utils.FileResourcesUtils; +import eirb.pg203.weather.utils.SplitQueryUrl; +import eirb.pg203.weather.utils.JSONFetcher; +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.IOException; +import java.net.URL; +import java.util.Map; + +public class FakeJSONFetcherOpenWeatherMap extends JSONFetcher { + private final String apiKey = "realKey"; + private final JSONObject wrongKeyResponse = FileResourcesUtils.getFileFromResourceAsJson("OpenWeatherMap/wrong-apikey.json"); + + private JSONObject responseExample() { + return eirb.pg203.weather.utils.FileResourcesUtils.getFileFromResourceAsJson("OpenWeatherMap/Bordeaux-partial-cloudy-rain-sunny.json"); + } + @Override + public JSONObject fetch(URL url) throws IOException { + Map params = SplitQueryUrl.splitQuery(url); + if (!params.getOrDefault("appid", "").contentEquals(apiKey)) + throw new IOException(); + return responseExample(); + } +} diff --git a/src/test/java/eirb/pg203/weather/fakeJSONFetcher/FakeJSONFetcherWeatherAPI.java b/src/test/java/eirb/pg203/weather/fakeJSONFetcher/FakeJSONFetcherWeatherAPI.java new file mode 100644 index 0000000..887452e --- /dev/null +++ b/src/test/java/eirb/pg203/weather/fakeJSONFetcher/FakeJSONFetcherWeatherAPI.java @@ -0,0 +1,37 @@ +package eirb.pg203.weather.fakeJSONFetcher; + +import eirb.pg203.weather.utils.FileResourcesUtils; +import eirb.pg203.weather.utils.SplitQueryUrl; +import eirb.pg203.weather.utils.JSONFetcher; +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Map; + +public class FakeJSONFetcherWeatherAPI extends JSONFetcher { + private final static String baseUrlFormat = "https://api.weatherapi.com/v1/forecast.json?key=%s&q=%s&days=%d"; + private final String apiKey = "realKey"; + private static final JSONObject wrongKeyRequest = FileResourcesUtils.getFileFromResourceAsJson("WeatherAPI/wrong-apikey.json"); + private static ArrayList bordeauxRequests() { + ArrayList bordeauxRequest = new ArrayList<>(); + bordeauxRequest.add(eirb.pg203.weather.utils.FileResourcesUtils.getFileFromResourceAsJson("WeatherAPI/Bordeaux-1-partial.json")); + bordeauxRequest.add(eirb.pg203.weather.utils.FileResourcesUtils.getFileFromResourceAsJson("WeatherAPI/Bordeaux-2-partial-sunny.json")); + bordeauxRequest.add(eirb.pg203.weather.utils.FileResourcesUtils.getFileFromResourceAsJson("WeatherAPI/Bordeaux-3-partial-sunny-rain.json")); + bordeauxRequest.add(eirb.pg203.weather.utils.FileResourcesUtils.getFileFromResourceAsJson("WeatherAPI/Bordeaux-4-partial-sunny-rain-cloudy.json")); + return bordeauxRequest; + } + + @Override + public JSONObject fetch(URL url) throws IOException { + Map params = SplitQueryUrl.splitQuery(url); + int days = Integer.parseInt(params.get("days")); + + if (!params.get("key").contentEquals(apiKey)) + throw new IOException(); + + return bordeauxRequests().get(days - 1); + } +} diff --git a/src/test/java/eirb/pg203/weather/utils/CityTest.java b/src/test/java/eirb/pg203/weather/utils/CityTest.java new file mode 100644 index 0000000..a0833ff --- /dev/null +++ b/src/test/java/eirb/pg203/weather/utils/CityTest.java @@ -0,0 +1,50 @@ +package eirb.pg203.weather.utils; + +import eirb.pg203.weather.fakeJSONFetcher.FakeJSONFetcherCity; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import java.io.IOException; + +public class CityTest { + private final static float epsilon = 0.001F; + @ParameterizedTest(name = "{0} is located at [lat:{1}, lon:{2}]") + @CsvSource({ + "Paris,48.859F,2.347F,'City(Paris, lat: 48.859001, lon: 2.347000)'", + "Bordeaux,44.851895F,-0.587877F,'City(Bordeaux, lat: 44.851894, lon: -0.587877)'" + }) + void testRealCity(String cityName, float expectedLat, float expectedLon, String expectedString) throws IOException { + City city = new City(cityName); + city.JSONFetcher = new FakeJSONFetcherCity(); + + /* Name coherence */ + Assertions.assertEquals(cityName, city.getCityName()); + /* Localisation */ + Coords coords = city.getCityCoords(); + float lat = coords.getLat(); + float lon = coords.getLon(); + + Assertions.assertTrue(Math.abs(lat - expectedLat) < epsilon); + Assertions.assertTrue(Math.abs(lon - expectedLon) < epsilon); + + /* String representation */ + Assertions.assertEquals(expectedString, city.toString()); + } + + @Test + void testFakeCity(){ + String fakeCity = "farlmjmjfkl"; + String fakeCityRepresentation = "City("+ fakeCity +", lat: Request failed, lon: Request Failed)"; + City city = new City(fakeCity); + + /* String representation */ + Assertions.assertEquals(fakeCityRepresentation, city.toString()); + + /* Throw exception */ + Assertions.assertThrows(IOException.class, city::getCityCoords); + + } + +} diff --git a/src/test/java/eirb/pg203/weather/utils/CoordsTest.java b/src/test/java/eirb/pg203/weather/utils/CoordsTest.java new file mode 100644 index 0000000..c2a24e0 --- /dev/null +++ b/src/test/java/eirb/pg203/weather/utils/CoordsTest.java @@ -0,0 +1,53 @@ +package eirb.pg203.weather.utils; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class CoordsTest { + private static final float epsilon = 0.01F; + + @Test + void getLat() { + float lat = 1f; + float lon = 2f; + Coords coords = new Coords(lat, lon); + + assertEquals(lat, coords.getLat(), epsilon); + } + + @Test + void getLon() { + float lat = 1f; + float lon = 2f; + Coords coords = new Coords(lat, lon); + + assertEquals(lon, coords.getLon(), epsilon); + } + + @Test + void setLat() { + float lat = 1f; + float lon = 2f; + Coords coords = new Coords(lat, lon); + + float sndLat = 3f; + coords.setLat(sndLat); + + assertEquals(sndLat, coords.getLat(), epsilon); + + } + + @Test + void setLon() { + float lat = 1f; + float lon = 2f; + Coords coords = new Coords(lat, lon); + + float sndLon = 4f; + coords.setLon(sndLon); + + assertEquals(sndLon, coords.getLon(), epsilon); + + } +} \ No newline at end of file diff --git a/src/test/java/eirb/pg203/weather/utils/FileResourcesUtils.java b/src/test/java/eirb/pg203/weather/utils/FileResourcesUtils.java new file mode 100644 index 0000000..2e83ade --- /dev/null +++ b/src/test/java/eirb/pg203/weather/utils/FileResourcesUtils.java @@ -0,0 +1,53 @@ +package eirb.pg203.weather.utils; + +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +public class FileResourcesUtils { + /** + * Fetch ressource file + * Code from https://mkyong.com + * @param fileName + * @return + */ + public static InputStream getFileFromResourceAsStream(String fileName) { + + // The class loader that loaded the class + ClassLoader classLoader = FileResourcesUtils.class.getClassLoader(); + InputStream inputStream = classLoader.getResourceAsStream(fileName); + + // the stream holding the file content + if (inputStream == null) { + throw new IllegalArgumentException("file not found! " + fileName); + } else { + return inputStream; + } + + } + + public static JSONObject getFileFromResourceAsJson(String fileName) { + InputStream inputStream = getFileFromResourceAsStream(fileName); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + StringBuilder stringBuilder = new StringBuilder(); + String line; + while(true){ + try { + if (!bufferedReader.ready()) break; + } catch (IOException e) { + throw new RuntimeException(e); + } + try { + line = bufferedReader.readLine(); + } catch (IOException e) { + throw new RuntimeException(e); + } + stringBuilder.append(line); + } + + return new JSONObject(stringBuilder.toString()); + } +} diff --git a/src/test/java/eirb/pg203/weather/utils/SplitQueryUrl.java b/src/test/java/eirb/pg203/weather/utils/SplitQueryUrl.java new file mode 100644 index 0000000..881a9ab --- /dev/null +++ b/src/test/java/eirb/pg203/weather/utils/SplitQueryUrl.java @@ -0,0 +1,20 @@ +package eirb.pg203.weather.utils; + +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.net.URLDecoder; +import java.util.LinkedHashMap; +import java.util.Map; + +public class SplitQueryUrl { + public static Map splitQuery(URL url) throws UnsupportedEncodingException { + Map query_pairs = new LinkedHashMap(); + String query = url.getQuery(); + String[] pairs = query.split("&"); + for (String pair : pairs) { + int idx = pair.indexOf("="); + query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8")); + } + return query_pairs; + } +} diff --git a/src/test/resources/City/bordeaux.json b/src/test/resources/City/bordeaux.json new file mode 100644 index 0000000..76577c9 --- /dev/null +++ b/src/test/resources/City/bordeaux.json @@ -0,0 +1,37 @@ +{ + "type": "FeatureCollection", + "version": "draft", + "features": [ + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + -0.587877, + 44.851895 + ] + }, + "properties": { + "label": "Bordeaux", + "score": 0.9608036363636362, + "id": "33063", + "banId": "f38fe08f-c87b-4b3f-8f05-1566b8da9c39", + "type": "municipality", + "name": "Bordeaux", + "postcode": "33000", + "citycode": "33063", + "x": 416627.63, + "y": 6423408.37, + "population": 261804, + "city": "Bordeaux", + "context": "33, Gironde, Nouvelle-Aquitaine", + "importance": 0.56884, + "municipality": "Bordeaux" + } + } + ], + "attribution": "BAN", + "licence": "ETALAB-2.0", + "query": "Bordeaux", + "limit": 1 +} \ No newline at end of file diff --git a/src/test/resources/City/fakeCity.json b/src/test/resources/City/fakeCity.json new file mode 100644 index 0000000..21a422a --- /dev/null +++ b/src/test/resources/City/fakeCity.json @@ -0,0 +1,9 @@ +{ + "type": "FeatureCollection", + "version": "draft", + "features": [], + "attribution": "BAN", + "licence": "ETALAB-2.0", + "query": "farmjfakj", + "limit": 1 +} \ No newline at end of file diff --git a/src/test/resources/City/paris.json b/src/test/resources/City/paris.json new file mode 100644 index 0000000..d1e0e1f --- /dev/null +++ b/src/test/resources/City/paris.json @@ -0,0 +1,36 @@ +{ + "type": "FeatureCollection", + "version": "draft", + "features": [ + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 2.347, + 48.859 + ] + }, + "properties": { + "label": "Paris", + "score": 0.9703381818181818, + "id": "75056", + "type": "municipality", + "name": "Paris", + "postcode": "75001", + "citycode": "75056", + "x": 652089.7, + "y": 6862305.26, + "population": 2133111, + "city": "Paris", + "context": "75, Paris, Île-de-France", + "importance": 0.67372, + "municipality": "Paris" + } + } + ], + "attribution": "BAN", + "licence": "ETALAB-2.0", + "query": "Paris", + "limit": 1 +} \ No newline at end of file diff --git a/src/test/resources/OpenMeteo/Bordeaux-partial-cloudy-rain-sunny.json b/src/test/resources/OpenMeteo/Bordeaux-partial-cloudy-rain-sunny.json new file mode 100644 index 0000000..c30d533 --- /dev/null +++ b/src/test/resources/OpenMeteo/Bordeaux-partial-cloudy-rain-sunny.json @@ -0,0 +1,55 @@ +{ + "latitude": 44.84, + "longitude": -0.58000016, + "generationtime_ms": 0.1360177993774414, + "utc_offset_seconds": 0, + "timezone": "GMT", + "timezone_abbreviation": "GMT", + "elevation": 15, + "daily_units": { + "time": "iso8601", + "weather_code": "wmo code", + "temperature_2m_max": "°C", + "temperature_2m_min": "°C", + "wind_speed_10m_max": "km/h", + "wind_direction_10m_dominant": "°" + }, + "daily": { + "time": [ + "2024-11-23", + "2024-11-24", + "2024-11-25", + "2024-11-26" + ], + "weather_code": [ + 2, + 3, + 63, + 0 + ], + "temperature_2m_max": [ + 12.3, + 17.2, + 15.4, + 13.7 + ], + "temperature_2m_min": [ + 2.9, + 9.2, + 9.2, + 7.9 + ], + "wind_speed_10m_max": [ + 17.6, + 20.6, + 21.7, + 9.4 + ], + "wind_direction_10m_dominant": [ + 151, + 149, + 187, + 177 + ] + } +} \ No newline at end of file diff --git a/src/test/resources/OpenWeatherMap/Bordeaux-partial-cloudy-rain-sunny.json b/src/test/resources/OpenWeatherMap/Bordeaux-partial-cloudy-rain-sunny.json new file mode 100644 index 0000000..21735d5 --- /dev/null +++ b/src/test/resources/OpenWeatherMap/Bordeaux-partial-cloudy-rain-sunny.json @@ -0,0 +1,1475 @@ +{ + "cod": "200", + "message": 0, + "cnt": 40, + "list": [ + { + "dt": 1732406400, + "main": { + "temp": 10.2, + "feels_like": 9.23, + "temp_min": 10.18, + "temp_max": 10.2, + "pressure": 1017, + "sea_level": 1017, + "grnd_level": 1012, + "humidity": 75, + "temp_kf": 0.02 + }, + "weather": [ + { + "id": 802, + "main": "Clouds", + "description": "scattered clouds", + "icon": "03n" + } + ], + "clouds": { + "all": 33 + }, + "wind": { + "speed": 4.79, + "deg": 140, + "gust": 13.02 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-24 00:00:00" + }, + { + "dt": 1732417200, + "main": { + "temp": 10.26, + "feels_like": 9.22, + "temp_min": 10.26, + "temp_max": 10.29, + "pressure": 1016, + "sea_level": 1016, + "grnd_level": 1011, + "humidity": 72, + "temp_kf": -0.03 + }, + "weather": [ + { + "id": 803, + "main": "Clouds", + "description": "broken clouds", + "icon": "04n" + } + ], + "clouds": { + "all": 67 + }, + "wind": { + "speed": 5.15, + "deg": 135, + "gust": 13.89 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-24 03:00:00" + }, + { + "dt": 1732428000, + "main": { + "temp": 10.15, + "feels_like": 9.18, + "temp_min": 10.15, + "temp_max": 10.15, + "pressure": 1016, + "sea_level": 1016, + "grnd_level": 1011, + "humidity": 75, + "temp_kf": 0 + }, + "weather": [ + { + "id": 804, + "main": "Clouds", + "description": "overcast clouds", + "icon": "04n" + } + ], + "clouds": { + "all": 93 + }, + "wind": { + "speed": 5.71, + "deg": 138, + "gust": 14.58 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-24 06:00:00" + }, + { + "dt": 1732438800, + "main": { + "temp": 11.77, + "feels_like": 10.91, + "temp_min": 11.77, + "temp_max": 11.77, + "pressure": 1016, + "sea_level": 1016, + "grnd_level": 1011, + "humidity": 73, + "temp_kf": 0 + }, + "weather": [ + { + "id": 801, + "main": "Clouds", + "description": "few clouds", + "icon": "02d" + } + ], + "clouds": { + "all": 13 + }, + "wind": { + "speed": 5.93, + "deg": 134, + "gust": 14.45 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2024-11-24 09:00:00" + }, + { + "dt": 1732449600, + "main": { + "temp": 16.48, + "feels_like": 15.72, + "temp_min": 16.48, + "temp_max": 16.48, + "pressure": 1013, + "sea_level": 1013, + "grnd_level": 1009, + "humidity": 59, + "temp_kf": 0 + }, + "weather": [ + { + "id": 800, + "main": "Clear", + "description": "clear sky", + "icon": "01d" + } + ], + "clouds": { + "all": 10 + }, + "wind": { + "speed": 6.38, + "deg": 140, + "gust": 13.55 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2024-11-24 12:00:00" + }, + { + "dt": 1732460400, + "main": { + "temp": 17.25, + "feels_like": 16.55, + "temp_min": 17.25, + "temp_max": 17.25, + "pressure": 1011, + "sea_level": 1011, + "grnd_level": 1007, + "humidity": 58, + "temp_kf": 0 + }, + "weather": [ + { + "id": 803, + "main": "Clouds", + "description": "broken clouds", + "icon": "04d" + } + ], + "clouds": { + "all": 65 + }, + "wind": { + "speed": 6.31, + "deg": 146, + "gust": 15.59 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2024-11-24 15:00:00" + }, + { + "dt": 1732471200, + "main": { + "temp": 15.26, + "feels_like": 14.59, + "temp_min": 15.26, + "temp_max": 15.26, + "pressure": 1012, + "sea_level": 1012, + "grnd_level": 1007, + "humidity": 67, + "temp_kf": 0 + }, + "weather": [ + { + "id": 803, + "main": "Clouds", + "description": "broken clouds", + "icon": "04n" + } + ], + "clouds": { + "all": 84 + }, + "wind": { + "speed": 5.73, + "deg": 149, + "gust": 15.31 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-24 18:00:00" + }, + { + "dt": 1732482000, + "main": { + "temp": 15.9, + "feels_like": 15.14, + "temp_min": 15.9, + "temp_max": 15.9, + "pressure": 1011, + "sea_level": 1011, + "grnd_level": 1006, + "humidity": 61, + "temp_kf": 0 + }, + "weather": [ + { + "id": 804, + "main": "Clouds", + "description": "overcast clouds", + "icon": "04n" + } + ], + "clouds": { + "all": 100 + }, + "wind": { + "speed": 5.9, + "deg": 155, + "gust": 17.26 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-24 21:00:00" + }, + { + "dt": 1732492800, + "main": { + "temp": 16.01, + "feels_like": 15.13, + "temp_min": 16.01, + "temp_max": 16.01, + "pressure": 1009, + "sea_level": 1009, + "grnd_level": 1004, + "humidity": 56, + "temp_kf": 0 + }, + "weather": [ + { + "id": 804, + "main": "Clouds", + "description": "overcast clouds", + "icon": "04n" + } + ], + "clouds": { + "all": 100 + }, + "wind": { + "speed": 6.95, + "deg": 150, + "gust": 18.68 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-25 00:00:00" + }, + { + "dt": 1732503600, + "main": { + "temp": 16.52, + "feels_like": 15.59, + "temp_min": 16.52, + "temp_max": 16.52, + "pressure": 1007, + "sea_level": 1007, + "grnd_level": 1002, + "humidity": 52, + "temp_kf": 0 + }, + "weather": [ + { + "id": 804, + "main": "Clouds", + "description": "overcast clouds", + "icon": "04n" + } + ], + "clouds": { + "all": 99 + }, + "wind": { + "speed": 5.13, + "deg": 161, + "gust": 15.28 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-25 03:00:00" + }, + { + "dt": 1732514400, + "main": { + "temp": 16.06, + "feels_like": 15.37, + "temp_min": 16.06, + "temp_max": 16.06, + "pressure": 1008, + "sea_level": 1008, + "grnd_level": 1003, + "humidity": 63, + "temp_kf": 0 + }, + "weather": [ + { + "id": 804, + "main": "Clouds", + "description": "overcast clouds", + "icon": "04n" + } + ], + "clouds": { + "all": 100 + }, + "wind": { + "speed": 2.59, + "deg": 215, + "gust": 7.05 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-25 06:00:00" + }, + { + "dt": 1732525200, + "main": { + "temp": 13.58, + "feels_like": 13.4, + "temp_min": 13.58, + "temp_max": 13.58, + "pressure": 1011, + "sea_level": 1011, + "grnd_level": 1007, + "humidity": 92, + "temp_kf": 0 + }, + "weather": [ + { + "id": 500, + "main": "Rain", + "description": "light rain", + "icon": "10d" + } + ], + "clouds": { + "all": 100 + }, + "wind": { + "speed": 3.32, + "deg": 296, + "gust": 8.35 + }, + "visibility": 10000, + "pop": 1, + "rain": { + "3h": 1.97 + }, + "sys": { + "pod": "d" + }, + "dt_txt": "2024-11-25 09:00:00" + }, + { + "dt": 1732536000, + "main": { + "temp": 11.61, + "feels_like": 11.18, + "temp_min": 11.61, + "temp_max": 11.61, + "pressure": 1015, + "sea_level": 1015, + "grnd_level": 1010, + "humidity": 90, + "temp_kf": 0 + }, + "weather": [ + { + "id": 501, + "main": "Rain", + "description": "moderate rain", + "icon": "10d" + } + ], + "clouds": { + "all": 100 + }, + "wind": { + "speed": 2.99, + "deg": 286, + "gust": 8.29 + }, + "visibility": 8895, + "pop": 1, + "rain": { + "3h": 5.34 + }, + "sys": { + "pod": "d" + }, + "dt_txt": "2024-11-25 12:00:00" + }, + { + "dt": 1732546800, + "main": { + "temp": 12.13, + "feels_like": 11.57, + "temp_min": 12.13, + "temp_max": 12.13, + "pressure": 1016, + "sea_level": 1016, + "grnd_level": 1012, + "humidity": 83, + "temp_kf": 0 + }, + "weather": [ + { + "id": 500, + "main": "Rain", + "description": "light rain", + "icon": "10d" + } + ], + "clouds": { + "all": 100 + }, + "wind": { + "speed": 3.33, + "deg": 253, + "gust": 7.07 + }, + "visibility": 10000, + "pop": 1, + "rain": { + "3h": 2.12 + }, + "sys": { + "pod": "d" + }, + "dt_txt": "2024-11-25 15:00:00" + }, + { + "dt": 1732557600, + "main": { + "temp": 10.97, + "feels_like": 10.34, + "temp_min": 10.97, + "temp_max": 10.97, + "pressure": 1019, + "sea_level": 1019, + "grnd_level": 1014, + "humidity": 85, + "temp_kf": 0 + }, + "weather": [ + { + "id": 500, + "main": "Rain", + "description": "light rain", + "icon": "10n" + } + ], + "clouds": { + "all": 99 + }, + "wind": { + "speed": 2.57, + "deg": 224, + "gust": 6.92 + }, + "visibility": 10000, + "pop": 1, + "rain": { + "3h": 0.73 + }, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-25 18:00:00" + }, + { + "dt": 1732568400, + "main": { + "temp": 9.43, + "feels_like": 8.47, + "temp_min": 9.43, + "temp_max": 9.43, + "pressure": 1021, + "sea_level": 1021, + "grnd_level": 1017, + "humidity": 91, + "temp_kf": 0 + }, + "weather": [ + { + "id": 500, + "main": "Rain", + "description": "light rain", + "icon": "10n" + } + ], + "clouds": { + "all": 40 + }, + "wind": { + "speed": 2.07, + "deg": 217, + "gust": 3.77 + }, + "visibility": 10000, + "pop": 0.36, + "rain": { + "3h": 0.24 + }, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-25 21:00:00" + }, + { + "dt": 1732579200, + "main": { + "temp": 8.75, + "feels_like": 7.73, + "temp_min": 8.75, + "temp_max": 8.75, + "pressure": 1022, + "sea_level": 1022, + "grnd_level": 1017, + "humidity": 91, + "temp_kf": 0 + }, + "weather": [ + { + "id": 801, + "main": "Clouds", + "description": "few clouds", + "icon": "02n" + } + ], + "clouds": { + "all": 21 + }, + "wind": { + "speed": 2.01, + "deg": 206, + "gust": 3.19 + }, + "visibility": 10000, + "pop": 9000, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-26 00:00:00" + }, + { + "dt": 1732590000, + "main": { + "temp": 8.39, + "feels_like": 7.37, + "temp_min": 8.39, + "temp_max": 8.39, + "pressure": 1023, + "sea_level": 1023, + "grnd_level": 1018, + "humidity": 92, + "temp_kf": 0 + }, + "weather": [ + { + "id": 802, + "main": "Clouds", + "description": "scattered clouds", + "icon": "03n" + } + ], + "clouds": { + "all": 31 + }, + "wind": { + "speed": 1.94, + "deg": 213, + "gust": 2.61 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-26 03:00:00" + }, + { + "dt": 1732600800, + "main": { + "temp": 8.51, + "feels_like": 7.16, + "temp_min": 8.51, + "temp_max": 8.51, + "pressure": 1023, + "sea_level": 1023, + "grnd_level": 1018, + "humidity": 93, + "temp_kf": 0 + }, + "weather": [ + { + "id": 803, + "main": "Clouds", + "description": "broken clouds", + "icon": "04n" + } + ], + "clouds": { + "all": 61 + }, + "wind": { + "speed": 2.36, + "deg": 181, + "gust": 4.11 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-26 06:00:00" + }, + { + "dt": 1732611600, + "main": { + "temp": 10.55, + "feels_like": 9.96, + "temp_min": 10.55, + "temp_max": 10.55, + "pressure": 1024, + "sea_level": 1024, + "grnd_level": 1019, + "humidity": 88, + "temp_kf": 0 + }, + "weather": [ + { + "id": 804, + "main": "Clouds", + "description": "overcast clouds", + "icon": "04d" + } + ], + "clouds": { + "all": 100 + }, + "wind": { + "speed": 2.54, + "deg": 202, + "gust": 6.63 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2024-11-26 09:00:00" + }, + { + "dt": 1732622400, + "main": { + "temp": 12.51, + "feels_like": 11.88, + "temp_min": 12.51, + "temp_max": 12.51, + "pressure": 1023, + "sea_level": 1023, + "grnd_level": 1018, + "humidity": 79, + "temp_kf": 0 + }, + "weather": [ + { + "id": 804, + "main": "Clouds", + "description": "overcast clouds", + "icon": "04d" + } + ], + "clouds": { + "all": 100 + }, + "wind": { + "speed": 2.43, + "deg": 205, + "gust": 4.14 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2024-11-26 12:00:00" + }, + { + "dt": 1732633200, + "main": { + "temp": 12.24, + "feels_like": 11.63, + "temp_min": 12.24, + "temp_max": 12.24, + "pressure": 1022, + "sea_level": 1022, + "grnd_level": 1018, + "humidity": 81, + "temp_kf": 0 + }, + "weather": [ + { + "id": 804, + "main": "Clouds", + "description": "overcast clouds", + "icon": "04d" + } + ], + "clouds": { + "all": 100 + }, + "wind": { + "speed": 2.67, + "deg": 189, + "gust": 4.81 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2024-11-26 15:00:00" + }, + { + "dt": 1732644000, + "main": { + "temp": 10.6, + "feels_like": 9.88, + "temp_min": 10.6, + "temp_max": 10.6, + "pressure": 1023, + "sea_level": 1023, + "grnd_level": 1018, + "humidity": 83, + "temp_kf": 0 + }, + "weather": [ + { + "id": 804, + "main": "Clouds", + "description": "overcast clouds", + "icon": "04n" + } + ], + "clouds": { + "all": 100 + }, + "wind": { + "speed": 1.63, + "deg": 172, + "gust": 2.51 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-26 18:00:00" + }, + { + "dt": 1732654800, + "main": { + "temp": 8.95, + "feels_like": 7.85, + "temp_min": 8.95, + "temp_max": 8.95, + "pressure": 1023, + "sea_level": 1023, + "grnd_level": 1018, + "humidity": 85, + "temp_kf": 0 + }, + "weather": [ + { + "id": 803, + "main": "Clouds", + "description": "broken clouds", + "icon": "04n" + } + ], + "clouds": { + "all": 72 + }, + "wind": { + "speed": 2.14, + "deg": 166, + "gust": 3.57 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-26 21:00:00" + }, + { + "dt": 1732665600, + "main": { + "temp": 8.1, + "feels_like": 6.71, + "temp_min": 8.1, + "temp_max": 8.1, + "pressure": 1022, + "sea_level": 1022, + "grnd_level": 1017, + "humidity": 89, + "temp_kf": 0 + }, + "weather": [ + { + "id": 802, + "main": "Clouds", + "description": "scattered clouds", + "icon": "03n" + } + ], + "clouds": { + "all": 0 + }, + "wind": { + "speed": 2.32, + "deg": 151, + "gust": 4.57 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-27 00:00:00" + }, + { + "dt": 1732676400, + "main": { + "temp": 7.55, + "feels_like": 5.92, + "temp_min": 7.55, + "temp_max": 7.55, + "pressure": 1021, + "sea_level": 1021, + "grnd_level": 1016, + "humidity": 88, + "temp_kf": 0 + }, + "weather": [ + { + "id": 803, + "main": "Clouds", + "description": "broken clouds", + "icon": "04n" + } + ], + "clouds": { + "all": 0 + }, + "wind": { + "speed": 2.5, + "deg": 154, + "gust": 5.91 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-27 03:00:00" + }, + { + "dt": 1732687200, + "main": { + "temp": 7.47, + "feels_like": 5.8, + "temp_min": 7.47, + "temp_max": 7.47, + "pressure": 1021, + "sea_level": 1021, + "grnd_level": 1016, + "humidity": 84, + "temp_kf": 0 + }, + "weather": [ + { + "id": 803, + "main": "Clouds", + "description": "broken clouds", + "icon": "04n" + } + ], + "clouds": { + "all": 0 + }, + "wind": { + "speed": 2.54, + "deg": 159, + "gust": 5.65 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-27 06:00:00" + }, + { + "dt": 1732698000, + "main": { + "temp": 9.35, + "feels_like": 8.38, + "temp_min": 9.35, + "temp_max": 9.35, + "pressure": 1022, + "sea_level": 1022, + "grnd_level": 1017, + "humidity": 74, + "temp_kf": 0 + }, + "weather": [ + { + "id": 803, + "main": "Clouds", + "description": "broken clouds", + "icon": "04d" + } + ], + "clouds": { + "all": 0 + }, + "wind": { + "speed": 2.07, + "deg": 161, + "gust": 4.74 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2024-11-27 09:00:00" + }, + { + "dt": 1732708800, + "main": { + "temp": 11.8, + "feels_like": 10.73, + "temp_min": 11.8, + "temp_max": 11.8, + "pressure": 1021, + "sea_level": 1021, + "grnd_level": 1016, + "humidity": 65, + "temp_kf": 0 + }, + "weather": [ + { + "id": 803, + "main": "Clouds", + "description": "broken clouds", + "icon": "04d" + } + ], + "clouds": { + "all": 0 + }, + "wind": { + "speed": 1.46, + "deg": 173, + "gust": 3.12 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2024-11-27 12:00:00" + }, + { + "dt": 1732719600, + "main": { + "temp": 14.28, + "feels_like": 13.23, + "temp_min": 14.28, + "temp_max": 14.28, + "pressure": 1021, + "sea_level": 1021, + "grnd_level": 1016, + "humidity": 56, + "temp_kf": 0 + }, + "weather": [ + { + "id": 802, + "main": "Clouds", + "description": "scattered clouds", + "icon": "03d" + } + ], + "clouds": { + "all": 0 + }, + "wind": { + "speed": 1.34, + "deg": 158, + "gust": 1.71 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2024-11-27 15:00:00" + }, + { + "dt": 1732730400, + "main": { + "temp": 10.81, + "feels_like": 9.7, + "temp_min": 10.81, + "temp_max": 10.81, + "pressure": 1021, + "sea_level": 1021, + "grnd_level": 1016, + "humidity": 67, + "temp_kf": 0 + }, + "weather": [ + { + "id": 802, + "main": "Clouds", + "description": "scattered clouds", + "icon": "03n" + } + ], + "clouds": { + "all": 0 + }, + "wind": { + "speed": 1.81, + "deg": 164, + "gust": 1.94 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-27 18:00:00" + }, + { + "dt": 1732741200, + "main": { + "temp": 9.66, + "feels_like": 8.85, + "temp_min": 9.66, + "temp_max": 9.66, + "pressure": 1022, + "sea_level": 1022, + "grnd_level": 1017, + "humidity": 72, + "temp_kf": 0 + }, + "weather": [ + { + "id": 802, + "main": "Clouds", + "description": "scattered clouds", + "icon": "03n" + } + ], + "clouds": { + "all": 48 + }, + "wind": { + "speed": 1.93, + "deg": 160, + "gust": 2.05 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-27 21:00:00" + }, + { + "dt": 1732752000, + "main": { + "temp": 9.16, + "feels_like": 8.53, + "temp_min": 9.16, + "temp_max": 9.16, + "pressure": 1021, + "sea_level": 1021, + "grnd_level": 1016, + "humidity": 74, + "temp_kf": 0 + }, + "weather": [ + { + "id": 803, + "main": "Clouds", + "description": "broken clouds", + "icon": "04n" + } + ], + "clouds": { + "all": 57 + }, + "wind": { + "speed": 1.66, + "deg": 167, + "gust": 1.66 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-28 00:00:00" + }, + { + "dt": 1732762800, + "main": { + "temp": 9.04, + "feels_like": 8.02, + "temp_min": 9.04, + "temp_max": 9.04, + "pressure": 1021, + "sea_level": 1021, + "grnd_level": 1016, + "humidity": 73, + "temp_kf": 0 + }, + "weather": [ + { + "id": 803, + "main": "Clouds", + "description": "broken clouds", + "icon": "04n" + } + ], + "clouds": { + "all": 82 + }, + "wind": { + "speed": 2.06, + "deg": 172, + "gust": 2.47 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-28 03:00:00" + }, + { + "dt": 1732773600, + "main": { + "temp": 8.56, + "feels_like": 7.61, + "temp_min": 8.56, + "temp_max": 8.56, + "pressure": 1021, + "sea_level": 1021, + "grnd_level": 1016, + "humidity": 74, + "temp_kf": 0 + }, + "weather": [ + { + "id": 804, + "main": "Clouds", + "description": "overcast clouds", + "icon": "04n" + } + ], + "clouds": { + "all": 86 + }, + "wind": { + "speed": 1.89, + "deg": 193, + "gust": 1.99 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-28 06:00:00" + }, + { + "dt": 1732784400, + "main": { + "temp": 10.51, + "feels_like": 9.52, + "temp_min": 10.51, + "temp_max": 10.51, + "pressure": 1022, + "sea_level": 1022, + "grnd_level": 1017, + "humidity": 73, + "temp_kf": 0 + }, + "weather": [ + { + "id": 804, + "main": "Clouds", + "description": "overcast clouds", + "icon": "04d" + } + ], + "clouds": { + "all": 93 + }, + "wind": { + "speed": 1.5, + "deg": 203, + "gust": 2.77 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2024-11-28 09:00:00" + }, + { + "dt": 1732795200, + "main": { + "temp": 13.48, + "feels_like": 12.79, + "temp_min": 13.48, + "temp_max": 13.48, + "pressure": 1022, + "sea_level": 1022, + "grnd_level": 1017, + "humidity": 73, + "temp_kf": 0 + }, + "weather": [ + { + "id": 804, + "main": "Clouds", + "description": "overcast clouds", + "icon": "04d" + } + ], + "clouds": { + "all": 91 + }, + "wind": { + "speed": 2.13, + "deg": 223, + "gust": 3.44 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2024-11-28 12:00:00" + }, + { + "dt": 1732806000, + "main": { + "temp": 15.76, + "feels_like": 15.27, + "temp_min": 15.76, + "temp_max": 15.76, + "pressure": 1022, + "sea_level": 1022, + "grnd_level": 1017, + "humidity": 72, + "temp_kf": 0 + }, + "weather": [ + { + "id": 803, + "main": "Clouds", + "description": "broken clouds", + "icon": "04d" + } + ], + "clouds": { + "all": 64 + }, + "wind": { + "speed": 1.82, + "deg": 262, + "gust": 3.62 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "d" + }, + "dt_txt": "2024-11-28 15:00:00" + }, + { + "dt": 1732816800, + "main": { + "temp": 12.48, + "feels_like": 12.16, + "temp_min": 12.48, + "temp_max": 12.48, + "pressure": 1023, + "sea_level": 1023, + "grnd_level": 1018, + "humidity": 91, + "temp_kf": 0 + }, + "weather": [ + { + "id": 803, + "main": "Clouds", + "description": "broken clouds", + "icon": "04n" + } + ], + "clouds": { + "all": 63 + }, + "wind": { + "speed": 1.09, + "deg": 273, + "gust": 0.73 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-28 18:00:00" + }, + { + "dt": 1732827600, + "main": { + "temp": 12.51, + "feels_like": 12.04, + "temp_min": 12.51, + "temp_max": 12.51, + "pressure": 1024, + "sea_level": 1024, + "grnd_level": 1019, + "humidity": 85, + "temp_kf": 0 + }, + "weather": [ + { + "id": 804, + "main": "Clouds", + "description": "overcast clouds", + "icon": "04n" + } + ], + "clouds": { + "all": 89 + }, + "wind": { + "speed": 2.32, + "deg": 96, + "gust": 4.52 + }, + "visibility": 10000, + "pop": 0, + "sys": { + "pod": "n" + }, + "dt_txt": "2024-11-28 21:00:00" + } + ], + "city": { + "id": 3031582, + "name": "Bordeaux", + "coord": { + "lat": 44.85, + "lon": -0.59 + }, + "country": "FR", + "population": 231844, + "timezone": 3600, + "sunrise": 1732345841, + "sunset": 1732379244 + } +} \ No newline at end of file diff --git a/src/test/resources/OpenWeatherMap/wrong-apikey.json b/src/test/resources/OpenWeatherMap/wrong-apikey.json new file mode 100644 index 0000000..0ba9c1e --- /dev/null +++ b/src/test/resources/OpenWeatherMap/wrong-apikey.json @@ -0,0 +1,4 @@ +{ + "cod": 401, + "message": "Invalid API key. Please see https://openweathermap.org/faq#error401 for more info." +} \ No newline at end of file diff --git a/src/test/resources/WeatherAPI/Bordeaux-1-partial.json b/src/test/resources/WeatherAPI/Bordeaux-1-partial.json new file mode 100644 index 0000000..6e10f39 --- /dev/null +++ b/src/test/resources/WeatherAPI/Bordeaux-1-partial.json @@ -0,0 +1,3057 @@ +{ + "location": { + "name": "Bordeaux", + "region": "Aquitaine", + "country": "France", + "lat": 44.8333, + "lon": -0.5667, + "tz_id": "Europe/Paris", + "localtime_epoch": 1732356248, + "localtime": "2024-11-23 11:04" + }, + "current": { + "last_updated_epoch": 1732356000, + "last_updated": "2024-11-23 11:00", + "temp_c": 7.4, + "temp_f": 45.3, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.4, + "wind_kph": 18.4, + "wind_degree": 148, + "wind_dir": "SSE", + "pressure_mb": 1018, + "pressure_in": 30.06, + "precip_mm": 0, + "precip_in": 0, + "humidity": 76, + "cloud": 0, + "feelslike_c": 4.3, + "feelslike_f": 39.7, + "windchill_c": 6, + "windchill_f": 42.7, + "heatindex_c": 8.7, + "heatindex_f": 47.7, + "dewpoint_c": 1.3, + "dewpoint_f": 34.3, + "vis_km": 10, + "vis_miles": 6, + "uv": 0.9, + "gust_mph": 15.9, + "gust_kph": 25.5 + }, + "forecast": { + "forecastday": [ + { + "date": "2024-11-23", + "date_epoch": 1732320000, + "day": { + "maxtemp_c": 13.1, + "maxtemp_f": 55.7, + "mintemp_c": 4, + "mintemp_f": 39.3, + "avgtemp_c": 8.1, + "avgtemp_f": 46.6, + "maxwind_mph": 13, + "maxwind_kph": 20.9, + "totalprecip_mm": 0, + "totalprecip_in": 0, + "totalsnow_cm": 0, + "avgvis_km": 10, + "avgvis_miles": 6, + "avghumidity": 69, + "daily_will_it_rain": 0, + "daily_chance_of_rain": 0, + "daily_will_it_snow": 0, + "daily_chance_of_snow": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/day/116.png", + "code": 1003 + }, + "uv": 0.3 + }, + "astro": { + "sunrise": "08:10 AM", + "sunset": "05:27 PM", + "moonrise": "12:08 AM", + "moonset": "02:13 PM", + "moon_phase": "Last Quarter", + "moon_illumination": 51, + "is_moon_up": 0, + "is_sun_up": 0 + }, + "hour": [ + { + "time_epoch": 1732316400, + "time": "2024-11-23 00:00", + "temp_c": 5.6, + "temp_f": 42, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 6.7, + "wind_kph": 10.8, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1022, + "pressure_in": 30.19, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 81, + "cloud": 17, + "feelslike_c": 3.2, + "feelslike_f": 37.7, + "windchill_c": 3.2, + "windchill_f": 37.7, + "heatindex_c": 5.6, + "heatindex_f": 42, + "dewpoint_c": 2.6, + "dewpoint_f": 36.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 13.7, + "gust_kph": 22, + "uv": 0 + }, + { + "time_epoch": 1732320000, + "time": "2024-11-23 01:00", + "temp_c": 5.8, + "temp_f": 42.4, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 6.9, + "wind_kph": 11.2, + "wind_degree": 141, + "wind_dir": "SE", + "pressure_mb": 1022, + "pressure_in": 30.17, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 80, + "cloud": 47, + "feelslike_c": 3.3, + "feelslike_f": 38, + "windchill_c": 3.3, + "windchill_f": 38, + "heatindex_c": 5.8, + "heatindex_f": 42.4, + "dewpoint_c": 2.5, + "dewpoint_f": 36.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 13.4, + "gust_kph": 21.6, + "uv": 0 + }, + { + "time_epoch": 1732323600, + "time": "2024-11-23 02:00", + "temp_c": 5.6, + "temp_f": 42.1, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 8.3, + "wind_kph": 13.3, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1021, + "pressure_in": 30.14, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 79, + "cloud": 56, + "feelslike_c": 2.8, + "feelslike_f": 37, + "windchill_c": 2.8, + "windchill_f": 37, + "heatindex_c": 5.6, + "heatindex_f": 42.1, + "dewpoint_c": 2.3, + "dewpoint_f": 36.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 15.3, + "gust_kph": 24.7, + "uv": 0 + }, + { + "time_epoch": 1732327200, + "time": "2024-11-23 03:00", + "temp_c": 5.1, + "temp_f": 41.3, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 9.8, + "wind_kph": 15.8, + "wind_degree": 133, + "wind_dir": "SE", + "pressure_mb": 1020, + "pressure_in": 30.13, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 79, + "cloud": 86, + "feelslike_c": 1.8, + "feelslike_f": 35.3, + "windchill_c": 1.8, + "windchill_f": 35.3, + "heatindex_c": 5.2, + "heatindex_f": 41.3, + "dewpoint_c": 1.9, + "dewpoint_f": 35.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 17.6, + "gust_kph": 28.4, + "uv": 0 + }, + { + "time_epoch": 1732330800, + "time": "2024-11-23 04:00", + "temp_c": 4.8, + "temp_f": 40.7, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 10.5, + "wind_kph": 16.9, + "wind_degree": 130, + "wind_dir": "SE", + "pressure_mb": 1020, + "pressure_in": 30.12, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 79, + "cloud": 44, + "feelslike_c": 1.3, + "feelslike_f": 34.3, + "windchill_c": 1.3, + "windchill_f": 34.3, + "heatindex_c": 4.9, + "heatindex_f": 40.7, + "dewpoint_c": 1.5, + "dewpoint_f": 34.7, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 18.1, + "gust_kph": 29.1, + "uv": 0 + }, + { + "time_epoch": 1732334400, + "time": "2024-11-23 05:00", + "temp_c": 4.3, + "temp_f": 39.7, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11, + "wind_kph": 17.6, + "wind_degree": 130, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.1, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 80, + "cloud": 46, + "feelslike_c": 0.5, + "feelslike_f": 32.8, + "windchill_c": 0.5, + "windchill_f": 32.8, + "heatindex_c": 4.3, + "heatindex_f": 39.7, + "dewpoint_c": 1.2, + "dewpoint_f": 34.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19.1, + "gust_kph": 30.8, + "uv": 0 + }, + { + "time_epoch": 1732338000, + "time": "2024-11-23 06:00", + "temp_c": 4, + "temp_f": 39.3, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.08, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 80, + "cloud": 39, + "feelslike_c": 0.1, + "feelslike_f": 32.2, + "windchill_c": 0.1, + "windchill_f": 32.2, + "heatindex_c": 4, + "heatindex_f": 39.3, + "dewpoint_c": 0.9, + "dewpoint_f": 33.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19.8, + "gust_kph": 31.8, + "uv": 0 + }, + { + "time_epoch": 1732341600, + "time": "2024-11-23 07:00", + "temp_c": 4, + "temp_f": 39.3, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.08, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 78, + "cloud": 26, + "feelslike_c": 0.1, + "feelslike_f": 32.2, + "windchill_c": 0.1, + "windchill_f": 32.2, + "heatindex_c": 4, + "heatindex_f": 39.3, + "dewpoint_c": 0.6, + "dewpoint_f": 33, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19.9, + "gust_kph": 32, + "uv": 0 + }, + { + "time_epoch": 1732345200, + "time": "2024-11-23 08:00", + "temp_c": 4.1, + "temp_f": 39.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 10.5, + "wind_kph": 16.9, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.09, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 75, + "cloud": 7, + "feelslike_c": 0.4, + "feelslike_f": 32.6, + "windchill_c": 0.4, + "windchill_f": 32.6, + "heatindex_c": 4.1, + "heatindex_f": 39.4, + "dewpoint_c": 0.1, + "dewpoint_f": 32.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 18.8, + "gust_kph": 30.2, + "uv": 0 + }, + { + "time_epoch": 1732348800, + "time": "2024-11-23 09:00", + "temp_c": 4.6, + "temp_f": 40.3, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 10.7, + "wind_kph": 17.3, + "wind_degree": 143, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.09, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 71, + "cloud": 13, + "feelslike_c": 1, + "feelslike_f": 33.7, + "windchill_c": 1, + "windchill_f": 33.7, + "heatindex_c": 4.6, + "heatindex_f": 40.4, + "dewpoint_c": -0.2, + "dewpoint_f": 31.7, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19, + "gust_kph": 30.5, + "uv": 0 + }, + { + "time_epoch": 1732352400, + "time": "2024-11-23 10:00", + "temp_c": 6.6, + "temp_f": 43.9, + "is_day": 1, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/day/116.png", + "code": 1003 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 146, + "wind_dir": "SSE", + "pressure_mb": 1019, + "pressure_in": 30.08, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 63, + "cloud": 49, + "feelslike_c": 3.4, + "feelslike_f": 38, + "windchill_c": 3.4, + "windchill_f": 38, + "heatindex_c": 6.6, + "heatindex_f": 43.9, + "dewpoint_c": 0.2, + "dewpoint_f": 32.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 17.5, + "gust_kph": 28.2, + "uv": 0.4 + }, + { + "time_epoch": 1732356000, + "time": "2024-11-23 11:00", + "temp_c": 7.4, + "temp_f": 45.3, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.4, + "wind_kph": 18.4, + "wind_degree": 148, + "wind_dir": "SSE", + "pressure_mb": 1018, + "pressure_in": 30.06, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 76, + "cloud": 0, + "feelslike_c": 6, + "feelslike_f": 42.7, + "windchill_c": 6, + "windchill_f": 42.7, + "heatindex_c": 8.7, + "heatindex_f": 47.7, + "dewpoint_c": 1.3, + "dewpoint_f": 34.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 15.9, + "gust_kph": 25.5, + "uv": 0.9 + }, + { + "time_epoch": 1732359600, + "time": "2024-11-23 12:00", + "temp_c": 10.4, + "temp_f": 50.8, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11, + "wind_kph": 17.6, + "wind_degree": 149, + "wind_dir": "SSE", + "pressure_mb": 1018, + "pressure_in": 30.07, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 56, + "cloud": 21, + "feelslike_c": 8.2, + "feelslike_f": 46.7, + "windchill_c": 8.2, + "windchill_f": 46.7, + "heatindex_c": 10.5, + "heatindex_f": 50.8, + "dewpoint_c": 2.2, + "dewpoint_f": 35.9, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 14.7, + "gust_kph": 23.6, + "uv": 1.3 + }, + { + "time_epoch": 1732363200, + "time": "2024-11-23 13:00", + "temp_c": 12.3, + "temp_f": 54.2, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.4, + "wind_kph": 18.4, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1017, + "pressure_in": 30.04, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 52, + "cloud": 22, + "feelslike_c": 10.5, + "feelslike_f": 50.8, + "windchill_c": 10.5, + "windchill_f": 50.8, + "heatindex_c": 12.3, + "heatindex_f": 54.2, + "dewpoint_c": 2.8, + "dewpoint_f": 37, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 14.9, + "gust_kph": 23.9, + "uv": 1.6 + }, + { + "time_epoch": 1732366800, + "time": "2024-11-23 14:00", + "temp_c": 13, + "temp_f": 55.4, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 10.3, + "wind_kph": 16.6, + "wind_degree": 149, + "wind_dir": "SSE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 54, + "cloud": 12, + "feelslike_c": 11.5, + "feelslike_f": 52.7, + "windchill_c": 11.5, + "windchill_f": 52.7, + "heatindex_c": 13, + "heatindex_f": 55.4, + "dewpoint_c": 3.8, + "dewpoint_f": 38.9, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 14, + "gust_kph": 22.6, + "uv": 1.4 + }, + { + "time_epoch": 1732370400, + "time": "2024-11-23 15:00", + "temp_c": 13.1, + "temp_f": 55.7, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.4, + "wind_kph": 18.4, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1016, + "pressure_in": 30.01, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 54, + "cloud": 22, + "feelslike_c": 11.5, + "feelslike_f": 52.7, + "windchill_c": 11.5, + "windchill_f": 52.7, + "heatindex_c": 13.2, + "heatindex_f": 55.7, + "dewpoint_c": 4.2, + "dewpoint_f": 39.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 16.8, + "gust_kph": 27.1, + "uv": 0.9 + }, + { + "time_epoch": 1732374000, + "time": "2024-11-23 16:00", + "temp_c": 12.5, + "temp_f": 54.4, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 10.7, + "wind_kph": 17.3, + "wind_degree": 148, + "wind_dir": "SSE", + "pressure_mb": 1017, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 57, + "cloud": 14, + "feelslike_c": 10.7, + "feelslike_f": 51.3, + "windchill_c": 10.7, + "windchill_f": 51.3, + "heatindex_c": 12.5, + "heatindex_f": 54.4, + "dewpoint_c": 4.1, + "dewpoint_f": 39.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 17.5, + "gust_kph": 28.1, + "uv": 0.4 + }, + { + "time_epoch": 1732377600, + "time": "2024-11-23 17:00", + "temp_c": 11.2, + "temp_f": 52.1, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 141, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 61, + "cloud": 22, + "feelslike_c": 9, + "feelslike_f": 48.2, + "windchill_c": 9, + "windchill_f": 48.2, + "heatindex_c": 11.2, + "heatindex_f": 52.1, + "dewpoint_c": 4, + "dewpoint_f": 39.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 20.2, + "gust_kph": 32.5, + "uv": 0 + }, + { + "time_epoch": 1732381200, + "time": "2024-11-23 18:00", + "temp_c": 10.2, + "temp_f": 50.4, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11.6, + "wind_kph": 18.7, + "wind_degree": 141, + "wind_dir": "SE", + "pressure_mb": 1016, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 64, + "cloud": 47, + "feelslike_c": 7.8, + "feelslike_f": 46, + "windchill_c": 7.8, + "windchill_f": 46, + "heatindex_c": 10.2, + "heatindex_f": 50.4, + "dewpoint_c": 3.8, + "dewpoint_f": 38.9, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.2, + "gust_kph": 35.7, + "uv": 0 + }, + { + "time_epoch": 1732384800, + "time": "2024-11-23 19:00", + "temp_c": 10, + "temp_f": 50.1, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.3, + "wind_kph": 19.8, + "wind_degree": 144, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 66, + "cloud": 62, + "feelslike_c": 7.5, + "feelslike_f": 45.4, + "windchill_c": 7.5, + "windchill_f": 45.4, + "heatindex_c": 10, + "heatindex_f": 50.1, + "dewpoint_c": 4, + "dewpoint_f": 39.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.8, + "gust_kph": 36.8, + "uv": 0 + }, + { + "time_epoch": 1732388400, + "time": "2024-11-23 20:00", + "temp_c": 10, + "temp_f": 50, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 143, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 68, + "cloud": 57, + "feelslike_c": 7.3, + "feelslike_f": 45.2, + "windchill_c": 7.3, + "windchill_f": 45.2, + "heatindex_c": 10, + "heatindex_f": 50, + "dewpoint_c": 4.3, + "dewpoint_f": 39.8, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.6, + "gust_kph": 36.3, + "uv": 0 + }, + { + "time_epoch": 1732392000, + "time": "2024-11-23 21:00", + "temp_c": 9.7, + "temp_f": 49.5, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 142, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 71, + "cloud": 46, + "feelslike_c": 7, + "feelslike_f": 44.6, + "windchill_c": 7, + "windchill_f": 44.6, + "heatindex_c": 9.7, + "heatindex_f": 49.5, + "dewpoint_c": 4.6, + "dewpoint_f": 40.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.3, + "gust_kph": 35.9, + "uv": 0 + }, + { + "time_epoch": 1732395600, + "time": "2024-11-23 22:00", + "temp_c": 9.5, + "temp_f": 49.1, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13, + "wind_kph": 20.9, + "wind_degree": 139, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 73, + "cloud": 24, + "feelslike_c": 6.6, + "feelslike_f": 44, + "windchill_c": 6.6, + "windchill_f": 44, + "heatindex_c": 9.5, + "heatindex_f": 49.1, + "dewpoint_c": 5, + "dewpoint_f": 41, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23, + "gust_kph": 37, + "uv": 0 + }, + { + "time_epoch": 1732399200, + "time": "2024-11-23 23:00", + "temp_c": 9.3, + "temp_f": 48.8, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 12.8, + "wind_kph": 20.5, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 76, + "cloud": 21, + "feelslike_c": 6.5, + "feelslike_f": 43.7, + "windchill_c": 6.5, + "windchill_f": 43.7, + "heatindex_c": 9.3, + "heatindex_f": 48.8, + "dewpoint_c": 5.3, + "dewpoint_f": 41.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23, + "gust_kph": 37, + "uv": 0 + } + ] + }, + { + "date": "2024-11-24", + "date_epoch": 1732406400, + "day": { + "maxtemp_c": 17.2, + "maxtemp_f": 63, + "mintemp_c": 9.3, + "mintemp_f": 48.8, + "avgtemp_c": 13, + "avgtemp_f": 55.3, + "maxwind_mph": 16.3, + "maxwind_kph": 26.3, + "totalprecip_mm": 0, + "totalprecip_in": 0, + "totalsnow_cm": 0, + "avgvis_km": 10, + "avgvis_miles": 6, + "avghumidity": 70, + "daily_will_it_rain": 0, + "daily_chance_of_rain": 0, + "daily_will_it_snow": 0, + "daily_chance_of_snow": 0, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "uv": 0.3 + }, + "astro": { + "sunrise": "08:12 AM", + "sunset": "05:26 PM", + "moonrise": "01:14 AM", + "moonset": "02:30 PM", + "moon_phase": "Waning Crescent", + "moon_illumination": 41, + "is_moon_up": 0, + "is_sun_up": 0 + }, + "hour": [ + { + "time_epoch": 1732402800, + "time": "2024-11-24 00:00", + "temp_c": 9.3, + "temp_f": 48.8, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 77, + "cloud": 41, + "feelslike_c": 6.5, + "feelslike_f": 43.8, + "windchill_c": 6.5, + "windchill_f": 43.8, + "heatindex_c": 9.3, + "heatindex_f": 48.8, + "dewpoint_c": 5.6, + "dewpoint_f": 42, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.1, + "gust_kph": 37.2, + "uv": 0 + }, + { + "time_epoch": 1732406400, + "time": "2024-11-24 01:00", + "temp_c": 9.5, + "temp_f": 49.1, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 139, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 77, + "cloud": 33, + "feelslike_c": 6.7, + "feelslike_f": 44.1, + "windchill_c": 6.7, + "windchill_f": 44.1, + "heatindex_c": 9.5, + "heatindex_f": 49.1, + "dewpoint_c": 5.7, + "dewpoint_f": 42.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.4, + "gust_kph": 37.7, + "uv": 0 + }, + { + "time_epoch": 1732410000, + "time": "2024-11-24 02:00", + "temp_c": 9.7, + "temp_f": 49.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 12.3, + "wind_kph": 19.8, + "wind_degree": 139, + "wind_dir": "SE", + "pressure_mb": 1016, + "pressure_in": 30, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 77, + "cloud": 22, + "feelslike_c": 7, + "feelslike_f": 44.5, + "windchill_c": 7, + "windchill_f": 44.5, + "heatindex_c": 9.7, + "heatindex_f": 49.4, + "dewpoint_c": 5.8, + "dewpoint_f": 42.4, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.2, + "gust_kph": 37.3, + "uv": 0 + }, + { + "time_epoch": 1732413600, + "time": "2024-11-24 03:00", + "temp_c": 9.7, + "temp_f": 49.5, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 12.8, + "wind_kph": 20.5, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1016, + "pressure_in": 30, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 76, + "cloud": 14, + "feelslike_c": 7, + "feelslike_f": 44.6, + "windchill_c": 7, + "windchill_f": 44.6, + "heatindex_c": 9.7, + "heatindex_f": 49.5, + "dewpoint_c": 5.7, + "dewpoint_f": 42.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.3, + "gust_kph": 39.2, + "uv": 0 + }, + { + "time_epoch": 1732417200, + "time": "2024-11-24 04:00", + "temp_c": 9.8, + "temp_f": 49.6, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13, + "wind_kph": 20.9, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 75, + "cloud": 10, + "feelslike_c": 7, + "feelslike_f": 44.6, + "windchill_c": 7, + "windchill_f": 44.6, + "heatindex_c": 9.8, + "heatindex_f": 49.6, + "dewpoint_c": 5.7, + "dewpoint_f": 42.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.6, + "gust_kph": 39.6, + "uv": 0 + }, + { + "time_epoch": 1732420800, + "time": "2024-11-24 05:00", + "temp_c": 9.7, + "temp_f": 49.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13.4, + "wind_kph": 21.6, + "wind_degree": 136, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 76, + "cloud": 10, + "feelslike_c": 6.8, + "feelslike_f": 44.3, + "windchill_c": 6.8, + "windchill_f": 44.3, + "heatindex_c": 9.7, + "heatindex_f": 49.4, + "dewpoint_c": 5.7, + "dewpoint_f": 42.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25.3, + "gust_kph": 40.7, + "uv": 0 + }, + { + "time_epoch": 1732424400, + "time": "2024-11-24 06:00", + "temp_c": 9.7, + "temp_f": 49.5, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13.6, + "wind_kph": 22, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 77, + "cloud": 11, + "feelslike_c": 6.8, + "feelslike_f": 44.3, + "windchill_c": 6.8, + "windchill_f": 44.3, + "heatindex_c": 9.7, + "heatindex_f": 49.5, + "dewpoint_c": 5.8, + "dewpoint_f": 42.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25.7, + "gust_kph": 41.4, + "uv": 0 + }, + { + "time_epoch": 1732428000, + "time": "2024-11-24 07:00", + "temp_c": 9.7, + "temp_f": 49.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13.6, + "wind_kph": 22, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.97, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 78, + "cloud": 8, + "feelslike_c": 6.8, + "feelslike_f": 44.2, + "windchill_c": 6.8, + "windchill_f": 44.2, + "heatindex_c": 9.7, + "heatindex_f": 49.4, + "dewpoint_c": 6, + "dewpoint_f": 42.7, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25.5, + "gust_kph": 41, + "uv": 0 + }, + { + "time_epoch": 1732431600, + "time": "2024-11-24 08:00", + "temp_c": 9.7, + "temp_f": 49.5, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13.2, + "wind_kph": 21.2, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 78, + "cloud": 7, + "feelslike_c": 6.9, + "feelslike_f": 44.4, + "windchill_c": 6.9, + "windchill_f": 44.4, + "heatindex_c": 9.7, + "heatindex_f": 49.5, + "dewpoint_c": 6.1, + "dewpoint_f": 43, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.8, + "gust_kph": 40, + "uv": 0 + }, + { + "time_epoch": 1732435200, + "time": "2024-11-24 09:00", + "temp_c": 10.1, + "temp_f": 50.1, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 13.6, + "wind_kph": 22, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 78, + "cloud": 7, + "feelslike_c": 7.3, + "feelslike_f": 45.1, + "windchill_c": 7.3, + "windchill_f": 45.1, + "heatindex_c": 10.1, + "heatindex_f": 50.1, + "dewpoint_c": 6.4, + "dewpoint_f": 43.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.5, + "gust_kph": 39.5, + "uv": 0 + }, + { + "time_epoch": 1732438800, + "time": "2024-11-24 10:00", + "temp_c": 11.4, + "temp_f": 52.5, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 14.5, + "wind_kph": 23.4, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.97, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 74, + "cloud": 5, + "feelslike_c": 8.9, + "feelslike_f": 47.9, + "windchill_c": 8.9, + "windchill_f": 47.9, + "heatindex_c": 11.4, + "heatindex_f": 52.5, + "dewpoint_c": 7, + "dewpoint_f": 44.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.2, + "gust_kph": 37.3, + "uv": 0.4 + }, + { + "time_epoch": 1732442400, + "time": "2024-11-24 11:00", + "temp_c": 13.2, + "temp_f": 55.7, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 15.7, + "wind_kph": 25.2, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.96, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 70, + "cloud": 4, + "feelslike_c": 11, + "feelslike_f": 51.8, + "windchill_c": 11, + "windchill_f": 51.8, + "heatindex_c": 13.2, + "heatindex_f": 55.7, + "dewpoint_c": 7.8, + "dewpoint_f": 46, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.5, + "gust_kph": 36.3, + "uv": 0.8 + }, + { + "time_epoch": 1732446000, + "time": "2024-11-24 12:00", + "temp_c": 15, + "temp_f": 58.9, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 16.1, + "wind_kph": 25.9, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1014, + "pressure_in": 29.95, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 65, + "cloud": 4, + "feelslike_c": 13.3, + "feelslike_f": 55.9, + "windchill_c": 13.3, + "windchill_f": 55.9, + "heatindex_c": 15, + "heatindex_f": 58.9, + "dewpoint_c": 8.4, + "dewpoint_f": 47.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 21.9, + "gust_kph": 35.2, + "uv": 1.3 + }, + { + "time_epoch": 1732449600, + "time": "2024-11-24 13:00", + "temp_c": 16.4, + "temp_f": 61.6, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 16.1, + "wind_kph": 25.9, + "wind_degree": 142, + "wind_dir": "SE", + "pressure_mb": 1013, + "pressure_in": 29.91, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 60, + "cloud": 5, + "feelslike_c": 16.4, + "feelslike_f": 61.6, + "windchill_c": 16.4, + "windchill_f": 61.6, + "heatindex_c": 16.4, + "heatindex_f": 61.6, + "dewpoint_c": 8.8, + "dewpoint_f": 47.8, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 21.6, + "gust_kph": 34.7, + "uv": 1.4 + }, + { + "time_epoch": 1732453200, + "time": "2024-11-24 14:00", + "temp_c": 17.2, + "temp_f": 62.9, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 16.3, + "wind_kph": 26.3, + "wind_degree": 143, + "wind_dir": "SE", + "pressure_mb": 1012, + "pressure_in": 29.89, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 59, + "cloud": 4, + "feelslike_c": 17.2, + "feelslike_f": 62.9, + "windchill_c": 17.2, + "windchill_f": 62.9, + "heatindex_c": 17.2, + "heatindex_f": 62.9, + "dewpoint_c": 9, + "dewpoint_f": 48.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.9, + "gust_kph": 36.8, + "uv": 1.3 + }, + { + "time_epoch": 1732456800, + "time": "2024-11-24 15:00", + "temp_c": 17.2, + "temp_f": 63, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 16.3, + "wind_kph": 26.3, + "wind_degree": 145, + "wind_dir": "SE", + "pressure_mb": 1012, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 59, + "cloud": 1, + "feelslike_c": 17.2, + "feelslike_f": 63, + "windchill_c": 17.2, + "windchill_f": 63, + "heatindex_c": 17.2, + "heatindex_f": 63, + "dewpoint_c": 9.2, + "dewpoint_f": 48.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25, + "gust_kph": 40.2, + "uv": 0.8 + }, + { + "time_epoch": 1732460400, + "time": "2024-11-24 16:00", + "temp_c": 16.6, + "temp_f": 61.9, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 15.7, + "wind_kph": 25.2, + "wind_degree": 147, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 61, + "cloud": 3, + "feelslike_c": 16.6, + "feelslike_f": 61.9, + "windchill_c": 16.6, + "windchill_f": 61.9, + "heatindex_c": 16.6, + "heatindex_f": 61.9, + "dewpoint_c": 9.2, + "dewpoint_f": 48.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25.9, + "gust_kph": 41.7, + "uv": 0.4 + }, + { + "time_epoch": 1732464000, + "time": "2024-11-24 17:00", + "temp_c": 15.7, + "temp_f": 60.3, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 15.4, + "wind_kph": 24.8, + "wind_degree": 147, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 65, + "cloud": 22, + "feelslike_c": 15.7, + "feelslike_f": 60.3, + "windchill_c": 15.7, + "windchill_f": 60.3, + "heatindex_c": 15.7, + "heatindex_f": 60.3, + "dewpoint_c": 9.1, + "dewpoint_f": 48.4, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 27, + "gust_kph": 43.5, + "uv": 0 + }, + { + "time_epoch": 1732467600, + "time": "2024-11-24 18:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 15.4, + "wind_kph": 24.8, + "wind_degree": 149, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 66, + "cloud": 15, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 9.1, + "dewpoint_f": 48.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 27.8, + "gust_kph": 44.8, + "uv": 0 + }, + { + "time_epoch": 1732471200, + "time": "2024-11-24 19:00", + "temp_c": 15.2, + "temp_f": 59.4, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 15.7, + "wind_kph": 25.2, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 67, + "cloud": 47, + "feelslike_c": 15.2, + "feelslike_f": 59.4, + "windchill_c": 15.2, + "windchill_f": 59.4, + "heatindex_c": 15.2, + "heatindex_f": 59.4, + "dewpoint_c": 9.1, + "dewpoint_f": 48.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 28.4, + "gust_kph": 45.7, + "uv": 0 + }, + { + "time_epoch": 1732474800, + "time": "2024-11-24 20:00", + "temp_c": 15.2, + "temp_f": 59.4, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 14.8, + "wind_kph": 23.8, + "wind_degree": 149, + "wind_dir": "SSE", + "pressure_mb": 1012, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 67, + "cloud": 56, + "feelslike_c": 15.2, + "feelslike_f": 59.4, + "windchill_c": 15.2, + "windchill_f": 59.4, + "heatindex_c": 15.2, + "heatindex_f": 59.4, + "dewpoint_c": 9.2, + "dewpoint_f": 48.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.5, + "gust_kph": 42.6, + "uv": 0 + }, + { + "time_epoch": 1732478400, + "time": "2024-11-24 21:00", + "temp_c": 15.4, + "temp_f": 59.7, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 14.3, + "wind_kph": 23, + "wind_degree": 151, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 67, + "cloud": 49, + "feelslike_c": 15.4, + "feelslike_f": 59.7, + "windchill_c": 15.4, + "windchill_f": 59.7, + "heatindex_c": 15.4, + "heatindex_f": 59.7, + "dewpoint_c": 9.3, + "dewpoint_f": 48.8, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.7, + "gust_kph": 39.8, + "uv": 0 + }, + { + "time_epoch": 1732482000, + "time": "2024-11-24 22:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 13, + "wind_kph": 20.9, + "wind_degree": 155, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 67, + "cloud": 47, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 9.2, + "dewpoint_f": 48.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.7, + "gust_kph": 36.5, + "uv": 0 + }, + { + "time_epoch": 1732485600, + "time": "2024-11-24 23:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 13.4, + "wind_kph": 21.6, + "wind_degree": 151, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 65, + "cloud": 66, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 8.8, + "dewpoint_f": 47.9, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.8, + "gust_kph": 38.3, + "uv": 0 + } + ] + }, + { + "date": "2024-11-25", + "date_epoch": 1732492800, + "day": { + "maxtemp_c": 15.5, + "maxtemp_f": 59.8, + "mintemp_c": 9.5, + "mintemp_f": 49.1, + "avgtemp_c": 12.7, + "avgtemp_f": 54.8, + "maxwind_mph": 15, + "maxwind_kph": 24.1, + "totalprecip_mm": 7.56, + "totalprecip_in": 0.3, + "totalsnow_cm": 0, + "avgvis_km": 8.6, + "avgvis_miles": 5, + "avghumidity": 80, + "daily_will_it_rain": 1, + "daily_chance_of_rain": 89, + "daily_will_it_snow": 0, + "daily_chance_of_snow": 0, + "condition": { + "text": "Moderate rain", + "icon": "//cdn.weatherapi.com/weather/64x64/day/302.png", + "code": 1189 + }, + "uv": 0 + }, + "astro": { + "sunrise": "08:13 AM", + "sunset": "05:26 PM", + "moonrise": "02:17 AM", + "moonset": "02:46 PM", + "moon_phase": "Waning Crescent", + "moon_illumination": 32, + "is_moon_up": 0, + "is_sun_up": 0 + }, + "hour": [ + { + "time_epoch": 1732489200, + "time": "2024-11-25 00:00", + "temp_c": 15.5, + "temp_f": 59.8, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 13.4, + "wind_kph": 21.6, + "wind_degree": 153, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.85, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 63, + "cloud": 66, + "feelslike_c": 15.5, + "feelslike_f": 59.8, + "windchill_c": 15.5, + "windchill_f": 59.8, + "heatindex_c": 15.5, + "heatindex_f": 59.8, + "dewpoint_c": 8.5, + "dewpoint_f": 47.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.7, + "gust_kph": 39.7, + "uv": 0 + }, + { + "time_epoch": 1732492800, + "time": "2024-11-25 01:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 15, + "wind_kph": 24.1, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0.04, + "precip_in": 0, + "snow_cm": 0, + "humidity": 64, + "cloud": 56, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 8.5, + "dewpoint_f": 47.3, + "will_it_rain": 0, + "chance_of_rain": 69, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.1, + "gust_kph": 42.1, + "uv": 0 + }, + { + "time_epoch": 1732496400, + "time": "2024-11-25 02:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 14.5, + "wind_kph": 23.4, + "wind_degree": 148, + "wind_dir": "SSE", + "pressure_mb": 1010, + "pressure_in": 29.82, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 62, + "cloud": 67, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 8.1, + "dewpoint_f": 46.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.6, + "gust_kph": 42.7, + "uv": 0 + }, + { + "time_epoch": 1732500000, + "time": "2024-11-25 03:00", + "temp_c": 15.5, + "temp_f": 60, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 15, + "wind_kph": 24.1, + "wind_degree": 154, + "wind_dir": "SSE", + "pressure_mb": 1010, + "pressure_in": 29.81, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 59, + "cloud": 82, + "feelslike_c": 15.5, + "feelslike_f": 60, + "windchill_c": 15.5, + "windchill_f": 60, + "heatindex_c": 15.5, + "heatindex_f": 60, + "dewpoint_c": 7.5, + "dewpoint_f": 45.4, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.2, + "gust_kph": 42.1, + "uv": 0 + }, + { + "time_epoch": 1732503600, + "time": "2024-11-25 04:00", + "temp_c": 16.4, + "temp_f": 61.6, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 15, + "wind_kph": 24.1, + "wind_degree": 160, + "wind_dir": "SSE", + "pressure_mb": 1009, + "pressure_in": 29.79, + "precip_mm": 0.01, + "precip_in": 0, + "snow_cm": 0, + "humidity": 54, + "cloud": 85, + "feelslike_c": 16.4, + "feelslike_f": 61.6, + "windchill_c": 16.4, + "windchill_f": 61.6, + "heatindex_c": 16.4, + "heatindex_f": 61.6, + "dewpoint_c": 7, + "dewpoint_f": 44.7, + "will_it_rain": 0, + "chance_of_rain": 70, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.5, + "gust_kph": 42.7, + "uv": 0 + }, + { + "time_epoch": 1732507200, + "time": "2024-11-25 05:00", + "temp_c": 15.5, + "temp_f": 59.9, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 154, + "wind_dir": "SSE", + "pressure_mb": 1009, + "pressure_in": 29.8, + "precip_mm": 0.01, + "precip_in": 0, + "snow_cm": 0, + "humidity": 59, + "cloud": 86, + "feelslike_c": 15.5, + "feelslike_f": 59.9, + "windchill_c": 15.5, + "windchill_f": 59.9, + "heatindex_c": 15.5, + "heatindex_f": 59.9, + "dewpoint_c": 7.5, + "dewpoint_f": 45.5, + "will_it_rain": 0, + "chance_of_rain": 67, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 21.5, + "gust_kph": 34.5, + "uv": 0 + }, + { + "time_epoch": 1732510800, + "time": "2024-11-25 06:00", + "temp_c": 15.5, + "temp_f": 59.8, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 8.5, + "wind_kph": 13.7, + "wind_degree": 181, + "wind_dir": "S", + "pressure_mb": 1010, + "pressure_in": 29.83, + "precip_mm": 0.04, + "precip_in": 0, + "snow_cm": 0, + "humidity": 60, + "cloud": 85, + "feelslike_c": 15.5, + "feelslike_f": 59.8, + "windchill_c": 15.5, + "windchill_f": 59.8, + "heatindex_c": 15.5, + "heatindex_f": 59.8, + "dewpoint_c": 7.8, + "dewpoint_f": 46.1, + "will_it_rain": 0, + "chance_of_rain": 64, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 15.4, + "gust_kph": 24.8, + "uv": 0 + }, + { + "time_epoch": 1732514400, + "time": "2024-11-25 07:00", + "temp_c": 15.1, + "temp_f": 59.1, + "is_day": 0, + "condition": { + "text": "Patchy light drizzle", + "icon": "//cdn.weatherapi.com/weather/64x64/night/263.png", + "code": 1150 + }, + "wind_mph": 7.2, + "wind_kph": 11.5, + "wind_degree": 238, + "wind_dir": "WSW", + "pressure_mb": 1011, + "pressure_in": 29.84, + "precip_mm": 0.32, + "precip_in": 0.01, + "snow_cm": 0, + "humidity": 73, + "cloud": 71, + "feelslike_c": 15.1, + "feelslike_f": 59.1, + "windchill_c": 15.1, + "windchill_f": 59.1, + "heatindex_c": 15.1, + "heatindex_f": 59.1, + "dewpoint_c": 10.2, + "dewpoint_f": 50.3, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 5, + "vis_miles": 3, + "gust_mph": 12.5, + "gust_kph": 20.1, + "uv": 0 + }, + { + "time_epoch": 1732518000, + "time": "2024-11-25 08:00", + "temp_c": 13.6, + "temp_f": 56.5, + "is_day": 0, + "condition": { + "text": "Light rain", + "icon": "//cdn.weatherapi.com/weather/64x64/night/296.png", + "code": 1183 + }, + "wind_mph": 8.5, + "wind_kph": 13.7, + "wind_degree": 301, + "wind_dir": "WNW", + "pressure_mb": 1012, + "pressure_in": 29.88, + "precip_mm": 0.84, + "precip_in": 0.03, + "snow_cm": 0, + "humidity": 91, + "cloud": 100, + "feelslike_c": 12.5, + "feelslike_f": 54.5, + "windchill_c": 12.5, + "windchill_f": 54.5, + "heatindex_c": 13.6, + "heatindex_f": 56.5, + "dewpoint_c": 12.2, + "dewpoint_f": 53.9, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 9, + "vis_miles": 5, + "gust_mph": 12.6, + "gust_kph": 20.3, + "uv": 0 + }, + { + "time_epoch": 1732521600, + "time": "2024-11-25 09:00", + "temp_c": 12.4, + "temp_f": 54.3, + "is_day": 1, + "condition": { + "text": "Light drizzle", + "icon": "//cdn.weatherapi.com/weather/64x64/day/266.png", + "code": 1153 + }, + "wind_mph": 6.7, + "wind_kph": 10.8, + "wind_degree": 316, + "wind_dir": "NW", + "pressure_mb": 1013, + "pressure_in": 29.92, + "precip_mm": 0.73, + "precip_in": 0.03, + "snow_cm": 0, + "humidity": 92, + "cloud": 100, + "feelslike_c": 11.4, + "feelslike_f": 52.5, + "windchill_c": 11.4, + "windchill_f": 52.5, + "heatindex_c": 12.4, + "heatindex_f": 54.3, + "dewpoint_c": 11.1, + "dewpoint_f": 52.1, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 2, + "vis_miles": 1, + "gust_mph": 9.8, + "gust_kph": 15.7, + "uv": 0 + }, + { + "time_epoch": 1732525200, + "time": "2024-11-25 10:00", + "temp_c": 12.4, + "temp_f": 54.4, + "is_day": 1, + "condition": { + "text": "Light rain", + "icon": "//cdn.weatherapi.com/weather/64x64/day/296.png", + "code": 1183 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 290, + "wind_dir": "WNW", + "pressure_mb": 1014, + "pressure_in": 29.95, + "precip_mm": 0.89, + "precip_in": 0.04, + "snow_cm": 0, + "humidity": 92, + "cloud": 100, + "feelslike_c": 11.8, + "feelslike_f": 53.3, + "windchill_c": 11.8, + "windchill_f": 53.3, + "heatindex_c": 12.5, + "heatindex_f": 54.4, + "dewpoint_c": 11.2, + "dewpoint_f": 52.1, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 9, + "vis_miles": 5, + "gust_mph": 7.5, + "gust_kph": 12.1, + "uv": 0 + }, + { + "time_epoch": 1732528800, + "time": "2024-11-25 11:00", + "temp_c": 12.5, + "temp_f": 54.4, + "is_day": 1, + "condition": { + "text": "Light rain", + "icon": "//cdn.weatherapi.com/weather/64x64/day/296.png", + "code": 1183 + }, + "wind_mph": 6, + "wind_kph": 9.7, + "wind_degree": 311, + "wind_dir": "NW", + "pressure_mb": 1015, + "pressure_in": 29.96, + "precip_mm": 1.36, + "precip_in": 0.05, + "snow_cm": 0, + "humidity": 93, + "cloud": 100, + "feelslike_c": 11.6, + "feelslike_f": 52.9, + "windchill_c": 11.6, + "windchill_f": 52.9, + "heatindex_c": 12.5, + "heatindex_f": 54.4, + "dewpoint_c": 11.3, + "dewpoint_f": 52.3, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 9, + "vis_miles": 5, + "gust_mph": 8.6, + "gust_kph": 13.8, + "uv": 0.1 + }, + { + "time_epoch": 1732532400, + "time": "2024-11-25 12:00", + "temp_c": 11.9, + "temp_f": 53.4, + "is_day": 1, + "condition": { + "text": "Light rain", + "icon": "//cdn.weatherapi.com/weather/64x64/day/296.png", + "code": 1183 + }, + "wind_mph": 8.3, + "wind_kph": 13.3, + "wind_degree": 308, + "wind_dir": "NW", + "pressure_mb": 1016, + "pressure_in": 29.99, + "precip_mm": 2.14, + "precip_in": 0.08, + "snow_cm": 0, + "humidity": 93, + "cloud": 100, + "feelslike_c": 10.4, + "feelslike_f": 50.8, + "windchill_c": 10.4, + "windchill_f": 50.8, + "heatindex_c": 11.9, + "heatindex_f": 53.4, + "dewpoint_c": 10.8, + "dewpoint_f": 51.4, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 9, + "vis_miles": 5, + "gust_mph": 11.6, + "gust_kph": 18.6, + "uv": 0.1 + }, + { + "time_epoch": 1732536000, + "time": "2024-11-25 13:00", + "temp_c": 11.3, + "temp_f": 52.4, + "is_day": 1, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.weatherapi.com/weather/64x64/day/353.png", + "code": 1240 + }, + "wind_mph": 6.7, + "wind_kph": 10.8, + "wind_degree": 302, + "wind_dir": "WNW", + "pressure_mb": 1016, + "pressure_in": 30.01, + "precip_mm": 0.24, + "precip_in": 0.01, + "snow_cm": 0, + "humidity": 89, + "cloud": 100, + "feelslike_c": 10.1, + "feelslike_f": 50.2, + "windchill_c": 10.1, + "windchill_f": 50.2, + "heatindex_c": 11.3, + "heatindex_f": 52.4, + "dewpoint_c": 9.6, + "dewpoint_f": 49.3, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 9.5, + "gust_kph": 15.2, + "uv": 0.1 + }, + { + "time_epoch": 1732539600, + "time": "2024-11-25 14:00", + "temp_c": 11.3, + "temp_f": 52.4, + "is_day": 1, + "condition": { + "text": "Light drizzle", + "icon": "//cdn.weatherapi.com/weather/64x64/day/266.png", + "code": 1153 + }, + "wind_mph": 5.6, + "wind_kph": 9, + "wind_degree": 283, + "wind_dir": "WNW", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0.37, + "precip_in": 0.01, + "snow_cm": 0, + "humidity": 89, + "cloud": 100, + "feelslike_c": 10.4, + "feelslike_f": 50.7, + "windchill_c": 10.4, + "windchill_f": 50.7, + "heatindex_c": 11.3, + "heatindex_f": 52.4, + "dewpoint_c": 9.5, + "dewpoint_f": 49.2, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 2, + "vis_miles": 1, + "gust_mph": 8, + "gust_kph": 12.9, + "uv": 0.1 + }, + { + "time_epoch": 1732543200, + "time": "2024-11-25 15:00", + "temp_c": 11.3, + "temp_f": 52.3, + "is_day": 1, + "condition": { + "text": "Light drizzle", + "icon": "//cdn.weatherapi.com/weather/64x64/day/266.png", + "code": 1153 + }, + "wind_mph": 7.4, + "wind_kph": 11.9, + "wind_degree": 269, + "wind_dir": "W", + "pressure_mb": 1018, + "pressure_in": 30.06, + "precip_mm": 0.45, + "precip_in": 0.02, + "snow_cm": 0, + "humidity": 88, + "cloud": 100, + "feelslike_c": 9.9, + "feelslike_f": 49.7, + "windchill_c": 9.9, + "windchill_f": 49.7, + "heatindex_c": 11.3, + "heatindex_f": 52.3, + "dewpoint_c": 9.4, + "dewpoint_f": 49, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 2, + "vis_miles": 1, + "gust_mph": 11, + "gust_kph": 17.6, + "uv": 0.1 + }, + { + "time_epoch": 1732546800, + "time": "2024-11-25 16:00", + "temp_c": 11.4, + "temp_f": 52.5, + "is_day": 1, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/day/119.png", + "code": 1006 + }, + "wind_mph": 3.6, + "wind_kph": 5.8, + "wind_degree": 244, + "wind_dir": "WSW", + "pressure_mb": 1018, + "pressure_in": 30.07, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 82, + "cloud": 65, + "feelslike_c": 11.2, + "feelslike_f": 52.1, + "windchill_c": 11.2, + "windchill_f": 52.1, + "heatindex_c": 11.4, + "heatindex_f": 52.5, + "dewpoint_c": 8.4, + "dewpoint_f": 47.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 5.6, + "gust_kph": 9, + "uv": 0.1 + }, + { + "time_epoch": 1732550400, + "time": "2024-11-25 17:00", + "temp_c": 11.4, + "temp_f": 52.4, + "is_day": 1, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 191, + "wind_dir": "SSW", + "pressure_mb": 1019, + "pressure_in": 30.09, + "precip_mm": 0.02, + "precip_in": 0, + "snow_cm": 0, + "humidity": 82, + "cloud": 58, + "feelslike_c": 10.5, + "feelslike_f": 51, + "windchill_c": 10.5, + "windchill_f": 51, + "heatindex_c": 11.4, + "heatindex_f": 52.4, + "dewpoint_c": 8.4, + "dewpoint_f": 47, + "will_it_rain": 1, + "chance_of_rain": 89, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 8.4, + "gust_kph": 13.5, + "uv": 0 + }, + { + "time_epoch": 1732554000, + "time": "2024-11-25 18:00", + "temp_c": 11.1, + "temp_f": 51.9, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 5.6, + "wind_kph": 9, + "wind_degree": 207, + "wind_dir": "SSW", + "pressure_mb": 1020, + "pressure_in": 30.11, + "precip_mm": 0.02, + "precip_in": 0, + "snow_cm": 0, + "humidity": 85, + "cloud": 89, + "feelslike_c": 10.1, + "feelslike_f": 50.1, + "windchill_c": 10.1, + "windchill_f": 50.1, + "heatindex_c": 11.1, + "heatindex_f": 51.9, + "dewpoint_c": 8.6, + "dewpoint_f": 47.4, + "will_it_rain": 1, + "chance_of_rain": 76, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 9.4, + "gust_kph": 15.2, + "uv": 0 + }, + { + "time_epoch": 1732557600, + "time": "2024-11-25 19:00", + "temp_c": 10.6, + "temp_f": 51.1, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 6, + "wind_kph": 9.7, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1020, + "pressure_in": 30.13, + "precip_mm": 0.04, + "precip_in": 0, + "snow_cm": 0, + "humidity": 88, + "cloud": 88, + "feelslike_c": 9.4, + "feelslike_f": 48.9, + "windchill_c": 9.4, + "windchill_f": 48.9, + "heatindex_c": 10.6, + "heatindex_f": 51.1, + "dewpoint_c": 8.8, + "dewpoint_f": 47.8, + "will_it_rain": 1, + "chance_of_rain": 76, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 10.6, + "gust_kph": 17.1, + "uv": 0 + }, + { + "time_epoch": 1732561200, + "time": "2024-11-25 20:00", + "temp_c": 10.1, + "temp_f": 50.2, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 5.6, + "wind_kph": 9, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1021, + "pressure_in": 30.16, + "precip_mm": 0.04, + "precip_in": 0, + "snow_cm": 0, + "humidity": 92, + "cloud": 87, + "feelslike_c": 8.9, + "feelslike_f": 48.1, + "windchill_c": 8.9, + "windchill_f": 48.1, + "heatindex_c": 10.1, + "heatindex_f": 50.2, + "dewpoint_c": 8.8, + "dewpoint_f": 47.9, + "will_it_rain": 1, + "chance_of_rain": 75, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 10.5, + "gust_kph": 16.9, + "uv": 0 + }, + { + "time_epoch": 1732564800, + "time": "2024-11-25 21:00", + "temp_c": 9.8, + "temp_f": 49.6, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1022, + "pressure_in": 30.17, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 93, + "cloud": 18, + "feelslike_c": 8.7, + "feelslike_f": 47.7, + "windchill_c": 8.7, + "windchill_f": 47.7, + "heatindex_c": 9.8, + "heatindex_f": 49.6, + "dewpoint_c": 8.7, + "dewpoint_f": 47.7, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 10.2, + "gust_kph": 16.3, + "uv": 0 + }, + { + "time_epoch": 1732568400, + "time": "2024-11-25 22:00", + "temp_c": 9.6, + "temp_f": 49.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1022, + "pressure_in": 30.19, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 93, + "cloud": 24, + "feelslike_c": 8.5, + "feelslike_f": 47.4, + "windchill_c": 8.5, + "windchill_f": 47.4, + "heatindex_c": 9.6, + "heatindex_f": 49.4, + "dewpoint_c": 8.6, + "dewpoint_f": 47.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 10.2, + "gust_kph": 16.5, + "uv": 0 + }, + { + "time_epoch": 1732572000, + "time": "2024-11-25 23:00", + "temp_c": 9.5, + "temp_f": 49.1, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 4.9, + "wind_kph": 7.9, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1023, + "pressure_in": 30.2, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 93, + "cloud": 26, + "feelslike_c": 8.4, + "feelslike_f": 47.2, + "windchill_c": 8.4, + "windchill_f": 47.2, + "heatindex_c": 9.5, + "heatindex_f": 49.1, + "dewpoint_c": 8.5, + "dewpoint_f": 47.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 9.8, + "gust_kph": 15.8, + "uv": 0 + } + ] + } + ] + } +} \ No newline at end of file diff --git a/src/test/resources/WeatherAPI/Bordeaux-2-partial-sunny.json b/src/test/resources/WeatherAPI/Bordeaux-2-partial-sunny.json new file mode 100644 index 0000000..6e10f39 --- /dev/null +++ b/src/test/resources/WeatherAPI/Bordeaux-2-partial-sunny.json @@ -0,0 +1,3057 @@ +{ + "location": { + "name": "Bordeaux", + "region": "Aquitaine", + "country": "France", + "lat": 44.8333, + "lon": -0.5667, + "tz_id": "Europe/Paris", + "localtime_epoch": 1732356248, + "localtime": "2024-11-23 11:04" + }, + "current": { + "last_updated_epoch": 1732356000, + "last_updated": "2024-11-23 11:00", + "temp_c": 7.4, + "temp_f": 45.3, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.4, + "wind_kph": 18.4, + "wind_degree": 148, + "wind_dir": "SSE", + "pressure_mb": 1018, + "pressure_in": 30.06, + "precip_mm": 0, + "precip_in": 0, + "humidity": 76, + "cloud": 0, + "feelslike_c": 4.3, + "feelslike_f": 39.7, + "windchill_c": 6, + "windchill_f": 42.7, + "heatindex_c": 8.7, + "heatindex_f": 47.7, + "dewpoint_c": 1.3, + "dewpoint_f": 34.3, + "vis_km": 10, + "vis_miles": 6, + "uv": 0.9, + "gust_mph": 15.9, + "gust_kph": 25.5 + }, + "forecast": { + "forecastday": [ + { + "date": "2024-11-23", + "date_epoch": 1732320000, + "day": { + "maxtemp_c": 13.1, + "maxtemp_f": 55.7, + "mintemp_c": 4, + "mintemp_f": 39.3, + "avgtemp_c": 8.1, + "avgtemp_f": 46.6, + "maxwind_mph": 13, + "maxwind_kph": 20.9, + "totalprecip_mm": 0, + "totalprecip_in": 0, + "totalsnow_cm": 0, + "avgvis_km": 10, + "avgvis_miles": 6, + "avghumidity": 69, + "daily_will_it_rain": 0, + "daily_chance_of_rain": 0, + "daily_will_it_snow": 0, + "daily_chance_of_snow": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/day/116.png", + "code": 1003 + }, + "uv": 0.3 + }, + "astro": { + "sunrise": "08:10 AM", + "sunset": "05:27 PM", + "moonrise": "12:08 AM", + "moonset": "02:13 PM", + "moon_phase": "Last Quarter", + "moon_illumination": 51, + "is_moon_up": 0, + "is_sun_up": 0 + }, + "hour": [ + { + "time_epoch": 1732316400, + "time": "2024-11-23 00:00", + "temp_c": 5.6, + "temp_f": 42, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 6.7, + "wind_kph": 10.8, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1022, + "pressure_in": 30.19, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 81, + "cloud": 17, + "feelslike_c": 3.2, + "feelslike_f": 37.7, + "windchill_c": 3.2, + "windchill_f": 37.7, + "heatindex_c": 5.6, + "heatindex_f": 42, + "dewpoint_c": 2.6, + "dewpoint_f": 36.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 13.7, + "gust_kph": 22, + "uv": 0 + }, + { + "time_epoch": 1732320000, + "time": "2024-11-23 01:00", + "temp_c": 5.8, + "temp_f": 42.4, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 6.9, + "wind_kph": 11.2, + "wind_degree": 141, + "wind_dir": "SE", + "pressure_mb": 1022, + "pressure_in": 30.17, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 80, + "cloud": 47, + "feelslike_c": 3.3, + "feelslike_f": 38, + "windchill_c": 3.3, + "windchill_f": 38, + "heatindex_c": 5.8, + "heatindex_f": 42.4, + "dewpoint_c": 2.5, + "dewpoint_f": 36.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 13.4, + "gust_kph": 21.6, + "uv": 0 + }, + { + "time_epoch": 1732323600, + "time": "2024-11-23 02:00", + "temp_c": 5.6, + "temp_f": 42.1, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 8.3, + "wind_kph": 13.3, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1021, + "pressure_in": 30.14, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 79, + "cloud": 56, + "feelslike_c": 2.8, + "feelslike_f": 37, + "windchill_c": 2.8, + "windchill_f": 37, + "heatindex_c": 5.6, + "heatindex_f": 42.1, + "dewpoint_c": 2.3, + "dewpoint_f": 36.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 15.3, + "gust_kph": 24.7, + "uv": 0 + }, + { + "time_epoch": 1732327200, + "time": "2024-11-23 03:00", + "temp_c": 5.1, + "temp_f": 41.3, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 9.8, + "wind_kph": 15.8, + "wind_degree": 133, + "wind_dir": "SE", + "pressure_mb": 1020, + "pressure_in": 30.13, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 79, + "cloud": 86, + "feelslike_c": 1.8, + "feelslike_f": 35.3, + "windchill_c": 1.8, + "windchill_f": 35.3, + "heatindex_c": 5.2, + "heatindex_f": 41.3, + "dewpoint_c": 1.9, + "dewpoint_f": 35.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 17.6, + "gust_kph": 28.4, + "uv": 0 + }, + { + "time_epoch": 1732330800, + "time": "2024-11-23 04:00", + "temp_c": 4.8, + "temp_f": 40.7, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 10.5, + "wind_kph": 16.9, + "wind_degree": 130, + "wind_dir": "SE", + "pressure_mb": 1020, + "pressure_in": 30.12, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 79, + "cloud": 44, + "feelslike_c": 1.3, + "feelslike_f": 34.3, + "windchill_c": 1.3, + "windchill_f": 34.3, + "heatindex_c": 4.9, + "heatindex_f": 40.7, + "dewpoint_c": 1.5, + "dewpoint_f": 34.7, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 18.1, + "gust_kph": 29.1, + "uv": 0 + }, + { + "time_epoch": 1732334400, + "time": "2024-11-23 05:00", + "temp_c": 4.3, + "temp_f": 39.7, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11, + "wind_kph": 17.6, + "wind_degree": 130, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.1, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 80, + "cloud": 46, + "feelslike_c": 0.5, + "feelslike_f": 32.8, + "windchill_c": 0.5, + "windchill_f": 32.8, + "heatindex_c": 4.3, + "heatindex_f": 39.7, + "dewpoint_c": 1.2, + "dewpoint_f": 34.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19.1, + "gust_kph": 30.8, + "uv": 0 + }, + { + "time_epoch": 1732338000, + "time": "2024-11-23 06:00", + "temp_c": 4, + "temp_f": 39.3, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.08, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 80, + "cloud": 39, + "feelslike_c": 0.1, + "feelslike_f": 32.2, + "windchill_c": 0.1, + "windchill_f": 32.2, + "heatindex_c": 4, + "heatindex_f": 39.3, + "dewpoint_c": 0.9, + "dewpoint_f": 33.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19.8, + "gust_kph": 31.8, + "uv": 0 + }, + { + "time_epoch": 1732341600, + "time": "2024-11-23 07:00", + "temp_c": 4, + "temp_f": 39.3, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.08, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 78, + "cloud": 26, + "feelslike_c": 0.1, + "feelslike_f": 32.2, + "windchill_c": 0.1, + "windchill_f": 32.2, + "heatindex_c": 4, + "heatindex_f": 39.3, + "dewpoint_c": 0.6, + "dewpoint_f": 33, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19.9, + "gust_kph": 32, + "uv": 0 + }, + { + "time_epoch": 1732345200, + "time": "2024-11-23 08:00", + "temp_c": 4.1, + "temp_f": 39.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 10.5, + "wind_kph": 16.9, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.09, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 75, + "cloud": 7, + "feelslike_c": 0.4, + "feelslike_f": 32.6, + "windchill_c": 0.4, + "windchill_f": 32.6, + "heatindex_c": 4.1, + "heatindex_f": 39.4, + "dewpoint_c": 0.1, + "dewpoint_f": 32.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 18.8, + "gust_kph": 30.2, + "uv": 0 + }, + { + "time_epoch": 1732348800, + "time": "2024-11-23 09:00", + "temp_c": 4.6, + "temp_f": 40.3, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 10.7, + "wind_kph": 17.3, + "wind_degree": 143, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.09, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 71, + "cloud": 13, + "feelslike_c": 1, + "feelslike_f": 33.7, + "windchill_c": 1, + "windchill_f": 33.7, + "heatindex_c": 4.6, + "heatindex_f": 40.4, + "dewpoint_c": -0.2, + "dewpoint_f": 31.7, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19, + "gust_kph": 30.5, + "uv": 0 + }, + { + "time_epoch": 1732352400, + "time": "2024-11-23 10:00", + "temp_c": 6.6, + "temp_f": 43.9, + "is_day": 1, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/day/116.png", + "code": 1003 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 146, + "wind_dir": "SSE", + "pressure_mb": 1019, + "pressure_in": 30.08, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 63, + "cloud": 49, + "feelslike_c": 3.4, + "feelslike_f": 38, + "windchill_c": 3.4, + "windchill_f": 38, + "heatindex_c": 6.6, + "heatindex_f": 43.9, + "dewpoint_c": 0.2, + "dewpoint_f": 32.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 17.5, + "gust_kph": 28.2, + "uv": 0.4 + }, + { + "time_epoch": 1732356000, + "time": "2024-11-23 11:00", + "temp_c": 7.4, + "temp_f": 45.3, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.4, + "wind_kph": 18.4, + "wind_degree": 148, + "wind_dir": "SSE", + "pressure_mb": 1018, + "pressure_in": 30.06, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 76, + "cloud": 0, + "feelslike_c": 6, + "feelslike_f": 42.7, + "windchill_c": 6, + "windchill_f": 42.7, + "heatindex_c": 8.7, + "heatindex_f": 47.7, + "dewpoint_c": 1.3, + "dewpoint_f": 34.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 15.9, + "gust_kph": 25.5, + "uv": 0.9 + }, + { + "time_epoch": 1732359600, + "time": "2024-11-23 12:00", + "temp_c": 10.4, + "temp_f": 50.8, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11, + "wind_kph": 17.6, + "wind_degree": 149, + "wind_dir": "SSE", + "pressure_mb": 1018, + "pressure_in": 30.07, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 56, + "cloud": 21, + "feelslike_c": 8.2, + "feelslike_f": 46.7, + "windchill_c": 8.2, + "windchill_f": 46.7, + "heatindex_c": 10.5, + "heatindex_f": 50.8, + "dewpoint_c": 2.2, + "dewpoint_f": 35.9, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 14.7, + "gust_kph": 23.6, + "uv": 1.3 + }, + { + "time_epoch": 1732363200, + "time": "2024-11-23 13:00", + "temp_c": 12.3, + "temp_f": 54.2, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.4, + "wind_kph": 18.4, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1017, + "pressure_in": 30.04, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 52, + "cloud": 22, + "feelslike_c": 10.5, + "feelslike_f": 50.8, + "windchill_c": 10.5, + "windchill_f": 50.8, + "heatindex_c": 12.3, + "heatindex_f": 54.2, + "dewpoint_c": 2.8, + "dewpoint_f": 37, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 14.9, + "gust_kph": 23.9, + "uv": 1.6 + }, + { + "time_epoch": 1732366800, + "time": "2024-11-23 14:00", + "temp_c": 13, + "temp_f": 55.4, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 10.3, + "wind_kph": 16.6, + "wind_degree": 149, + "wind_dir": "SSE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 54, + "cloud": 12, + "feelslike_c": 11.5, + "feelslike_f": 52.7, + "windchill_c": 11.5, + "windchill_f": 52.7, + "heatindex_c": 13, + "heatindex_f": 55.4, + "dewpoint_c": 3.8, + "dewpoint_f": 38.9, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 14, + "gust_kph": 22.6, + "uv": 1.4 + }, + { + "time_epoch": 1732370400, + "time": "2024-11-23 15:00", + "temp_c": 13.1, + "temp_f": 55.7, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.4, + "wind_kph": 18.4, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1016, + "pressure_in": 30.01, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 54, + "cloud": 22, + "feelslike_c": 11.5, + "feelslike_f": 52.7, + "windchill_c": 11.5, + "windchill_f": 52.7, + "heatindex_c": 13.2, + "heatindex_f": 55.7, + "dewpoint_c": 4.2, + "dewpoint_f": 39.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 16.8, + "gust_kph": 27.1, + "uv": 0.9 + }, + { + "time_epoch": 1732374000, + "time": "2024-11-23 16:00", + "temp_c": 12.5, + "temp_f": 54.4, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 10.7, + "wind_kph": 17.3, + "wind_degree": 148, + "wind_dir": "SSE", + "pressure_mb": 1017, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 57, + "cloud": 14, + "feelslike_c": 10.7, + "feelslike_f": 51.3, + "windchill_c": 10.7, + "windchill_f": 51.3, + "heatindex_c": 12.5, + "heatindex_f": 54.4, + "dewpoint_c": 4.1, + "dewpoint_f": 39.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 17.5, + "gust_kph": 28.1, + "uv": 0.4 + }, + { + "time_epoch": 1732377600, + "time": "2024-11-23 17:00", + "temp_c": 11.2, + "temp_f": 52.1, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 141, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 61, + "cloud": 22, + "feelslike_c": 9, + "feelslike_f": 48.2, + "windchill_c": 9, + "windchill_f": 48.2, + "heatindex_c": 11.2, + "heatindex_f": 52.1, + "dewpoint_c": 4, + "dewpoint_f": 39.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 20.2, + "gust_kph": 32.5, + "uv": 0 + }, + { + "time_epoch": 1732381200, + "time": "2024-11-23 18:00", + "temp_c": 10.2, + "temp_f": 50.4, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11.6, + "wind_kph": 18.7, + "wind_degree": 141, + "wind_dir": "SE", + "pressure_mb": 1016, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 64, + "cloud": 47, + "feelslike_c": 7.8, + "feelslike_f": 46, + "windchill_c": 7.8, + "windchill_f": 46, + "heatindex_c": 10.2, + "heatindex_f": 50.4, + "dewpoint_c": 3.8, + "dewpoint_f": 38.9, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.2, + "gust_kph": 35.7, + "uv": 0 + }, + { + "time_epoch": 1732384800, + "time": "2024-11-23 19:00", + "temp_c": 10, + "temp_f": 50.1, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.3, + "wind_kph": 19.8, + "wind_degree": 144, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 66, + "cloud": 62, + "feelslike_c": 7.5, + "feelslike_f": 45.4, + "windchill_c": 7.5, + "windchill_f": 45.4, + "heatindex_c": 10, + "heatindex_f": 50.1, + "dewpoint_c": 4, + "dewpoint_f": 39.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.8, + "gust_kph": 36.8, + "uv": 0 + }, + { + "time_epoch": 1732388400, + "time": "2024-11-23 20:00", + "temp_c": 10, + "temp_f": 50, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 143, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 68, + "cloud": 57, + "feelslike_c": 7.3, + "feelslike_f": 45.2, + "windchill_c": 7.3, + "windchill_f": 45.2, + "heatindex_c": 10, + "heatindex_f": 50, + "dewpoint_c": 4.3, + "dewpoint_f": 39.8, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.6, + "gust_kph": 36.3, + "uv": 0 + }, + { + "time_epoch": 1732392000, + "time": "2024-11-23 21:00", + "temp_c": 9.7, + "temp_f": 49.5, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 142, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 71, + "cloud": 46, + "feelslike_c": 7, + "feelslike_f": 44.6, + "windchill_c": 7, + "windchill_f": 44.6, + "heatindex_c": 9.7, + "heatindex_f": 49.5, + "dewpoint_c": 4.6, + "dewpoint_f": 40.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.3, + "gust_kph": 35.9, + "uv": 0 + }, + { + "time_epoch": 1732395600, + "time": "2024-11-23 22:00", + "temp_c": 9.5, + "temp_f": 49.1, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13, + "wind_kph": 20.9, + "wind_degree": 139, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 73, + "cloud": 24, + "feelslike_c": 6.6, + "feelslike_f": 44, + "windchill_c": 6.6, + "windchill_f": 44, + "heatindex_c": 9.5, + "heatindex_f": 49.1, + "dewpoint_c": 5, + "dewpoint_f": 41, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23, + "gust_kph": 37, + "uv": 0 + }, + { + "time_epoch": 1732399200, + "time": "2024-11-23 23:00", + "temp_c": 9.3, + "temp_f": 48.8, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 12.8, + "wind_kph": 20.5, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 76, + "cloud": 21, + "feelslike_c": 6.5, + "feelslike_f": 43.7, + "windchill_c": 6.5, + "windchill_f": 43.7, + "heatindex_c": 9.3, + "heatindex_f": 48.8, + "dewpoint_c": 5.3, + "dewpoint_f": 41.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23, + "gust_kph": 37, + "uv": 0 + } + ] + }, + { + "date": "2024-11-24", + "date_epoch": 1732406400, + "day": { + "maxtemp_c": 17.2, + "maxtemp_f": 63, + "mintemp_c": 9.3, + "mintemp_f": 48.8, + "avgtemp_c": 13, + "avgtemp_f": 55.3, + "maxwind_mph": 16.3, + "maxwind_kph": 26.3, + "totalprecip_mm": 0, + "totalprecip_in": 0, + "totalsnow_cm": 0, + "avgvis_km": 10, + "avgvis_miles": 6, + "avghumidity": 70, + "daily_will_it_rain": 0, + "daily_chance_of_rain": 0, + "daily_will_it_snow": 0, + "daily_chance_of_snow": 0, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "uv": 0.3 + }, + "astro": { + "sunrise": "08:12 AM", + "sunset": "05:26 PM", + "moonrise": "01:14 AM", + "moonset": "02:30 PM", + "moon_phase": "Waning Crescent", + "moon_illumination": 41, + "is_moon_up": 0, + "is_sun_up": 0 + }, + "hour": [ + { + "time_epoch": 1732402800, + "time": "2024-11-24 00:00", + "temp_c": 9.3, + "temp_f": 48.8, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 77, + "cloud": 41, + "feelslike_c": 6.5, + "feelslike_f": 43.8, + "windchill_c": 6.5, + "windchill_f": 43.8, + "heatindex_c": 9.3, + "heatindex_f": 48.8, + "dewpoint_c": 5.6, + "dewpoint_f": 42, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.1, + "gust_kph": 37.2, + "uv": 0 + }, + { + "time_epoch": 1732406400, + "time": "2024-11-24 01:00", + "temp_c": 9.5, + "temp_f": 49.1, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 139, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 77, + "cloud": 33, + "feelslike_c": 6.7, + "feelslike_f": 44.1, + "windchill_c": 6.7, + "windchill_f": 44.1, + "heatindex_c": 9.5, + "heatindex_f": 49.1, + "dewpoint_c": 5.7, + "dewpoint_f": 42.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.4, + "gust_kph": 37.7, + "uv": 0 + }, + { + "time_epoch": 1732410000, + "time": "2024-11-24 02:00", + "temp_c": 9.7, + "temp_f": 49.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 12.3, + "wind_kph": 19.8, + "wind_degree": 139, + "wind_dir": "SE", + "pressure_mb": 1016, + "pressure_in": 30, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 77, + "cloud": 22, + "feelslike_c": 7, + "feelslike_f": 44.5, + "windchill_c": 7, + "windchill_f": 44.5, + "heatindex_c": 9.7, + "heatindex_f": 49.4, + "dewpoint_c": 5.8, + "dewpoint_f": 42.4, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.2, + "gust_kph": 37.3, + "uv": 0 + }, + { + "time_epoch": 1732413600, + "time": "2024-11-24 03:00", + "temp_c": 9.7, + "temp_f": 49.5, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 12.8, + "wind_kph": 20.5, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1016, + "pressure_in": 30, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 76, + "cloud": 14, + "feelslike_c": 7, + "feelslike_f": 44.6, + "windchill_c": 7, + "windchill_f": 44.6, + "heatindex_c": 9.7, + "heatindex_f": 49.5, + "dewpoint_c": 5.7, + "dewpoint_f": 42.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.3, + "gust_kph": 39.2, + "uv": 0 + }, + { + "time_epoch": 1732417200, + "time": "2024-11-24 04:00", + "temp_c": 9.8, + "temp_f": 49.6, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13, + "wind_kph": 20.9, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 75, + "cloud": 10, + "feelslike_c": 7, + "feelslike_f": 44.6, + "windchill_c": 7, + "windchill_f": 44.6, + "heatindex_c": 9.8, + "heatindex_f": 49.6, + "dewpoint_c": 5.7, + "dewpoint_f": 42.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.6, + "gust_kph": 39.6, + "uv": 0 + }, + { + "time_epoch": 1732420800, + "time": "2024-11-24 05:00", + "temp_c": 9.7, + "temp_f": 49.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13.4, + "wind_kph": 21.6, + "wind_degree": 136, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 76, + "cloud": 10, + "feelslike_c": 6.8, + "feelslike_f": 44.3, + "windchill_c": 6.8, + "windchill_f": 44.3, + "heatindex_c": 9.7, + "heatindex_f": 49.4, + "dewpoint_c": 5.7, + "dewpoint_f": 42.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25.3, + "gust_kph": 40.7, + "uv": 0 + }, + { + "time_epoch": 1732424400, + "time": "2024-11-24 06:00", + "temp_c": 9.7, + "temp_f": 49.5, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13.6, + "wind_kph": 22, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 77, + "cloud": 11, + "feelslike_c": 6.8, + "feelslike_f": 44.3, + "windchill_c": 6.8, + "windchill_f": 44.3, + "heatindex_c": 9.7, + "heatindex_f": 49.5, + "dewpoint_c": 5.8, + "dewpoint_f": 42.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25.7, + "gust_kph": 41.4, + "uv": 0 + }, + { + "time_epoch": 1732428000, + "time": "2024-11-24 07:00", + "temp_c": 9.7, + "temp_f": 49.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13.6, + "wind_kph": 22, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.97, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 78, + "cloud": 8, + "feelslike_c": 6.8, + "feelslike_f": 44.2, + "windchill_c": 6.8, + "windchill_f": 44.2, + "heatindex_c": 9.7, + "heatindex_f": 49.4, + "dewpoint_c": 6, + "dewpoint_f": 42.7, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25.5, + "gust_kph": 41, + "uv": 0 + }, + { + "time_epoch": 1732431600, + "time": "2024-11-24 08:00", + "temp_c": 9.7, + "temp_f": 49.5, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13.2, + "wind_kph": 21.2, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 78, + "cloud": 7, + "feelslike_c": 6.9, + "feelslike_f": 44.4, + "windchill_c": 6.9, + "windchill_f": 44.4, + "heatindex_c": 9.7, + "heatindex_f": 49.5, + "dewpoint_c": 6.1, + "dewpoint_f": 43, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.8, + "gust_kph": 40, + "uv": 0 + }, + { + "time_epoch": 1732435200, + "time": "2024-11-24 09:00", + "temp_c": 10.1, + "temp_f": 50.1, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 13.6, + "wind_kph": 22, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 78, + "cloud": 7, + "feelslike_c": 7.3, + "feelslike_f": 45.1, + "windchill_c": 7.3, + "windchill_f": 45.1, + "heatindex_c": 10.1, + "heatindex_f": 50.1, + "dewpoint_c": 6.4, + "dewpoint_f": 43.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.5, + "gust_kph": 39.5, + "uv": 0 + }, + { + "time_epoch": 1732438800, + "time": "2024-11-24 10:00", + "temp_c": 11.4, + "temp_f": 52.5, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 14.5, + "wind_kph": 23.4, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.97, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 74, + "cloud": 5, + "feelslike_c": 8.9, + "feelslike_f": 47.9, + "windchill_c": 8.9, + "windchill_f": 47.9, + "heatindex_c": 11.4, + "heatindex_f": 52.5, + "dewpoint_c": 7, + "dewpoint_f": 44.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.2, + "gust_kph": 37.3, + "uv": 0.4 + }, + { + "time_epoch": 1732442400, + "time": "2024-11-24 11:00", + "temp_c": 13.2, + "temp_f": 55.7, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 15.7, + "wind_kph": 25.2, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.96, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 70, + "cloud": 4, + "feelslike_c": 11, + "feelslike_f": 51.8, + "windchill_c": 11, + "windchill_f": 51.8, + "heatindex_c": 13.2, + "heatindex_f": 55.7, + "dewpoint_c": 7.8, + "dewpoint_f": 46, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.5, + "gust_kph": 36.3, + "uv": 0.8 + }, + { + "time_epoch": 1732446000, + "time": "2024-11-24 12:00", + "temp_c": 15, + "temp_f": 58.9, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 16.1, + "wind_kph": 25.9, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1014, + "pressure_in": 29.95, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 65, + "cloud": 4, + "feelslike_c": 13.3, + "feelslike_f": 55.9, + "windchill_c": 13.3, + "windchill_f": 55.9, + "heatindex_c": 15, + "heatindex_f": 58.9, + "dewpoint_c": 8.4, + "dewpoint_f": 47.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 21.9, + "gust_kph": 35.2, + "uv": 1.3 + }, + { + "time_epoch": 1732449600, + "time": "2024-11-24 13:00", + "temp_c": 16.4, + "temp_f": 61.6, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 16.1, + "wind_kph": 25.9, + "wind_degree": 142, + "wind_dir": "SE", + "pressure_mb": 1013, + "pressure_in": 29.91, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 60, + "cloud": 5, + "feelslike_c": 16.4, + "feelslike_f": 61.6, + "windchill_c": 16.4, + "windchill_f": 61.6, + "heatindex_c": 16.4, + "heatindex_f": 61.6, + "dewpoint_c": 8.8, + "dewpoint_f": 47.8, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 21.6, + "gust_kph": 34.7, + "uv": 1.4 + }, + { + "time_epoch": 1732453200, + "time": "2024-11-24 14:00", + "temp_c": 17.2, + "temp_f": 62.9, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 16.3, + "wind_kph": 26.3, + "wind_degree": 143, + "wind_dir": "SE", + "pressure_mb": 1012, + "pressure_in": 29.89, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 59, + "cloud": 4, + "feelslike_c": 17.2, + "feelslike_f": 62.9, + "windchill_c": 17.2, + "windchill_f": 62.9, + "heatindex_c": 17.2, + "heatindex_f": 62.9, + "dewpoint_c": 9, + "dewpoint_f": 48.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.9, + "gust_kph": 36.8, + "uv": 1.3 + }, + { + "time_epoch": 1732456800, + "time": "2024-11-24 15:00", + "temp_c": 17.2, + "temp_f": 63, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 16.3, + "wind_kph": 26.3, + "wind_degree": 145, + "wind_dir": "SE", + "pressure_mb": 1012, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 59, + "cloud": 1, + "feelslike_c": 17.2, + "feelslike_f": 63, + "windchill_c": 17.2, + "windchill_f": 63, + "heatindex_c": 17.2, + "heatindex_f": 63, + "dewpoint_c": 9.2, + "dewpoint_f": 48.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25, + "gust_kph": 40.2, + "uv": 0.8 + }, + { + "time_epoch": 1732460400, + "time": "2024-11-24 16:00", + "temp_c": 16.6, + "temp_f": 61.9, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 15.7, + "wind_kph": 25.2, + "wind_degree": 147, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 61, + "cloud": 3, + "feelslike_c": 16.6, + "feelslike_f": 61.9, + "windchill_c": 16.6, + "windchill_f": 61.9, + "heatindex_c": 16.6, + "heatindex_f": 61.9, + "dewpoint_c": 9.2, + "dewpoint_f": 48.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25.9, + "gust_kph": 41.7, + "uv": 0.4 + }, + { + "time_epoch": 1732464000, + "time": "2024-11-24 17:00", + "temp_c": 15.7, + "temp_f": 60.3, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 15.4, + "wind_kph": 24.8, + "wind_degree": 147, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 65, + "cloud": 22, + "feelslike_c": 15.7, + "feelslike_f": 60.3, + "windchill_c": 15.7, + "windchill_f": 60.3, + "heatindex_c": 15.7, + "heatindex_f": 60.3, + "dewpoint_c": 9.1, + "dewpoint_f": 48.4, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 27, + "gust_kph": 43.5, + "uv": 0 + }, + { + "time_epoch": 1732467600, + "time": "2024-11-24 18:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 15.4, + "wind_kph": 24.8, + "wind_degree": 149, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 66, + "cloud": 15, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 9.1, + "dewpoint_f": 48.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 27.8, + "gust_kph": 44.8, + "uv": 0 + }, + { + "time_epoch": 1732471200, + "time": "2024-11-24 19:00", + "temp_c": 15.2, + "temp_f": 59.4, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 15.7, + "wind_kph": 25.2, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 67, + "cloud": 47, + "feelslike_c": 15.2, + "feelslike_f": 59.4, + "windchill_c": 15.2, + "windchill_f": 59.4, + "heatindex_c": 15.2, + "heatindex_f": 59.4, + "dewpoint_c": 9.1, + "dewpoint_f": 48.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 28.4, + "gust_kph": 45.7, + "uv": 0 + }, + { + "time_epoch": 1732474800, + "time": "2024-11-24 20:00", + "temp_c": 15.2, + "temp_f": 59.4, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 14.8, + "wind_kph": 23.8, + "wind_degree": 149, + "wind_dir": "SSE", + "pressure_mb": 1012, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 67, + "cloud": 56, + "feelslike_c": 15.2, + "feelslike_f": 59.4, + "windchill_c": 15.2, + "windchill_f": 59.4, + "heatindex_c": 15.2, + "heatindex_f": 59.4, + "dewpoint_c": 9.2, + "dewpoint_f": 48.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.5, + "gust_kph": 42.6, + "uv": 0 + }, + { + "time_epoch": 1732478400, + "time": "2024-11-24 21:00", + "temp_c": 15.4, + "temp_f": 59.7, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 14.3, + "wind_kph": 23, + "wind_degree": 151, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 67, + "cloud": 49, + "feelslike_c": 15.4, + "feelslike_f": 59.7, + "windchill_c": 15.4, + "windchill_f": 59.7, + "heatindex_c": 15.4, + "heatindex_f": 59.7, + "dewpoint_c": 9.3, + "dewpoint_f": 48.8, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.7, + "gust_kph": 39.8, + "uv": 0 + }, + { + "time_epoch": 1732482000, + "time": "2024-11-24 22:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 13, + "wind_kph": 20.9, + "wind_degree": 155, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 67, + "cloud": 47, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 9.2, + "dewpoint_f": 48.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.7, + "gust_kph": 36.5, + "uv": 0 + }, + { + "time_epoch": 1732485600, + "time": "2024-11-24 23:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 13.4, + "wind_kph": 21.6, + "wind_degree": 151, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 65, + "cloud": 66, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 8.8, + "dewpoint_f": 47.9, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.8, + "gust_kph": 38.3, + "uv": 0 + } + ] + }, + { + "date": "2024-11-25", + "date_epoch": 1732492800, + "day": { + "maxtemp_c": 15.5, + "maxtemp_f": 59.8, + "mintemp_c": 9.5, + "mintemp_f": 49.1, + "avgtemp_c": 12.7, + "avgtemp_f": 54.8, + "maxwind_mph": 15, + "maxwind_kph": 24.1, + "totalprecip_mm": 7.56, + "totalprecip_in": 0.3, + "totalsnow_cm": 0, + "avgvis_km": 8.6, + "avgvis_miles": 5, + "avghumidity": 80, + "daily_will_it_rain": 1, + "daily_chance_of_rain": 89, + "daily_will_it_snow": 0, + "daily_chance_of_snow": 0, + "condition": { + "text": "Moderate rain", + "icon": "//cdn.weatherapi.com/weather/64x64/day/302.png", + "code": 1189 + }, + "uv": 0 + }, + "astro": { + "sunrise": "08:13 AM", + "sunset": "05:26 PM", + "moonrise": "02:17 AM", + "moonset": "02:46 PM", + "moon_phase": "Waning Crescent", + "moon_illumination": 32, + "is_moon_up": 0, + "is_sun_up": 0 + }, + "hour": [ + { + "time_epoch": 1732489200, + "time": "2024-11-25 00:00", + "temp_c": 15.5, + "temp_f": 59.8, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 13.4, + "wind_kph": 21.6, + "wind_degree": 153, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.85, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 63, + "cloud": 66, + "feelslike_c": 15.5, + "feelslike_f": 59.8, + "windchill_c": 15.5, + "windchill_f": 59.8, + "heatindex_c": 15.5, + "heatindex_f": 59.8, + "dewpoint_c": 8.5, + "dewpoint_f": 47.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.7, + "gust_kph": 39.7, + "uv": 0 + }, + { + "time_epoch": 1732492800, + "time": "2024-11-25 01:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 15, + "wind_kph": 24.1, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0.04, + "precip_in": 0, + "snow_cm": 0, + "humidity": 64, + "cloud": 56, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 8.5, + "dewpoint_f": 47.3, + "will_it_rain": 0, + "chance_of_rain": 69, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.1, + "gust_kph": 42.1, + "uv": 0 + }, + { + "time_epoch": 1732496400, + "time": "2024-11-25 02:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 14.5, + "wind_kph": 23.4, + "wind_degree": 148, + "wind_dir": "SSE", + "pressure_mb": 1010, + "pressure_in": 29.82, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 62, + "cloud": 67, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 8.1, + "dewpoint_f": 46.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.6, + "gust_kph": 42.7, + "uv": 0 + }, + { + "time_epoch": 1732500000, + "time": "2024-11-25 03:00", + "temp_c": 15.5, + "temp_f": 60, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 15, + "wind_kph": 24.1, + "wind_degree": 154, + "wind_dir": "SSE", + "pressure_mb": 1010, + "pressure_in": 29.81, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 59, + "cloud": 82, + "feelslike_c": 15.5, + "feelslike_f": 60, + "windchill_c": 15.5, + "windchill_f": 60, + "heatindex_c": 15.5, + "heatindex_f": 60, + "dewpoint_c": 7.5, + "dewpoint_f": 45.4, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.2, + "gust_kph": 42.1, + "uv": 0 + }, + { + "time_epoch": 1732503600, + "time": "2024-11-25 04:00", + "temp_c": 16.4, + "temp_f": 61.6, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 15, + "wind_kph": 24.1, + "wind_degree": 160, + "wind_dir": "SSE", + "pressure_mb": 1009, + "pressure_in": 29.79, + "precip_mm": 0.01, + "precip_in": 0, + "snow_cm": 0, + "humidity": 54, + "cloud": 85, + "feelslike_c": 16.4, + "feelslike_f": 61.6, + "windchill_c": 16.4, + "windchill_f": 61.6, + "heatindex_c": 16.4, + "heatindex_f": 61.6, + "dewpoint_c": 7, + "dewpoint_f": 44.7, + "will_it_rain": 0, + "chance_of_rain": 70, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.5, + "gust_kph": 42.7, + "uv": 0 + }, + { + "time_epoch": 1732507200, + "time": "2024-11-25 05:00", + "temp_c": 15.5, + "temp_f": 59.9, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 154, + "wind_dir": "SSE", + "pressure_mb": 1009, + "pressure_in": 29.8, + "precip_mm": 0.01, + "precip_in": 0, + "snow_cm": 0, + "humidity": 59, + "cloud": 86, + "feelslike_c": 15.5, + "feelslike_f": 59.9, + "windchill_c": 15.5, + "windchill_f": 59.9, + "heatindex_c": 15.5, + "heatindex_f": 59.9, + "dewpoint_c": 7.5, + "dewpoint_f": 45.5, + "will_it_rain": 0, + "chance_of_rain": 67, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 21.5, + "gust_kph": 34.5, + "uv": 0 + }, + { + "time_epoch": 1732510800, + "time": "2024-11-25 06:00", + "temp_c": 15.5, + "temp_f": 59.8, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 8.5, + "wind_kph": 13.7, + "wind_degree": 181, + "wind_dir": "S", + "pressure_mb": 1010, + "pressure_in": 29.83, + "precip_mm": 0.04, + "precip_in": 0, + "snow_cm": 0, + "humidity": 60, + "cloud": 85, + "feelslike_c": 15.5, + "feelslike_f": 59.8, + "windchill_c": 15.5, + "windchill_f": 59.8, + "heatindex_c": 15.5, + "heatindex_f": 59.8, + "dewpoint_c": 7.8, + "dewpoint_f": 46.1, + "will_it_rain": 0, + "chance_of_rain": 64, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 15.4, + "gust_kph": 24.8, + "uv": 0 + }, + { + "time_epoch": 1732514400, + "time": "2024-11-25 07:00", + "temp_c": 15.1, + "temp_f": 59.1, + "is_day": 0, + "condition": { + "text": "Patchy light drizzle", + "icon": "//cdn.weatherapi.com/weather/64x64/night/263.png", + "code": 1150 + }, + "wind_mph": 7.2, + "wind_kph": 11.5, + "wind_degree": 238, + "wind_dir": "WSW", + "pressure_mb": 1011, + "pressure_in": 29.84, + "precip_mm": 0.32, + "precip_in": 0.01, + "snow_cm": 0, + "humidity": 73, + "cloud": 71, + "feelslike_c": 15.1, + "feelslike_f": 59.1, + "windchill_c": 15.1, + "windchill_f": 59.1, + "heatindex_c": 15.1, + "heatindex_f": 59.1, + "dewpoint_c": 10.2, + "dewpoint_f": 50.3, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 5, + "vis_miles": 3, + "gust_mph": 12.5, + "gust_kph": 20.1, + "uv": 0 + }, + { + "time_epoch": 1732518000, + "time": "2024-11-25 08:00", + "temp_c": 13.6, + "temp_f": 56.5, + "is_day": 0, + "condition": { + "text": "Light rain", + "icon": "//cdn.weatherapi.com/weather/64x64/night/296.png", + "code": 1183 + }, + "wind_mph": 8.5, + "wind_kph": 13.7, + "wind_degree": 301, + "wind_dir": "WNW", + "pressure_mb": 1012, + "pressure_in": 29.88, + "precip_mm": 0.84, + "precip_in": 0.03, + "snow_cm": 0, + "humidity": 91, + "cloud": 100, + "feelslike_c": 12.5, + "feelslike_f": 54.5, + "windchill_c": 12.5, + "windchill_f": 54.5, + "heatindex_c": 13.6, + "heatindex_f": 56.5, + "dewpoint_c": 12.2, + "dewpoint_f": 53.9, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 9, + "vis_miles": 5, + "gust_mph": 12.6, + "gust_kph": 20.3, + "uv": 0 + }, + { + "time_epoch": 1732521600, + "time": "2024-11-25 09:00", + "temp_c": 12.4, + "temp_f": 54.3, + "is_day": 1, + "condition": { + "text": "Light drizzle", + "icon": "//cdn.weatherapi.com/weather/64x64/day/266.png", + "code": 1153 + }, + "wind_mph": 6.7, + "wind_kph": 10.8, + "wind_degree": 316, + "wind_dir": "NW", + "pressure_mb": 1013, + "pressure_in": 29.92, + "precip_mm": 0.73, + "precip_in": 0.03, + "snow_cm": 0, + "humidity": 92, + "cloud": 100, + "feelslike_c": 11.4, + "feelslike_f": 52.5, + "windchill_c": 11.4, + "windchill_f": 52.5, + "heatindex_c": 12.4, + "heatindex_f": 54.3, + "dewpoint_c": 11.1, + "dewpoint_f": 52.1, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 2, + "vis_miles": 1, + "gust_mph": 9.8, + "gust_kph": 15.7, + "uv": 0 + }, + { + "time_epoch": 1732525200, + "time": "2024-11-25 10:00", + "temp_c": 12.4, + "temp_f": 54.4, + "is_day": 1, + "condition": { + "text": "Light rain", + "icon": "//cdn.weatherapi.com/weather/64x64/day/296.png", + "code": 1183 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 290, + "wind_dir": "WNW", + "pressure_mb": 1014, + "pressure_in": 29.95, + "precip_mm": 0.89, + "precip_in": 0.04, + "snow_cm": 0, + "humidity": 92, + "cloud": 100, + "feelslike_c": 11.8, + "feelslike_f": 53.3, + "windchill_c": 11.8, + "windchill_f": 53.3, + "heatindex_c": 12.5, + "heatindex_f": 54.4, + "dewpoint_c": 11.2, + "dewpoint_f": 52.1, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 9, + "vis_miles": 5, + "gust_mph": 7.5, + "gust_kph": 12.1, + "uv": 0 + }, + { + "time_epoch": 1732528800, + "time": "2024-11-25 11:00", + "temp_c": 12.5, + "temp_f": 54.4, + "is_day": 1, + "condition": { + "text": "Light rain", + "icon": "//cdn.weatherapi.com/weather/64x64/day/296.png", + "code": 1183 + }, + "wind_mph": 6, + "wind_kph": 9.7, + "wind_degree": 311, + "wind_dir": "NW", + "pressure_mb": 1015, + "pressure_in": 29.96, + "precip_mm": 1.36, + "precip_in": 0.05, + "snow_cm": 0, + "humidity": 93, + "cloud": 100, + "feelslike_c": 11.6, + "feelslike_f": 52.9, + "windchill_c": 11.6, + "windchill_f": 52.9, + "heatindex_c": 12.5, + "heatindex_f": 54.4, + "dewpoint_c": 11.3, + "dewpoint_f": 52.3, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 9, + "vis_miles": 5, + "gust_mph": 8.6, + "gust_kph": 13.8, + "uv": 0.1 + }, + { + "time_epoch": 1732532400, + "time": "2024-11-25 12:00", + "temp_c": 11.9, + "temp_f": 53.4, + "is_day": 1, + "condition": { + "text": "Light rain", + "icon": "//cdn.weatherapi.com/weather/64x64/day/296.png", + "code": 1183 + }, + "wind_mph": 8.3, + "wind_kph": 13.3, + "wind_degree": 308, + "wind_dir": "NW", + "pressure_mb": 1016, + "pressure_in": 29.99, + "precip_mm": 2.14, + "precip_in": 0.08, + "snow_cm": 0, + "humidity": 93, + "cloud": 100, + "feelslike_c": 10.4, + "feelslike_f": 50.8, + "windchill_c": 10.4, + "windchill_f": 50.8, + "heatindex_c": 11.9, + "heatindex_f": 53.4, + "dewpoint_c": 10.8, + "dewpoint_f": 51.4, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 9, + "vis_miles": 5, + "gust_mph": 11.6, + "gust_kph": 18.6, + "uv": 0.1 + }, + { + "time_epoch": 1732536000, + "time": "2024-11-25 13:00", + "temp_c": 11.3, + "temp_f": 52.4, + "is_day": 1, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.weatherapi.com/weather/64x64/day/353.png", + "code": 1240 + }, + "wind_mph": 6.7, + "wind_kph": 10.8, + "wind_degree": 302, + "wind_dir": "WNW", + "pressure_mb": 1016, + "pressure_in": 30.01, + "precip_mm": 0.24, + "precip_in": 0.01, + "snow_cm": 0, + "humidity": 89, + "cloud": 100, + "feelslike_c": 10.1, + "feelslike_f": 50.2, + "windchill_c": 10.1, + "windchill_f": 50.2, + "heatindex_c": 11.3, + "heatindex_f": 52.4, + "dewpoint_c": 9.6, + "dewpoint_f": 49.3, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 9.5, + "gust_kph": 15.2, + "uv": 0.1 + }, + { + "time_epoch": 1732539600, + "time": "2024-11-25 14:00", + "temp_c": 11.3, + "temp_f": 52.4, + "is_day": 1, + "condition": { + "text": "Light drizzle", + "icon": "//cdn.weatherapi.com/weather/64x64/day/266.png", + "code": 1153 + }, + "wind_mph": 5.6, + "wind_kph": 9, + "wind_degree": 283, + "wind_dir": "WNW", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0.37, + "precip_in": 0.01, + "snow_cm": 0, + "humidity": 89, + "cloud": 100, + "feelslike_c": 10.4, + "feelslike_f": 50.7, + "windchill_c": 10.4, + "windchill_f": 50.7, + "heatindex_c": 11.3, + "heatindex_f": 52.4, + "dewpoint_c": 9.5, + "dewpoint_f": 49.2, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 2, + "vis_miles": 1, + "gust_mph": 8, + "gust_kph": 12.9, + "uv": 0.1 + }, + { + "time_epoch": 1732543200, + "time": "2024-11-25 15:00", + "temp_c": 11.3, + "temp_f": 52.3, + "is_day": 1, + "condition": { + "text": "Light drizzle", + "icon": "//cdn.weatherapi.com/weather/64x64/day/266.png", + "code": 1153 + }, + "wind_mph": 7.4, + "wind_kph": 11.9, + "wind_degree": 269, + "wind_dir": "W", + "pressure_mb": 1018, + "pressure_in": 30.06, + "precip_mm": 0.45, + "precip_in": 0.02, + "snow_cm": 0, + "humidity": 88, + "cloud": 100, + "feelslike_c": 9.9, + "feelslike_f": 49.7, + "windchill_c": 9.9, + "windchill_f": 49.7, + "heatindex_c": 11.3, + "heatindex_f": 52.3, + "dewpoint_c": 9.4, + "dewpoint_f": 49, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 2, + "vis_miles": 1, + "gust_mph": 11, + "gust_kph": 17.6, + "uv": 0.1 + }, + { + "time_epoch": 1732546800, + "time": "2024-11-25 16:00", + "temp_c": 11.4, + "temp_f": 52.5, + "is_day": 1, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/day/119.png", + "code": 1006 + }, + "wind_mph": 3.6, + "wind_kph": 5.8, + "wind_degree": 244, + "wind_dir": "WSW", + "pressure_mb": 1018, + "pressure_in": 30.07, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 82, + "cloud": 65, + "feelslike_c": 11.2, + "feelslike_f": 52.1, + "windchill_c": 11.2, + "windchill_f": 52.1, + "heatindex_c": 11.4, + "heatindex_f": 52.5, + "dewpoint_c": 8.4, + "dewpoint_f": 47.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 5.6, + "gust_kph": 9, + "uv": 0.1 + }, + { + "time_epoch": 1732550400, + "time": "2024-11-25 17:00", + "temp_c": 11.4, + "temp_f": 52.4, + "is_day": 1, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 191, + "wind_dir": "SSW", + "pressure_mb": 1019, + "pressure_in": 30.09, + "precip_mm": 0.02, + "precip_in": 0, + "snow_cm": 0, + "humidity": 82, + "cloud": 58, + "feelslike_c": 10.5, + "feelslike_f": 51, + "windchill_c": 10.5, + "windchill_f": 51, + "heatindex_c": 11.4, + "heatindex_f": 52.4, + "dewpoint_c": 8.4, + "dewpoint_f": 47, + "will_it_rain": 1, + "chance_of_rain": 89, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 8.4, + "gust_kph": 13.5, + "uv": 0 + }, + { + "time_epoch": 1732554000, + "time": "2024-11-25 18:00", + "temp_c": 11.1, + "temp_f": 51.9, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 5.6, + "wind_kph": 9, + "wind_degree": 207, + "wind_dir": "SSW", + "pressure_mb": 1020, + "pressure_in": 30.11, + "precip_mm": 0.02, + "precip_in": 0, + "snow_cm": 0, + "humidity": 85, + "cloud": 89, + "feelslike_c": 10.1, + "feelslike_f": 50.1, + "windchill_c": 10.1, + "windchill_f": 50.1, + "heatindex_c": 11.1, + "heatindex_f": 51.9, + "dewpoint_c": 8.6, + "dewpoint_f": 47.4, + "will_it_rain": 1, + "chance_of_rain": 76, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 9.4, + "gust_kph": 15.2, + "uv": 0 + }, + { + "time_epoch": 1732557600, + "time": "2024-11-25 19:00", + "temp_c": 10.6, + "temp_f": 51.1, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 6, + "wind_kph": 9.7, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1020, + "pressure_in": 30.13, + "precip_mm": 0.04, + "precip_in": 0, + "snow_cm": 0, + "humidity": 88, + "cloud": 88, + "feelslike_c": 9.4, + "feelslike_f": 48.9, + "windchill_c": 9.4, + "windchill_f": 48.9, + "heatindex_c": 10.6, + "heatindex_f": 51.1, + "dewpoint_c": 8.8, + "dewpoint_f": 47.8, + "will_it_rain": 1, + "chance_of_rain": 76, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 10.6, + "gust_kph": 17.1, + "uv": 0 + }, + { + "time_epoch": 1732561200, + "time": "2024-11-25 20:00", + "temp_c": 10.1, + "temp_f": 50.2, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 5.6, + "wind_kph": 9, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1021, + "pressure_in": 30.16, + "precip_mm": 0.04, + "precip_in": 0, + "snow_cm": 0, + "humidity": 92, + "cloud": 87, + "feelslike_c": 8.9, + "feelslike_f": 48.1, + "windchill_c": 8.9, + "windchill_f": 48.1, + "heatindex_c": 10.1, + "heatindex_f": 50.2, + "dewpoint_c": 8.8, + "dewpoint_f": 47.9, + "will_it_rain": 1, + "chance_of_rain": 75, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 10.5, + "gust_kph": 16.9, + "uv": 0 + }, + { + "time_epoch": 1732564800, + "time": "2024-11-25 21:00", + "temp_c": 9.8, + "temp_f": 49.6, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1022, + "pressure_in": 30.17, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 93, + "cloud": 18, + "feelslike_c": 8.7, + "feelslike_f": 47.7, + "windchill_c": 8.7, + "windchill_f": 47.7, + "heatindex_c": 9.8, + "heatindex_f": 49.6, + "dewpoint_c": 8.7, + "dewpoint_f": 47.7, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 10.2, + "gust_kph": 16.3, + "uv": 0 + }, + { + "time_epoch": 1732568400, + "time": "2024-11-25 22:00", + "temp_c": 9.6, + "temp_f": 49.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1022, + "pressure_in": 30.19, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 93, + "cloud": 24, + "feelslike_c": 8.5, + "feelslike_f": 47.4, + "windchill_c": 8.5, + "windchill_f": 47.4, + "heatindex_c": 9.6, + "heatindex_f": 49.4, + "dewpoint_c": 8.6, + "dewpoint_f": 47.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 10.2, + "gust_kph": 16.5, + "uv": 0 + }, + { + "time_epoch": 1732572000, + "time": "2024-11-25 23:00", + "temp_c": 9.5, + "temp_f": 49.1, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 4.9, + "wind_kph": 7.9, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1023, + "pressure_in": 30.2, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 93, + "cloud": 26, + "feelslike_c": 8.4, + "feelslike_f": 47.2, + "windchill_c": 8.4, + "windchill_f": 47.2, + "heatindex_c": 9.5, + "heatindex_f": 49.1, + "dewpoint_c": 8.5, + "dewpoint_f": 47.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 9.8, + "gust_kph": 15.8, + "uv": 0 + } + ] + } + ] + } +} \ No newline at end of file diff --git a/src/test/resources/WeatherAPI/Bordeaux-3-partial-sunny-rain.json b/src/test/resources/WeatherAPI/Bordeaux-3-partial-sunny-rain.json new file mode 100644 index 0000000..6e10f39 --- /dev/null +++ b/src/test/resources/WeatherAPI/Bordeaux-3-partial-sunny-rain.json @@ -0,0 +1,3057 @@ +{ + "location": { + "name": "Bordeaux", + "region": "Aquitaine", + "country": "France", + "lat": 44.8333, + "lon": -0.5667, + "tz_id": "Europe/Paris", + "localtime_epoch": 1732356248, + "localtime": "2024-11-23 11:04" + }, + "current": { + "last_updated_epoch": 1732356000, + "last_updated": "2024-11-23 11:00", + "temp_c": 7.4, + "temp_f": 45.3, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.4, + "wind_kph": 18.4, + "wind_degree": 148, + "wind_dir": "SSE", + "pressure_mb": 1018, + "pressure_in": 30.06, + "precip_mm": 0, + "precip_in": 0, + "humidity": 76, + "cloud": 0, + "feelslike_c": 4.3, + "feelslike_f": 39.7, + "windchill_c": 6, + "windchill_f": 42.7, + "heatindex_c": 8.7, + "heatindex_f": 47.7, + "dewpoint_c": 1.3, + "dewpoint_f": 34.3, + "vis_km": 10, + "vis_miles": 6, + "uv": 0.9, + "gust_mph": 15.9, + "gust_kph": 25.5 + }, + "forecast": { + "forecastday": [ + { + "date": "2024-11-23", + "date_epoch": 1732320000, + "day": { + "maxtemp_c": 13.1, + "maxtemp_f": 55.7, + "mintemp_c": 4, + "mintemp_f": 39.3, + "avgtemp_c": 8.1, + "avgtemp_f": 46.6, + "maxwind_mph": 13, + "maxwind_kph": 20.9, + "totalprecip_mm": 0, + "totalprecip_in": 0, + "totalsnow_cm": 0, + "avgvis_km": 10, + "avgvis_miles": 6, + "avghumidity": 69, + "daily_will_it_rain": 0, + "daily_chance_of_rain": 0, + "daily_will_it_snow": 0, + "daily_chance_of_snow": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/day/116.png", + "code": 1003 + }, + "uv": 0.3 + }, + "astro": { + "sunrise": "08:10 AM", + "sunset": "05:27 PM", + "moonrise": "12:08 AM", + "moonset": "02:13 PM", + "moon_phase": "Last Quarter", + "moon_illumination": 51, + "is_moon_up": 0, + "is_sun_up": 0 + }, + "hour": [ + { + "time_epoch": 1732316400, + "time": "2024-11-23 00:00", + "temp_c": 5.6, + "temp_f": 42, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 6.7, + "wind_kph": 10.8, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1022, + "pressure_in": 30.19, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 81, + "cloud": 17, + "feelslike_c": 3.2, + "feelslike_f": 37.7, + "windchill_c": 3.2, + "windchill_f": 37.7, + "heatindex_c": 5.6, + "heatindex_f": 42, + "dewpoint_c": 2.6, + "dewpoint_f": 36.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 13.7, + "gust_kph": 22, + "uv": 0 + }, + { + "time_epoch": 1732320000, + "time": "2024-11-23 01:00", + "temp_c": 5.8, + "temp_f": 42.4, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 6.9, + "wind_kph": 11.2, + "wind_degree": 141, + "wind_dir": "SE", + "pressure_mb": 1022, + "pressure_in": 30.17, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 80, + "cloud": 47, + "feelslike_c": 3.3, + "feelslike_f": 38, + "windchill_c": 3.3, + "windchill_f": 38, + "heatindex_c": 5.8, + "heatindex_f": 42.4, + "dewpoint_c": 2.5, + "dewpoint_f": 36.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 13.4, + "gust_kph": 21.6, + "uv": 0 + }, + { + "time_epoch": 1732323600, + "time": "2024-11-23 02:00", + "temp_c": 5.6, + "temp_f": 42.1, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 8.3, + "wind_kph": 13.3, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1021, + "pressure_in": 30.14, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 79, + "cloud": 56, + "feelslike_c": 2.8, + "feelslike_f": 37, + "windchill_c": 2.8, + "windchill_f": 37, + "heatindex_c": 5.6, + "heatindex_f": 42.1, + "dewpoint_c": 2.3, + "dewpoint_f": 36.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 15.3, + "gust_kph": 24.7, + "uv": 0 + }, + { + "time_epoch": 1732327200, + "time": "2024-11-23 03:00", + "temp_c": 5.1, + "temp_f": 41.3, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 9.8, + "wind_kph": 15.8, + "wind_degree": 133, + "wind_dir": "SE", + "pressure_mb": 1020, + "pressure_in": 30.13, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 79, + "cloud": 86, + "feelslike_c": 1.8, + "feelslike_f": 35.3, + "windchill_c": 1.8, + "windchill_f": 35.3, + "heatindex_c": 5.2, + "heatindex_f": 41.3, + "dewpoint_c": 1.9, + "dewpoint_f": 35.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 17.6, + "gust_kph": 28.4, + "uv": 0 + }, + { + "time_epoch": 1732330800, + "time": "2024-11-23 04:00", + "temp_c": 4.8, + "temp_f": 40.7, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 10.5, + "wind_kph": 16.9, + "wind_degree": 130, + "wind_dir": "SE", + "pressure_mb": 1020, + "pressure_in": 30.12, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 79, + "cloud": 44, + "feelslike_c": 1.3, + "feelslike_f": 34.3, + "windchill_c": 1.3, + "windchill_f": 34.3, + "heatindex_c": 4.9, + "heatindex_f": 40.7, + "dewpoint_c": 1.5, + "dewpoint_f": 34.7, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 18.1, + "gust_kph": 29.1, + "uv": 0 + }, + { + "time_epoch": 1732334400, + "time": "2024-11-23 05:00", + "temp_c": 4.3, + "temp_f": 39.7, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11, + "wind_kph": 17.6, + "wind_degree": 130, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.1, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 80, + "cloud": 46, + "feelslike_c": 0.5, + "feelslike_f": 32.8, + "windchill_c": 0.5, + "windchill_f": 32.8, + "heatindex_c": 4.3, + "heatindex_f": 39.7, + "dewpoint_c": 1.2, + "dewpoint_f": 34.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19.1, + "gust_kph": 30.8, + "uv": 0 + }, + { + "time_epoch": 1732338000, + "time": "2024-11-23 06:00", + "temp_c": 4, + "temp_f": 39.3, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.08, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 80, + "cloud": 39, + "feelslike_c": 0.1, + "feelslike_f": 32.2, + "windchill_c": 0.1, + "windchill_f": 32.2, + "heatindex_c": 4, + "heatindex_f": 39.3, + "dewpoint_c": 0.9, + "dewpoint_f": 33.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19.8, + "gust_kph": 31.8, + "uv": 0 + }, + { + "time_epoch": 1732341600, + "time": "2024-11-23 07:00", + "temp_c": 4, + "temp_f": 39.3, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.08, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 78, + "cloud": 26, + "feelslike_c": 0.1, + "feelslike_f": 32.2, + "windchill_c": 0.1, + "windchill_f": 32.2, + "heatindex_c": 4, + "heatindex_f": 39.3, + "dewpoint_c": 0.6, + "dewpoint_f": 33, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19.9, + "gust_kph": 32, + "uv": 0 + }, + { + "time_epoch": 1732345200, + "time": "2024-11-23 08:00", + "temp_c": 4.1, + "temp_f": 39.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 10.5, + "wind_kph": 16.9, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.09, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 75, + "cloud": 7, + "feelslike_c": 0.4, + "feelslike_f": 32.6, + "windchill_c": 0.4, + "windchill_f": 32.6, + "heatindex_c": 4.1, + "heatindex_f": 39.4, + "dewpoint_c": 0.1, + "dewpoint_f": 32.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 18.8, + "gust_kph": 30.2, + "uv": 0 + }, + { + "time_epoch": 1732348800, + "time": "2024-11-23 09:00", + "temp_c": 4.6, + "temp_f": 40.3, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 10.7, + "wind_kph": 17.3, + "wind_degree": 143, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.09, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 71, + "cloud": 13, + "feelslike_c": 1, + "feelslike_f": 33.7, + "windchill_c": 1, + "windchill_f": 33.7, + "heatindex_c": 4.6, + "heatindex_f": 40.4, + "dewpoint_c": -0.2, + "dewpoint_f": 31.7, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19, + "gust_kph": 30.5, + "uv": 0 + }, + { + "time_epoch": 1732352400, + "time": "2024-11-23 10:00", + "temp_c": 6.6, + "temp_f": 43.9, + "is_day": 1, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/day/116.png", + "code": 1003 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 146, + "wind_dir": "SSE", + "pressure_mb": 1019, + "pressure_in": 30.08, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 63, + "cloud": 49, + "feelslike_c": 3.4, + "feelslike_f": 38, + "windchill_c": 3.4, + "windchill_f": 38, + "heatindex_c": 6.6, + "heatindex_f": 43.9, + "dewpoint_c": 0.2, + "dewpoint_f": 32.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 17.5, + "gust_kph": 28.2, + "uv": 0.4 + }, + { + "time_epoch": 1732356000, + "time": "2024-11-23 11:00", + "temp_c": 7.4, + "temp_f": 45.3, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.4, + "wind_kph": 18.4, + "wind_degree": 148, + "wind_dir": "SSE", + "pressure_mb": 1018, + "pressure_in": 30.06, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 76, + "cloud": 0, + "feelslike_c": 6, + "feelslike_f": 42.7, + "windchill_c": 6, + "windchill_f": 42.7, + "heatindex_c": 8.7, + "heatindex_f": 47.7, + "dewpoint_c": 1.3, + "dewpoint_f": 34.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 15.9, + "gust_kph": 25.5, + "uv": 0.9 + }, + { + "time_epoch": 1732359600, + "time": "2024-11-23 12:00", + "temp_c": 10.4, + "temp_f": 50.8, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11, + "wind_kph": 17.6, + "wind_degree": 149, + "wind_dir": "SSE", + "pressure_mb": 1018, + "pressure_in": 30.07, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 56, + "cloud": 21, + "feelslike_c": 8.2, + "feelslike_f": 46.7, + "windchill_c": 8.2, + "windchill_f": 46.7, + "heatindex_c": 10.5, + "heatindex_f": 50.8, + "dewpoint_c": 2.2, + "dewpoint_f": 35.9, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 14.7, + "gust_kph": 23.6, + "uv": 1.3 + }, + { + "time_epoch": 1732363200, + "time": "2024-11-23 13:00", + "temp_c": 12.3, + "temp_f": 54.2, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.4, + "wind_kph": 18.4, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1017, + "pressure_in": 30.04, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 52, + "cloud": 22, + "feelslike_c": 10.5, + "feelslike_f": 50.8, + "windchill_c": 10.5, + "windchill_f": 50.8, + "heatindex_c": 12.3, + "heatindex_f": 54.2, + "dewpoint_c": 2.8, + "dewpoint_f": 37, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 14.9, + "gust_kph": 23.9, + "uv": 1.6 + }, + { + "time_epoch": 1732366800, + "time": "2024-11-23 14:00", + "temp_c": 13, + "temp_f": 55.4, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 10.3, + "wind_kph": 16.6, + "wind_degree": 149, + "wind_dir": "SSE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 54, + "cloud": 12, + "feelslike_c": 11.5, + "feelslike_f": 52.7, + "windchill_c": 11.5, + "windchill_f": 52.7, + "heatindex_c": 13, + "heatindex_f": 55.4, + "dewpoint_c": 3.8, + "dewpoint_f": 38.9, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 14, + "gust_kph": 22.6, + "uv": 1.4 + }, + { + "time_epoch": 1732370400, + "time": "2024-11-23 15:00", + "temp_c": 13.1, + "temp_f": 55.7, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.4, + "wind_kph": 18.4, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1016, + "pressure_in": 30.01, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 54, + "cloud": 22, + "feelslike_c": 11.5, + "feelslike_f": 52.7, + "windchill_c": 11.5, + "windchill_f": 52.7, + "heatindex_c": 13.2, + "heatindex_f": 55.7, + "dewpoint_c": 4.2, + "dewpoint_f": 39.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 16.8, + "gust_kph": 27.1, + "uv": 0.9 + }, + { + "time_epoch": 1732374000, + "time": "2024-11-23 16:00", + "temp_c": 12.5, + "temp_f": 54.4, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 10.7, + "wind_kph": 17.3, + "wind_degree": 148, + "wind_dir": "SSE", + "pressure_mb": 1017, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 57, + "cloud": 14, + "feelslike_c": 10.7, + "feelslike_f": 51.3, + "windchill_c": 10.7, + "windchill_f": 51.3, + "heatindex_c": 12.5, + "heatindex_f": 54.4, + "dewpoint_c": 4.1, + "dewpoint_f": 39.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 17.5, + "gust_kph": 28.1, + "uv": 0.4 + }, + { + "time_epoch": 1732377600, + "time": "2024-11-23 17:00", + "temp_c": 11.2, + "temp_f": 52.1, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 141, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 61, + "cloud": 22, + "feelslike_c": 9, + "feelslike_f": 48.2, + "windchill_c": 9, + "windchill_f": 48.2, + "heatindex_c": 11.2, + "heatindex_f": 52.1, + "dewpoint_c": 4, + "dewpoint_f": 39.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 20.2, + "gust_kph": 32.5, + "uv": 0 + }, + { + "time_epoch": 1732381200, + "time": "2024-11-23 18:00", + "temp_c": 10.2, + "temp_f": 50.4, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11.6, + "wind_kph": 18.7, + "wind_degree": 141, + "wind_dir": "SE", + "pressure_mb": 1016, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 64, + "cloud": 47, + "feelslike_c": 7.8, + "feelslike_f": 46, + "windchill_c": 7.8, + "windchill_f": 46, + "heatindex_c": 10.2, + "heatindex_f": 50.4, + "dewpoint_c": 3.8, + "dewpoint_f": 38.9, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.2, + "gust_kph": 35.7, + "uv": 0 + }, + { + "time_epoch": 1732384800, + "time": "2024-11-23 19:00", + "temp_c": 10, + "temp_f": 50.1, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.3, + "wind_kph": 19.8, + "wind_degree": 144, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 66, + "cloud": 62, + "feelslike_c": 7.5, + "feelslike_f": 45.4, + "windchill_c": 7.5, + "windchill_f": 45.4, + "heatindex_c": 10, + "heatindex_f": 50.1, + "dewpoint_c": 4, + "dewpoint_f": 39.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.8, + "gust_kph": 36.8, + "uv": 0 + }, + { + "time_epoch": 1732388400, + "time": "2024-11-23 20:00", + "temp_c": 10, + "temp_f": 50, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 143, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 68, + "cloud": 57, + "feelslike_c": 7.3, + "feelslike_f": 45.2, + "windchill_c": 7.3, + "windchill_f": 45.2, + "heatindex_c": 10, + "heatindex_f": 50, + "dewpoint_c": 4.3, + "dewpoint_f": 39.8, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.6, + "gust_kph": 36.3, + "uv": 0 + }, + { + "time_epoch": 1732392000, + "time": "2024-11-23 21:00", + "temp_c": 9.7, + "temp_f": 49.5, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 142, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 71, + "cloud": 46, + "feelslike_c": 7, + "feelslike_f": 44.6, + "windchill_c": 7, + "windchill_f": 44.6, + "heatindex_c": 9.7, + "heatindex_f": 49.5, + "dewpoint_c": 4.6, + "dewpoint_f": 40.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.3, + "gust_kph": 35.9, + "uv": 0 + }, + { + "time_epoch": 1732395600, + "time": "2024-11-23 22:00", + "temp_c": 9.5, + "temp_f": 49.1, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13, + "wind_kph": 20.9, + "wind_degree": 139, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 73, + "cloud": 24, + "feelslike_c": 6.6, + "feelslike_f": 44, + "windchill_c": 6.6, + "windchill_f": 44, + "heatindex_c": 9.5, + "heatindex_f": 49.1, + "dewpoint_c": 5, + "dewpoint_f": 41, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23, + "gust_kph": 37, + "uv": 0 + }, + { + "time_epoch": 1732399200, + "time": "2024-11-23 23:00", + "temp_c": 9.3, + "temp_f": 48.8, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 12.8, + "wind_kph": 20.5, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 76, + "cloud": 21, + "feelslike_c": 6.5, + "feelslike_f": 43.7, + "windchill_c": 6.5, + "windchill_f": 43.7, + "heatindex_c": 9.3, + "heatindex_f": 48.8, + "dewpoint_c": 5.3, + "dewpoint_f": 41.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23, + "gust_kph": 37, + "uv": 0 + } + ] + }, + { + "date": "2024-11-24", + "date_epoch": 1732406400, + "day": { + "maxtemp_c": 17.2, + "maxtemp_f": 63, + "mintemp_c": 9.3, + "mintemp_f": 48.8, + "avgtemp_c": 13, + "avgtemp_f": 55.3, + "maxwind_mph": 16.3, + "maxwind_kph": 26.3, + "totalprecip_mm": 0, + "totalprecip_in": 0, + "totalsnow_cm": 0, + "avgvis_km": 10, + "avgvis_miles": 6, + "avghumidity": 70, + "daily_will_it_rain": 0, + "daily_chance_of_rain": 0, + "daily_will_it_snow": 0, + "daily_chance_of_snow": 0, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "uv": 0.3 + }, + "astro": { + "sunrise": "08:12 AM", + "sunset": "05:26 PM", + "moonrise": "01:14 AM", + "moonset": "02:30 PM", + "moon_phase": "Waning Crescent", + "moon_illumination": 41, + "is_moon_up": 0, + "is_sun_up": 0 + }, + "hour": [ + { + "time_epoch": 1732402800, + "time": "2024-11-24 00:00", + "temp_c": 9.3, + "temp_f": 48.8, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 77, + "cloud": 41, + "feelslike_c": 6.5, + "feelslike_f": 43.8, + "windchill_c": 6.5, + "windchill_f": 43.8, + "heatindex_c": 9.3, + "heatindex_f": 48.8, + "dewpoint_c": 5.6, + "dewpoint_f": 42, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.1, + "gust_kph": 37.2, + "uv": 0 + }, + { + "time_epoch": 1732406400, + "time": "2024-11-24 01:00", + "temp_c": 9.5, + "temp_f": 49.1, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 139, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 77, + "cloud": 33, + "feelslike_c": 6.7, + "feelslike_f": 44.1, + "windchill_c": 6.7, + "windchill_f": 44.1, + "heatindex_c": 9.5, + "heatindex_f": 49.1, + "dewpoint_c": 5.7, + "dewpoint_f": 42.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.4, + "gust_kph": 37.7, + "uv": 0 + }, + { + "time_epoch": 1732410000, + "time": "2024-11-24 02:00", + "temp_c": 9.7, + "temp_f": 49.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 12.3, + "wind_kph": 19.8, + "wind_degree": 139, + "wind_dir": "SE", + "pressure_mb": 1016, + "pressure_in": 30, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 77, + "cloud": 22, + "feelslike_c": 7, + "feelslike_f": 44.5, + "windchill_c": 7, + "windchill_f": 44.5, + "heatindex_c": 9.7, + "heatindex_f": 49.4, + "dewpoint_c": 5.8, + "dewpoint_f": 42.4, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.2, + "gust_kph": 37.3, + "uv": 0 + }, + { + "time_epoch": 1732413600, + "time": "2024-11-24 03:00", + "temp_c": 9.7, + "temp_f": 49.5, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 12.8, + "wind_kph": 20.5, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1016, + "pressure_in": 30, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 76, + "cloud": 14, + "feelslike_c": 7, + "feelslike_f": 44.6, + "windchill_c": 7, + "windchill_f": 44.6, + "heatindex_c": 9.7, + "heatindex_f": 49.5, + "dewpoint_c": 5.7, + "dewpoint_f": 42.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.3, + "gust_kph": 39.2, + "uv": 0 + }, + { + "time_epoch": 1732417200, + "time": "2024-11-24 04:00", + "temp_c": 9.8, + "temp_f": 49.6, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13, + "wind_kph": 20.9, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 75, + "cloud": 10, + "feelslike_c": 7, + "feelslike_f": 44.6, + "windchill_c": 7, + "windchill_f": 44.6, + "heatindex_c": 9.8, + "heatindex_f": 49.6, + "dewpoint_c": 5.7, + "dewpoint_f": 42.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.6, + "gust_kph": 39.6, + "uv": 0 + }, + { + "time_epoch": 1732420800, + "time": "2024-11-24 05:00", + "temp_c": 9.7, + "temp_f": 49.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13.4, + "wind_kph": 21.6, + "wind_degree": 136, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 76, + "cloud": 10, + "feelslike_c": 6.8, + "feelslike_f": 44.3, + "windchill_c": 6.8, + "windchill_f": 44.3, + "heatindex_c": 9.7, + "heatindex_f": 49.4, + "dewpoint_c": 5.7, + "dewpoint_f": 42.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25.3, + "gust_kph": 40.7, + "uv": 0 + }, + { + "time_epoch": 1732424400, + "time": "2024-11-24 06:00", + "temp_c": 9.7, + "temp_f": 49.5, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13.6, + "wind_kph": 22, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 77, + "cloud": 11, + "feelslike_c": 6.8, + "feelslike_f": 44.3, + "windchill_c": 6.8, + "windchill_f": 44.3, + "heatindex_c": 9.7, + "heatindex_f": 49.5, + "dewpoint_c": 5.8, + "dewpoint_f": 42.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25.7, + "gust_kph": 41.4, + "uv": 0 + }, + { + "time_epoch": 1732428000, + "time": "2024-11-24 07:00", + "temp_c": 9.7, + "temp_f": 49.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13.6, + "wind_kph": 22, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.97, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 78, + "cloud": 8, + "feelslike_c": 6.8, + "feelslike_f": 44.2, + "windchill_c": 6.8, + "windchill_f": 44.2, + "heatindex_c": 9.7, + "heatindex_f": 49.4, + "dewpoint_c": 6, + "dewpoint_f": 42.7, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25.5, + "gust_kph": 41, + "uv": 0 + }, + { + "time_epoch": 1732431600, + "time": "2024-11-24 08:00", + "temp_c": 9.7, + "temp_f": 49.5, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13.2, + "wind_kph": 21.2, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 78, + "cloud": 7, + "feelslike_c": 6.9, + "feelslike_f": 44.4, + "windchill_c": 6.9, + "windchill_f": 44.4, + "heatindex_c": 9.7, + "heatindex_f": 49.5, + "dewpoint_c": 6.1, + "dewpoint_f": 43, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.8, + "gust_kph": 40, + "uv": 0 + }, + { + "time_epoch": 1732435200, + "time": "2024-11-24 09:00", + "temp_c": 10.1, + "temp_f": 50.1, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 13.6, + "wind_kph": 22, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 78, + "cloud": 7, + "feelslike_c": 7.3, + "feelslike_f": 45.1, + "windchill_c": 7.3, + "windchill_f": 45.1, + "heatindex_c": 10.1, + "heatindex_f": 50.1, + "dewpoint_c": 6.4, + "dewpoint_f": 43.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.5, + "gust_kph": 39.5, + "uv": 0 + }, + { + "time_epoch": 1732438800, + "time": "2024-11-24 10:00", + "temp_c": 11.4, + "temp_f": 52.5, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 14.5, + "wind_kph": 23.4, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.97, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 74, + "cloud": 5, + "feelslike_c": 8.9, + "feelslike_f": 47.9, + "windchill_c": 8.9, + "windchill_f": 47.9, + "heatindex_c": 11.4, + "heatindex_f": 52.5, + "dewpoint_c": 7, + "dewpoint_f": 44.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.2, + "gust_kph": 37.3, + "uv": 0.4 + }, + { + "time_epoch": 1732442400, + "time": "2024-11-24 11:00", + "temp_c": 13.2, + "temp_f": 55.7, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 15.7, + "wind_kph": 25.2, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.96, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 70, + "cloud": 4, + "feelslike_c": 11, + "feelslike_f": 51.8, + "windchill_c": 11, + "windchill_f": 51.8, + "heatindex_c": 13.2, + "heatindex_f": 55.7, + "dewpoint_c": 7.8, + "dewpoint_f": 46, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.5, + "gust_kph": 36.3, + "uv": 0.8 + }, + { + "time_epoch": 1732446000, + "time": "2024-11-24 12:00", + "temp_c": 15, + "temp_f": 58.9, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 16.1, + "wind_kph": 25.9, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1014, + "pressure_in": 29.95, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 65, + "cloud": 4, + "feelslike_c": 13.3, + "feelslike_f": 55.9, + "windchill_c": 13.3, + "windchill_f": 55.9, + "heatindex_c": 15, + "heatindex_f": 58.9, + "dewpoint_c": 8.4, + "dewpoint_f": 47.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 21.9, + "gust_kph": 35.2, + "uv": 1.3 + }, + { + "time_epoch": 1732449600, + "time": "2024-11-24 13:00", + "temp_c": 16.4, + "temp_f": 61.6, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 16.1, + "wind_kph": 25.9, + "wind_degree": 142, + "wind_dir": "SE", + "pressure_mb": 1013, + "pressure_in": 29.91, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 60, + "cloud": 5, + "feelslike_c": 16.4, + "feelslike_f": 61.6, + "windchill_c": 16.4, + "windchill_f": 61.6, + "heatindex_c": 16.4, + "heatindex_f": 61.6, + "dewpoint_c": 8.8, + "dewpoint_f": 47.8, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 21.6, + "gust_kph": 34.7, + "uv": 1.4 + }, + { + "time_epoch": 1732453200, + "time": "2024-11-24 14:00", + "temp_c": 17.2, + "temp_f": 62.9, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 16.3, + "wind_kph": 26.3, + "wind_degree": 143, + "wind_dir": "SE", + "pressure_mb": 1012, + "pressure_in": 29.89, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 59, + "cloud": 4, + "feelslike_c": 17.2, + "feelslike_f": 62.9, + "windchill_c": 17.2, + "windchill_f": 62.9, + "heatindex_c": 17.2, + "heatindex_f": 62.9, + "dewpoint_c": 9, + "dewpoint_f": 48.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.9, + "gust_kph": 36.8, + "uv": 1.3 + }, + { + "time_epoch": 1732456800, + "time": "2024-11-24 15:00", + "temp_c": 17.2, + "temp_f": 63, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 16.3, + "wind_kph": 26.3, + "wind_degree": 145, + "wind_dir": "SE", + "pressure_mb": 1012, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 59, + "cloud": 1, + "feelslike_c": 17.2, + "feelslike_f": 63, + "windchill_c": 17.2, + "windchill_f": 63, + "heatindex_c": 17.2, + "heatindex_f": 63, + "dewpoint_c": 9.2, + "dewpoint_f": 48.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25, + "gust_kph": 40.2, + "uv": 0.8 + }, + { + "time_epoch": 1732460400, + "time": "2024-11-24 16:00", + "temp_c": 16.6, + "temp_f": 61.9, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 15.7, + "wind_kph": 25.2, + "wind_degree": 147, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 61, + "cloud": 3, + "feelslike_c": 16.6, + "feelslike_f": 61.9, + "windchill_c": 16.6, + "windchill_f": 61.9, + "heatindex_c": 16.6, + "heatindex_f": 61.9, + "dewpoint_c": 9.2, + "dewpoint_f": 48.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25.9, + "gust_kph": 41.7, + "uv": 0.4 + }, + { + "time_epoch": 1732464000, + "time": "2024-11-24 17:00", + "temp_c": 15.7, + "temp_f": 60.3, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 15.4, + "wind_kph": 24.8, + "wind_degree": 147, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 65, + "cloud": 22, + "feelslike_c": 15.7, + "feelslike_f": 60.3, + "windchill_c": 15.7, + "windchill_f": 60.3, + "heatindex_c": 15.7, + "heatindex_f": 60.3, + "dewpoint_c": 9.1, + "dewpoint_f": 48.4, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 27, + "gust_kph": 43.5, + "uv": 0 + }, + { + "time_epoch": 1732467600, + "time": "2024-11-24 18:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 15.4, + "wind_kph": 24.8, + "wind_degree": 149, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 66, + "cloud": 15, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 9.1, + "dewpoint_f": 48.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 27.8, + "gust_kph": 44.8, + "uv": 0 + }, + { + "time_epoch": 1732471200, + "time": "2024-11-24 19:00", + "temp_c": 15.2, + "temp_f": 59.4, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 15.7, + "wind_kph": 25.2, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 67, + "cloud": 47, + "feelslike_c": 15.2, + "feelslike_f": 59.4, + "windchill_c": 15.2, + "windchill_f": 59.4, + "heatindex_c": 15.2, + "heatindex_f": 59.4, + "dewpoint_c": 9.1, + "dewpoint_f": 48.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 28.4, + "gust_kph": 45.7, + "uv": 0 + }, + { + "time_epoch": 1732474800, + "time": "2024-11-24 20:00", + "temp_c": 15.2, + "temp_f": 59.4, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 14.8, + "wind_kph": 23.8, + "wind_degree": 149, + "wind_dir": "SSE", + "pressure_mb": 1012, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 67, + "cloud": 56, + "feelslike_c": 15.2, + "feelslike_f": 59.4, + "windchill_c": 15.2, + "windchill_f": 59.4, + "heatindex_c": 15.2, + "heatindex_f": 59.4, + "dewpoint_c": 9.2, + "dewpoint_f": 48.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.5, + "gust_kph": 42.6, + "uv": 0 + }, + { + "time_epoch": 1732478400, + "time": "2024-11-24 21:00", + "temp_c": 15.4, + "temp_f": 59.7, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 14.3, + "wind_kph": 23, + "wind_degree": 151, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 67, + "cloud": 49, + "feelslike_c": 15.4, + "feelslike_f": 59.7, + "windchill_c": 15.4, + "windchill_f": 59.7, + "heatindex_c": 15.4, + "heatindex_f": 59.7, + "dewpoint_c": 9.3, + "dewpoint_f": 48.8, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.7, + "gust_kph": 39.8, + "uv": 0 + }, + { + "time_epoch": 1732482000, + "time": "2024-11-24 22:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 13, + "wind_kph": 20.9, + "wind_degree": 155, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 67, + "cloud": 47, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 9.2, + "dewpoint_f": 48.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.7, + "gust_kph": 36.5, + "uv": 0 + }, + { + "time_epoch": 1732485600, + "time": "2024-11-24 23:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 13.4, + "wind_kph": 21.6, + "wind_degree": 151, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 65, + "cloud": 66, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 8.8, + "dewpoint_f": 47.9, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.8, + "gust_kph": 38.3, + "uv": 0 + } + ] + }, + { + "date": "2024-11-25", + "date_epoch": 1732492800, + "day": { + "maxtemp_c": 15.5, + "maxtemp_f": 59.8, + "mintemp_c": 9.5, + "mintemp_f": 49.1, + "avgtemp_c": 12.7, + "avgtemp_f": 54.8, + "maxwind_mph": 15, + "maxwind_kph": 24.1, + "totalprecip_mm": 7.56, + "totalprecip_in": 0.3, + "totalsnow_cm": 0, + "avgvis_km": 8.6, + "avgvis_miles": 5, + "avghumidity": 80, + "daily_will_it_rain": 1, + "daily_chance_of_rain": 89, + "daily_will_it_snow": 0, + "daily_chance_of_snow": 0, + "condition": { + "text": "Moderate rain", + "icon": "//cdn.weatherapi.com/weather/64x64/day/302.png", + "code": 1189 + }, + "uv": 0 + }, + "astro": { + "sunrise": "08:13 AM", + "sunset": "05:26 PM", + "moonrise": "02:17 AM", + "moonset": "02:46 PM", + "moon_phase": "Waning Crescent", + "moon_illumination": 32, + "is_moon_up": 0, + "is_sun_up": 0 + }, + "hour": [ + { + "time_epoch": 1732489200, + "time": "2024-11-25 00:00", + "temp_c": 15.5, + "temp_f": 59.8, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 13.4, + "wind_kph": 21.6, + "wind_degree": 153, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.85, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 63, + "cloud": 66, + "feelslike_c": 15.5, + "feelslike_f": 59.8, + "windchill_c": 15.5, + "windchill_f": 59.8, + "heatindex_c": 15.5, + "heatindex_f": 59.8, + "dewpoint_c": 8.5, + "dewpoint_f": 47.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.7, + "gust_kph": 39.7, + "uv": 0 + }, + { + "time_epoch": 1732492800, + "time": "2024-11-25 01:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 15, + "wind_kph": 24.1, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0.04, + "precip_in": 0, + "snow_cm": 0, + "humidity": 64, + "cloud": 56, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 8.5, + "dewpoint_f": 47.3, + "will_it_rain": 0, + "chance_of_rain": 69, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.1, + "gust_kph": 42.1, + "uv": 0 + }, + { + "time_epoch": 1732496400, + "time": "2024-11-25 02:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 14.5, + "wind_kph": 23.4, + "wind_degree": 148, + "wind_dir": "SSE", + "pressure_mb": 1010, + "pressure_in": 29.82, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 62, + "cloud": 67, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 8.1, + "dewpoint_f": 46.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.6, + "gust_kph": 42.7, + "uv": 0 + }, + { + "time_epoch": 1732500000, + "time": "2024-11-25 03:00", + "temp_c": 15.5, + "temp_f": 60, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 15, + "wind_kph": 24.1, + "wind_degree": 154, + "wind_dir": "SSE", + "pressure_mb": 1010, + "pressure_in": 29.81, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 59, + "cloud": 82, + "feelslike_c": 15.5, + "feelslike_f": 60, + "windchill_c": 15.5, + "windchill_f": 60, + "heatindex_c": 15.5, + "heatindex_f": 60, + "dewpoint_c": 7.5, + "dewpoint_f": 45.4, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.2, + "gust_kph": 42.1, + "uv": 0 + }, + { + "time_epoch": 1732503600, + "time": "2024-11-25 04:00", + "temp_c": 16.4, + "temp_f": 61.6, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 15, + "wind_kph": 24.1, + "wind_degree": 160, + "wind_dir": "SSE", + "pressure_mb": 1009, + "pressure_in": 29.79, + "precip_mm": 0.01, + "precip_in": 0, + "snow_cm": 0, + "humidity": 54, + "cloud": 85, + "feelslike_c": 16.4, + "feelslike_f": 61.6, + "windchill_c": 16.4, + "windchill_f": 61.6, + "heatindex_c": 16.4, + "heatindex_f": 61.6, + "dewpoint_c": 7, + "dewpoint_f": 44.7, + "will_it_rain": 0, + "chance_of_rain": 70, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.5, + "gust_kph": 42.7, + "uv": 0 + }, + { + "time_epoch": 1732507200, + "time": "2024-11-25 05:00", + "temp_c": 15.5, + "temp_f": 59.9, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 154, + "wind_dir": "SSE", + "pressure_mb": 1009, + "pressure_in": 29.8, + "precip_mm": 0.01, + "precip_in": 0, + "snow_cm": 0, + "humidity": 59, + "cloud": 86, + "feelslike_c": 15.5, + "feelslike_f": 59.9, + "windchill_c": 15.5, + "windchill_f": 59.9, + "heatindex_c": 15.5, + "heatindex_f": 59.9, + "dewpoint_c": 7.5, + "dewpoint_f": 45.5, + "will_it_rain": 0, + "chance_of_rain": 67, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 21.5, + "gust_kph": 34.5, + "uv": 0 + }, + { + "time_epoch": 1732510800, + "time": "2024-11-25 06:00", + "temp_c": 15.5, + "temp_f": 59.8, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 8.5, + "wind_kph": 13.7, + "wind_degree": 181, + "wind_dir": "S", + "pressure_mb": 1010, + "pressure_in": 29.83, + "precip_mm": 0.04, + "precip_in": 0, + "snow_cm": 0, + "humidity": 60, + "cloud": 85, + "feelslike_c": 15.5, + "feelslike_f": 59.8, + "windchill_c": 15.5, + "windchill_f": 59.8, + "heatindex_c": 15.5, + "heatindex_f": 59.8, + "dewpoint_c": 7.8, + "dewpoint_f": 46.1, + "will_it_rain": 0, + "chance_of_rain": 64, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 15.4, + "gust_kph": 24.8, + "uv": 0 + }, + { + "time_epoch": 1732514400, + "time": "2024-11-25 07:00", + "temp_c": 15.1, + "temp_f": 59.1, + "is_day": 0, + "condition": { + "text": "Patchy light drizzle", + "icon": "//cdn.weatherapi.com/weather/64x64/night/263.png", + "code": 1150 + }, + "wind_mph": 7.2, + "wind_kph": 11.5, + "wind_degree": 238, + "wind_dir": "WSW", + "pressure_mb": 1011, + "pressure_in": 29.84, + "precip_mm": 0.32, + "precip_in": 0.01, + "snow_cm": 0, + "humidity": 73, + "cloud": 71, + "feelslike_c": 15.1, + "feelslike_f": 59.1, + "windchill_c": 15.1, + "windchill_f": 59.1, + "heatindex_c": 15.1, + "heatindex_f": 59.1, + "dewpoint_c": 10.2, + "dewpoint_f": 50.3, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 5, + "vis_miles": 3, + "gust_mph": 12.5, + "gust_kph": 20.1, + "uv": 0 + }, + { + "time_epoch": 1732518000, + "time": "2024-11-25 08:00", + "temp_c": 13.6, + "temp_f": 56.5, + "is_day": 0, + "condition": { + "text": "Light rain", + "icon": "//cdn.weatherapi.com/weather/64x64/night/296.png", + "code": 1183 + }, + "wind_mph": 8.5, + "wind_kph": 13.7, + "wind_degree": 301, + "wind_dir": "WNW", + "pressure_mb": 1012, + "pressure_in": 29.88, + "precip_mm": 0.84, + "precip_in": 0.03, + "snow_cm": 0, + "humidity": 91, + "cloud": 100, + "feelslike_c": 12.5, + "feelslike_f": 54.5, + "windchill_c": 12.5, + "windchill_f": 54.5, + "heatindex_c": 13.6, + "heatindex_f": 56.5, + "dewpoint_c": 12.2, + "dewpoint_f": 53.9, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 9, + "vis_miles": 5, + "gust_mph": 12.6, + "gust_kph": 20.3, + "uv": 0 + }, + { + "time_epoch": 1732521600, + "time": "2024-11-25 09:00", + "temp_c": 12.4, + "temp_f": 54.3, + "is_day": 1, + "condition": { + "text": "Light drizzle", + "icon": "//cdn.weatherapi.com/weather/64x64/day/266.png", + "code": 1153 + }, + "wind_mph": 6.7, + "wind_kph": 10.8, + "wind_degree": 316, + "wind_dir": "NW", + "pressure_mb": 1013, + "pressure_in": 29.92, + "precip_mm": 0.73, + "precip_in": 0.03, + "snow_cm": 0, + "humidity": 92, + "cloud": 100, + "feelslike_c": 11.4, + "feelslike_f": 52.5, + "windchill_c": 11.4, + "windchill_f": 52.5, + "heatindex_c": 12.4, + "heatindex_f": 54.3, + "dewpoint_c": 11.1, + "dewpoint_f": 52.1, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 2, + "vis_miles": 1, + "gust_mph": 9.8, + "gust_kph": 15.7, + "uv": 0 + }, + { + "time_epoch": 1732525200, + "time": "2024-11-25 10:00", + "temp_c": 12.4, + "temp_f": 54.4, + "is_day": 1, + "condition": { + "text": "Light rain", + "icon": "//cdn.weatherapi.com/weather/64x64/day/296.png", + "code": 1183 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 290, + "wind_dir": "WNW", + "pressure_mb": 1014, + "pressure_in": 29.95, + "precip_mm": 0.89, + "precip_in": 0.04, + "snow_cm": 0, + "humidity": 92, + "cloud": 100, + "feelslike_c": 11.8, + "feelslike_f": 53.3, + "windchill_c": 11.8, + "windchill_f": 53.3, + "heatindex_c": 12.5, + "heatindex_f": 54.4, + "dewpoint_c": 11.2, + "dewpoint_f": 52.1, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 9, + "vis_miles": 5, + "gust_mph": 7.5, + "gust_kph": 12.1, + "uv": 0 + }, + { + "time_epoch": 1732528800, + "time": "2024-11-25 11:00", + "temp_c": 12.5, + "temp_f": 54.4, + "is_day": 1, + "condition": { + "text": "Light rain", + "icon": "//cdn.weatherapi.com/weather/64x64/day/296.png", + "code": 1183 + }, + "wind_mph": 6, + "wind_kph": 9.7, + "wind_degree": 311, + "wind_dir": "NW", + "pressure_mb": 1015, + "pressure_in": 29.96, + "precip_mm": 1.36, + "precip_in": 0.05, + "snow_cm": 0, + "humidity": 93, + "cloud": 100, + "feelslike_c": 11.6, + "feelslike_f": 52.9, + "windchill_c": 11.6, + "windchill_f": 52.9, + "heatindex_c": 12.5, + "heatindex_f": 54.4, + "dewpoint_c": 11.3, + "dewpoint_f": 52.3, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 9, + "vis_miles": 5, + "gust_mph": 8.6, + "gust_kph": 13.8, + "uv": 0.1 + }, + { + "time_epoch": 1732532400, + "time": "2024-11-25 12:00", + "temp_c": 11.9, + "temp_f": 53.4, + "is_day": 1, + "condition": { + "text": "Light rain", + "icon": "//cdn.weatherapi.com/weather/64x64/day/296.png", + "code": 1183 + }, + "wind_mph": 8.3, + "wind_kph": 13.3, + "wind_degree": 308, + "wind_dir": "NW", + "pressure_mb": 1016, + "pressure_in": 29.99, + "precip_mm": 2.14, + "precip_in": 0.08, + "snow_cm": 0, + "humidity": 93, + "cloud": 100, + "feelslike_c": 10.4, + "feelslike_f": 50.8, + "windchill_c": 10.4, + "windchill_f": 50.8, + "heatindex_c": 11.9, + "heatindex_f": 53.4, + "dewpoint_c": 10.8, + "dewpoint_f": 51.4, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 9, + "vis_miles": 5, + "gust_mph": 11.6, + "gust_kph": 18.6, + "uv": 0.1 + }, + { + "time_epoch": 1732536000, + "time": "2024-11-25 13:00", + "temp_c": 11.3, + "temp_f": 52.4, + "is_day": 1, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.weatherapi.com/weather/64x64/day/353.png", + "code": 1240 + }, + "wind_mph": 6.7, + "wind_kph": 10.8, + "wind_degree": 302, + "wind_dir": "WNW", + "pressure_mb": 1016, + "pressure_in": 30.01, + "precip_mm": 0.24, + "precip_in": 0.01, + "snow_cm": 0, + "humidity": 89, + "cloud": 100, + "feelslike_c": 10.1, + "feelslike_f": 50.2, + "windchill_c": 10.1, + "windchill_f": 50.2, + "heatindex_c": 11.3, + "heatindex_f": 52.4, + "dewpoint_c": 9.6, + "dewpoint_f": 49.3, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 9.5, + "gust_kph": 15.2, + "uv": 0.1 + }, + { + "time_epoch": 1732539600, + "time": "2024-11-25 14:00", + "temp_c": 11.3, + "temp_f": 52.4, + "is_day": 1, + "condition": { + "text": "Light drizzle", + "icon": "//cdn.weatherapi.com/weather/64x64/day/266.png", + "code": 1153 + }, + "wind_mph": 5.6, + "wind_kph": 9, + "wind_degree": 283, + "wind_dir": "WNW", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0.37, + "precip_in": 0.01, + "snow_cm": 0, + "humidity": 89, + "cloud": 100, + "feelslike_c": 10.4, + "feelslike_f": 50.7, + "windchill_c": 10.4, + "windchill_f": 50.7, + "heatindex_c": 11.3, + "heatindex_f": 52.4, + "dewpoint_c": 9.5, + "dewpoint_f": 49.2, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 2, + "vis_miles": 1, + "gust_mph": 8, + "gust_kph": 12.9, + "uv": 0.1 + }, + { + "time_epoch": 1732543200, + "time": "2024-11-25 15:00", + "temp_c": 11.3, + "temp_f": 52.3, + "is_day": 1, + "condition": { + "text": "Light drizzle", + "icon": "//cdn.weatherapi.com/weather/64x64/day/266.png", + "code": 1153 + }, + "wind_mph": 7.4, + "wind_kph": 11.9, + "wind_degree": 269, + "wind_dir": "W", + "pressure_mb": 1018, + "pressure_in": 30.06, + "precip_mm": 0.45, + "precip_in": 0.02, + "snow_cm": 0, + "humidity": 88, + "cloud": 100, + "feelslike_c": 9.9, + "feelslike_f": 49.7, + "windchill_c": 9.9, + "windchill_f": 49.7, + "heatindex_c": 11.3, + "heatindex_f": 52.3, + "dewpoint_c": 9.4, + "dewpoint_f": 49, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 2, + "vis_miles": 1, + "gust_mph": 11, + "gust_kph": 17.6, + "uv": 0.1 + }, + { + "time_epoch": 1732546800, + "time": "2024-11-25 16:00", + "temp_c": 11.4, + "temp_f": 52.5, + "is_day": 1, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/day/119.png", + "code": 1006 + }, + "wind_mph": 3.6, + "wind_kph": 5.8, + "wind_degree": 244, + "wind_dir": "WSW", + "pressure_mb": 1018, + "pressure_in": 30.07, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 82, + "cloud": 65, + "feelslike_c": 11.2, + "feelslike_f": 52.1, + "windchill_c": 11.2, + "windchill_f": 52.1, + "heatindex_c": 11.4, + "heatindex_f": 52.5, + "dewpoint_c": 8.4, + "dewpoint_f": 47.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 5.6, + "gust_kph": 9, + "uv": 0.1 + }, + { + "time_epoch": 1732550400, + "time": "2024-11-25 17:00", + "temp_c": 11.4, + "temp_f": 52.4, + "is_day": 1, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 191, + "wind_dir": "SSW", + "pressure_mb": 1019, + "pressure_in": 30.09, + "precip_mm": 0.02, + "precip_in": 0, + "snow_cm": 0, + "humidity": 82, + "cloud": 58, + "feelslike_c": 10.5, + "feelslike_f": 51, + "windchill_c": 10.5, + "windchill_f": 51, + "heatindex_c": 11.4, + "heatindex_f": 52.4, + "dewpoint_c": 8.4, + "dewpoint_f": 47, + "will_it_rain": 1, + "chance_of_rain": 89, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 8.4, + "gust_kph": 13.5, + "uv": 0 + }, + { + "time_epoch": 1732554000, + "time": "2024-11-25 18:00", + "temp_c": 11.1, + "temp_f": 51.9, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 5.6, + "wind_kph": 9, + "wind_degree": 207, + "wind_dir": "SSW", + "pressure_mb": 1020, + "pressure_in": 30.11, + "precip_mm": 0.02, + "precip_in": 0, + "snow_cm": 0, + "humidity": 85, + "cloud": 89, + "feelslike_c": 10.1, + "feelslike_f": 50.1, + "windchill_c": 10.1, + "windchill_f": 50.1, + "heatindex_c": 11.1, + "heatindex_f": 51.9, + "dewpoint_c": 8.6, + "dewpoint_f": 47.4, + "will_it_rain": 1, + "chance_of_rain": 76, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 9.4, + "gust_kph": 15.2, + "uv": 0 + }, + { + "time_epoch": 1732557600, + "time": "2024-11-25 19:00", + "temp_c": 10.6, + "temp_f": 51.1, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 6, + "wind_kph": 9.7, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1020, + "pressure_in": 30.13, + "precip_mm": 0.04, + "precip_in": 0, + "snow_cm": 0, + "humidity": 88, + "cloud": 88, + "feelslike_c": 9.4, + "feelslike_f": 48.9, + "windchill_c": 9.4, + "windchill_f": 48.9, + "heatindex_c": 10.6, + "heatindex_f": 51.1, + "dewpoint_c": 8.8, + "dewpoint_f": 47.8, + "will_it_rain": 1, + "chance_of_rain": 76, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 10.6, + "gust_kph": 17.1, + "uv": 0 + }, + { + "time_epoch": 1732561200, + "time": "2024-11-25 20:00", + "temp_c": 10.1, + "temp_f": 50.2, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 5.6, + "wind_kph": 9, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1021, + "pressure_in": 30.16, + "precip_mm": 0.04, + "precip_in": 0, + "snow_cm": 0, + "humidity": 92, + "cloud": 87, + "feelslike_c": 8.9, + "feelslike_f": 48.1, + "windchill_c": 8.9, + "windchill_f": 48.1, + "heatindex_c": 10.1, + "heatindex_f": 50.2, + "dewpoint_c": 8.8, + "dewpoint_f": 47.9, + "will_it_rain": 1, + "chance_of_rain": 75, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 10.5, + "gust_kph": 16.9, + "uv": 0 + }, + { + "time_epoch": 1732564800, + "time": "2024-11-25 21:00", + "temp_c": 9.8, + "temp_f": 49.6, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1022, + "pressure_in": 30.17, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 93, + "cloud": 18, + "feelslike_c": 8.7, + "feelslike_f": 47.7, + "windchill_c": 8.7, + "windchill_f": 47.7, + "heatindex_c": 9.8, + "heatindex_f": 49.6, + "dewpoint_c": 8.7, + "dewpoint_f": 47.7, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 10.2, + "gust_kph": 16.3, + "uv": 0 + }, + { + "time_epoch": 1732568400, + "time": "2024-11-25 22:00", + "temp_c": 9.6, + "temp_f": 49.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1022, + "pressure_in": 30.19, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 93, + "cloud": 24, + "feelslike_c": 8.5, + "feelslike_f": 47.4, + "windchill_c": 8.5, + "windchill_f": 47.4, + "heatindex_c": 9.6, + "heatindex_f": 49.4, + "dewpoint_c": 8.6, + "dewpoint_f": 47.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 10.2, + "gust_kph": 16.5, + "uv": 0 + }, + { + "time_epoch": 1732572000, + "time": "2024-11-25 23:00", + "temp_c": 9.5, + "temp_f": 49.1, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 4.9, + "wind_kph": 7.9, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1023, + "pressure_in": 30.2, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 93, + "cloud": 26, + "feelslike_c": 8.4, + "feelslike_f": 47.2, + "windchill_c": 8.4, + "windchill_f": 47.2, + "heatindex_c": 9.5, + "heatindex_f": 49.1, + "dewpoint_c": 8.5, + "dewpoint_f": 47.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 9.8, + "gust_kph": 15.8, + "uv": 0 + } + ] + } + ] + } +} \ No newline at end of file diff --git a/src/test/resources/WeatherAPI/Bordeaux-4-partial-sunny-rain-cloudy.json b/src/test/resources/WeatherAPI/Bordeaux-4-partial-sunny-rain-cloudy.json new file mode 100644 index 0000000..a5781ec --- /dev/null +++ b/src/test/resources/WeatherAPI/Bordeaux-4-partial-sunny-rain-cloudy.json @@ -0,0 +1,4059 @@ +{ + "location": { + "name": "Bordeaux", + "region": "Aquitaine", + "country": "France", + "lat": 44.8333, + "lon": -0.5667, + "tz_id": "Europe/Paris", + "localtime_epoch": 1732356248, + "localtime": "2024-11-23 11:04" + }, + "current": { + "last_updated_epoch": 1732356000, + "last_updated": "2024-11-23 11:00", + "temp_c": 7.4, + "temp_f": 45.3, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.4, + "wind_kph": 18.4, + "wind_degree": 148, + "wind_dir": "SSE", + "pressure_mb": 1018, + "pressure_in": 30.06, + "precip_mm": 0, + "precip_in": 0, + "humidity": 76, + "cloud": 0, + "feelslike_c": 4.3, + "feelslike_f": 39.7, + "windchill_c": 6, + "windchill_f": 42.7, + "heatindex_c": 8.7, + "heatindex_f": 47.7, + "dewpoint_c": 1.3, + "dewpoint_f": 34.3, + "vis_km": 10, + "vis_miles": 6, + "uv": 0.9, + "gust_mph": 15.9, + "gust_kph": 25.5 + }, + "forecast": { + "forecastday": [ + { + "date": "2024-11-23", + "date_epoch": 1732320000, + "day": { + "maxtemp_c": 13.1, + "maxtemp_f": 55.7, + "mintemp_c": 4, + "mintemp_f": 39.3, + "avgtemp_c": 8.1, + "avgtemp_f": 46.6, + "maxwind_mph": 13, + "maxwind_kph": 20.9, + "totalprecip_mm": 0, + "totalprecip_in": 0, + "totalsnow_cm": 0, + "avgvis_km": 10, + "avgvis_miles": 6, + "avghumidity": 69, + "daily_will_it_rain": 0, + "daily_chance_of_rain": 0, + "daily_will_it_snow": 0, + "daily_chance_of_snow": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/day/116.png", + "code": 1003 + }, + "uv": 0.3 + }, + "astro": { + "sunrise": "08:10 AM", + "sunset": "05:27 PM", + "moonrise": "12:08 AM", + "moonset": "02:13 PM", + "moon_phase": "Last Quarter", + "moon_illumination": 51, + "is_moon_up": 0, + "is_sun_up": 0 + }, + "hour": [ + { + "time_epoch": 1732316400, + "time": "2024-11-23 00:00", + "temp_c": 5.6, + "temp_f": 42, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 6.7, + "wind_kph": 10.8, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1022, + "pressure_in": 30.19, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 81, + "cloud": 17, + "feelslike_c": 3.2, + "feelslike_f": 37.7, + "windchill_c": 3.2, + "windchill_f": 37.7, + "heatindex_c": 5.6, + "heatindex_f": 42, + "dewpoint_c": 2.6, + "dewpoint_f": 36.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 13.7, + "gust_kph": 22, + "uv": 0 + }, + { + "time_epoch": 1732320000, + "time": "2024-11-23 01:00", + "temp_c": 5.8, + "temp_f": 42.4, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 6.9, + "wind_kph": 11.2, + "wind_degree": 141, + "wind_dir": "SE", + "pressure_mb": 1022, + "pressure_in": 30.17, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 80, + "cloud": 47, + "feelslike_c": 3.3, + "feelslike_f": 38, + "windchill_c": 3.3, + "windchill_f": 38, + "heatindex_c": 5.8, + "heatindex_f": 42.4, + "dewpoint_c": 2.5, + "dewpoint_f": 36.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 13.4, + "gust_kph": 21.6, + "uv": 0 + }, + { + "time_epoch": 1732323600, + "time": "2024-11-23 02:00", + "temp_c": 5.6, + "temp_f": 42.1, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 8.3, + "wind_kph": 13.3, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1021, + "pressure_in": 30.14, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 79, + "cloud": 56, + "feelslike_c": 2.8, + "feelslike_f": 37, + "windchill_c": 2.8, + "windchill_f": 37, + "heatindex_c": 5.6, + "heatindex_f": 42.1, + "dewpoint_c": 2.3, + "dewpoint_f": 36.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 15.3, + "gust_kph": 24.7, + "uv": 0 + }, + { + "time_epoch": 1732327200, + "time": "2024-11-23 03:00", + "temp_c": 5.1, + "temp_f": 41.3, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 9.8, + "wind_kph": 15.8, + "wind_degree": 133, + "wind_dir": "SE", + "pressure_mb": 1020, + "pressure_in": 30.13, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 79, + "cloud": 86, + "feelslike_c": 1.8, + "feelslike_f": 35.3, + "windchill_c": 1.8, + "windchill_f": 35.3, + "heatindex_c": 5.2, + "heatindex_f": 41.3, + "dewpoint_c": 1.9, + "dewpoint_f": 35.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 17.6, + "gust_kph": 28.4, + "uv": 0 + }, + { + "time_epoch": 1732330800, + "time": "2024-11-23 04:00", + "temp_c": 4.8, + "temp_f": 40.7, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 10.5, + "wind_kph": 16.9, + "wind_degree": 130, + "wind_dir": "SE", + "pressure_mb": 1020, + "pressure_in": 30.12, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 79, + "cloud": 44, + "feelslike_c": 1.3, + "feelslike_f": 34.3, + "windchill_c": 1.3, + "windchill_f": 34.3, + "heatindex_c": 4.9, + "heatindex_f": 40.7, + "dewpoint_c": 1.5, + "dewpoint_f": 34.7, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 18.1, + "gust_kph": 29.1, + "uv": 0 + }, + { + "time_epoch": 1732334400, + "time": "2024-11-23 05:00", + "temp_c": 4.3, + "temp_f": 39.7, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11, + "wind_kph": 17.6, + "wind_degree": 130, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.1, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 80, + "cloud": 46, + "feelslike_c": 0.5, + "feelslike_f": 32.8, + "windchill_c": 0.5, + "windchill_f": 32.8, + "heatindex_c": 4.3, + "heatindex_f": 39.7, + "dewpoint_c": 1.2, + "dewpoint_f": 34.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19.1, + "gust_kph": 30.8, + "uv": 0 + }, + { + "time_epoch": 1732338000, + "time": "2024-11-23 06:00", + "temp_c": 4, + "temp_f": 39.3, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.08, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 80, + "cloud": 39, + "feelslike_c": 0.1, + "feelslike_f": 32.2, + "windchill_c": 0.1, + "windchill_f": 32.2, + "heatindex_c": 4, + "heatindex_f": 39.3, + "dewpoint_c": 0.9, + "dewpoint_f": 33.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19.8, + "gust_kph": 31.8, + "uv": 0 + }, + { + "time_epoch": 1732341600, + "time": "2024-11-23 07:00", + "temp_c": 4, + "temp_f": 39.3, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.08, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 78, + "cloud": 26, + "feelslike_c": 0.1, + "feelslike_f": 32.2, + "windchill_c": 0.1, + "windchill_f": 32.2, + "heatindex_c": 4, + "heatindex_f": 39.3, + "dewpoint_c": 0.6, + "dewpoint_f": 33, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19.9, + "gust_kph": 32, + "uv": 0 + }, + { + "time_epoch": 1732345200, + "time": "2024-11-23 08:00", + "temp_c": 4.1, + "temp_f": 39.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 10.5, + "wind_kph": 16.9, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.09, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 75, + "cloud": 7, + "feelslike_c": 0.4, + "feelslike_f": 32.6, + "windchill_c": 0.4, + "windchill_f": 32.6, + "heatindex_c": 4.1, + "heatindex_f": 39.4, + "dewpoint_c": 0.1, + "dewpoint_f": 32.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 18.8, + "gust_kph": 30.2, + "uv": 0 + }, + { + "time_epoch": 1732348800, + "time": "2024-11-23 09:00", + "temp_c": 4.6, + "temp_f": 40.3, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 10.7, + "wind_kph": 17.3, + "wind_degree": 143, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.09, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 71, + "cloud": 13, + "feelslike_c": 1, + "feelslike_f": 33.7, + "windchill_c": 1, + "windchill_f": 33.7, + "heatindex_c": 4.6, + "heatindex_f": 40.4, + "dewpoint_c": -0.2, + "dewpoint_f": 31.7, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19, + "gust_kph": 30.5, + "uv": 0 + }, + { + "time_epoch": 1732352400, + "time": "2024-11-23 10:00", + "temp_c": 6.6, + "temp_f": 43.9, + "is_day": 1, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/day/116.png", + "code": 1003 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 146, + "wind_dir": "SSE", + "pressure_mb": 1019, + "pressure_in": 30.08, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 63, + "cloud": 49, + "feelslike_c": 3.4, + "feelslike_f": 38, + "windchill_c": 3.4, + "windchill_f": 38, + "heatindex_c": 6.6, + "heatindex_f": 43.9, + "dewpoint_c": 0.2, + "dewpoint_f": 32.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 17.5, + "gust_kph": 28.2, + "uv": 0.4 + }, + { + "time_epoch": 1732356000, + "time": "2024-11-23 11:00", + "temp_c": 7.4, + "temp_f": 45.3, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.4, + "wind_kph": 18.4, + "wind_degree": 148, + "wind_dir": "SSE", + "pressure_mb": 1018, + "pressure_in": 30.06, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 76, + "cloud": 0, + "feelslike_c": 6, + "feelslike_f": 42.7, + "windchill_c": 6, + "windchill_f": 42.7, + "heatindex_c": 8.7, + "heatindex_f": 47.7, + "dewpoint_c": 1.3, + "dewpoint_f": 34.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 15.9, + "gust_kph": 25.5, + "uv": 0.9 + }, + { + "time_epoch": 1732359600, + "time": "2024-11-23 12:00", + "temp_c": 10.4, + "temp_f": 50.8, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11, + "wind_kph": 17.6, + "wind_degree": 149, + "wind_dir": "SSE", + "pressure_mb": 1018, + "pressure_in": 30.07, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 56, + "cloud": 21, + "feelslike_c": 8.2, + "feelslike_f": 46.7, + "windchill_c": 8.2, + "windchill_f": 46.7, + "heatindex_c": 10.5, + "heatindex_f": 50.8, + "dewpoint_c": 2.2, + "dewpoint_f": 35.9, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 14.7, + "gust_kph": 23.6, + "uv": 1.3 + }, + { + "time_epoch": 1732363200, + "time": "2024-11-23 13:00", + "temp_c": 12.3, + "temp_f": 54.2, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.4, + "wind_kph": 18.4, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1017, + "pressure_in": 30.04, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 52, + "cloud": 22, + "feelslike_c": 10.5, + "feelslike_f": 50.8, + "windchill_c": 10.5, + "windchill_f": 50.8, + "heatindex_c": 12.3, + "heatindex_f": 54.2, + "dewpoint_c": 2.8, + "dewpoint_f": 37, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 14.9, + "gust_kph": 23.9, + "uv": 1.6 + }, + { + "time_epoch": 1732366800, + "time": "2024-11-23 14:00", + "temp_c": 13, + "temp_f": 55.4, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 10.3, + "wind_kph": 16.6, + "wind_degree": 149, + "wind_dir": "SSE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 54, + "cloud": 12, + "feelslike_c": 11.5, + "feelslike_f": 52.7, + "windchill_c": 11.5, + "windchill_f": 52.7, + "heatindex_c": 13, + "heatindex_f": 55.4, + "dewpoint_c": 3.8, + "dewpoint_f": 38.9, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 14, + "gust_kph": 22.6, + "uv": 1.4 + }, + { + "time_epoch": 1732370400, + "time": "2024-11-23 15:00", + "temp_c": 13.1, + "temp_f": 55.7, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.4, + "wind_kph": 18.4, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1016, + "pressure_in": 30.01, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 54, + "cloud": 22, + "feelslike_c": 11.5, + "feelslike_f": 52.7, + "windchill_c": 11.5, + "windchill_f": 52.7, + "heatindex_c": 13.2, + "heatindex_f": 55.7, + "dewpoint_c": 4.2, + "dewpoint_f": 39.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 16.8, + "gust_kph": 27.1, + "uv": 0.9 + }, + { + "time_epoch": 1732374000, + "time": "2024-11-23 16:00", + "temp_c": 12.5, + "temp_f": 54.4, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 10.7, + "wind_kph": 17.3, + "wind_degree": 148, + "wind_dir": "SSE", + "pressure_mb": 1017, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 57, + "cloud": 14, + "feelslike_c": 10.7, + "feelslike_f": 51.3, + "windchill_c": 10.7, + "windchill_f": 51.3, + "heatindex_c": 12.5, + "heatindex_f": 54.4, + "dewpoint_c": 4.1, + "dewpoint_f": 39.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 17.5, + "gust_kph": 28.1, + "uv": 0.4 + }, + { + "time_epoch": 1732377600, + "time": "2024-11-23 17:00", + "temp_c": 11.2, + "temp_f": 52.1, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 141, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 61, + "cloud": 22, + "feelslike_c": 9, + "feelslike_f": 48.2, + "windchill_c": 9, + "windchill_f": 48.2, + "heatindex_c": 11.2, + "heatindex_f": 52.1, + "dewpoint_c": 4, + "dewpoint_f": 39.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 20.2, + "gust_kph": 32.5, + "uv": 0 + }, + { + "time_epoch": 1732381200, + "time": "2024-11-23 18:00", + "temp_c": 10.2, + "temp_f": 50.4, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11.6, + "wind_kph": 18.7, + "wind_degree": 141, + "wind_dir": "SE", + "pressure_mb": 1016, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 64, + "cloud": 47, + "feelslike_c": 7.8, + "feelslike_f": 46, + "windchill_c": 7.8, + "windchill_f": 46, + "heatindex_c": 10.2, + "heatindex_f": 50.4, + "dewpoint_c": 3.8, + "dewpoint_f": 38.9, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.2, + "gust_kph": 35.7, + "uv": 0 + }, + { + "time_epoch": 1732384800, + "time": "2024-11-23 19:00", + "temp_c": 10, + "temp_f": 50.1, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.3, + "wind_kph": 19.8, + "wind_degree": 144, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 66, + "cloud": 62, + "feelslike_c": 7.5, + "feelslike_f": 45.4, + "windchill_c": 7.5, + "windchill_f": 45.4, + "heatindex_c": 10, + "heatindex_f": 50.1, + "dewpoint_c": 4, + "dewpoint_f": 39.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.8, + "gust_kph": 36.8, + "uv": 0 + }, + { + "time_epoch": 1732388400, + "time": "2024-11-23 20:00", + "temp_c": 10, + "temp_f": 50, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 143, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 68, + "cloud": 57, + "feelslike_c": 7.3, + "feelslike_f": 45.2, + "windchill_c": 7.3, + "windchill_f": 45.2, + "heatindex_c": 10, + "heatindex_f": 50, + "dewpoint_c": 4.3, + "dewpoint_f": 39.8, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.6, + "gust_kph": 36.3, + "uv": 0 + }, + { + "time_epoch": 1732392000, + "time": "2024-11-23 21:00", + "temp_c": 9.7, + "temp_f": 49.5, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 142, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 71, + "cloud": 46, + "feelslike_c": 7, + "feelslike_f": 44.6, + "windchill_c": 7, + "windchill_f": 44.6, + "heatindex_c": 9.7, + "heatindex_f": 49.5, + "dewpoint_c": 4.6, + "dewpoint_f": 40.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.3, + "gust_kph": 35.9, + "uv": 0 + }, + { + "time_epoch": 1732395600, + "time": "2024-11-23 22:00", + "temp_c": 9.5, + "temp_f": 49.1, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13, + "wind_kph": 20.9, + "wind_degree": 139, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 73, + "cloud": 24, + "feelslike_c": 6.6, + "feelslike_f": 44, + "windchill_c": 6.6, + "windchill_f": 44, + "heatindex_c": 9.5, + "heatindex_f": 49.1, + "dewpoint_c": 5, + "dewpoint_f": 41, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23, + "gust_kph": 37, + "uv": 0 + }, + { + "time_epoch": 1732399200, + "time": "2024-11-23 23:00", + "temp_c": 9.3, + "temp_f": 48.8, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 12.8, + "wind_kph": 20.5, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 76, + "cloud": 21, + "feelslike_c": 6.5, + "feelslike_f": 43.7, + "windchill_c": 6.5, + "windchill_f": 43.7, + "heatindex_c": 9.3, + "heatindex_f": 48.8, + "dewpoint_c": 5.3, + "dewpoint_f": 41.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23, + "gust_kph": 37, + "uv": 0 + } + ] + }, + { + "date": "2024-11-24", + "date_epoch": 1732406400, + "day": { + "maxtemp_c": 17.2, + "maxtemp_f": 63, + "mintemp_c": 9.3, + "mintemp_f": 48.8, + "avgtemp_c": 13, + "avgtemp_f": 55.3, + "maxwind_mph": 16.3, + "maxwind_kph": 26.3, + "totalprecip_mm": 0, + "totalprecip_in": 0, + "totalsnow_cm": 0, + "avgvis_km": 10, + "avgvis_miles": 6, + "avghumidity": 70, + "daily_will_it_rain": 0, + "daily_chance_of_rain": 0, + "daily_will_it_snow": 0, + "daily_chance_of_snow": 0, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "uv": 0.3 + }, + "astro": { + "sunrise": "08:12 AM", + "sunset": "05:26 PM", + "moonrise": "01:14 AM", + "moonset": "02:30 PM", + "moon_phase": "Waning Crescent", + "moon_illumination": 41, + "is_moon_up": 0, + "is_sun_up": 0 + }, + "hour": [ + { + "time_epoch": 1732402800, + "time": "2024-11-24 00:00", + "temp_c": 9.3, + "temp_f": 48.8, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 77, + "cloud": 41, + "feelslike_c": 6.5, + "feelslike_f": 43.8, + "windchill_c": 6.5, + "windchill_f": 43.8, + "heatindex_c": 9.3, + "heatindex_f": 48.8, + "dewpoint_c": 5.6, + "dewpoint_f": 42, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.1, + "gust_kph": 37.2, + "uv": 0 + }, + { + "time_epoch": 1732406400, + "time": "2024-11-24 01:00", + "temp_c": 9.5, + "temp_f": 49.1, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 139, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 77, + "cloud": 33, + "feelslike_c": 6.7, + "feelslike_f": 44.1, + "windchill_c": 6.7, + "windchill_f": 44.1, + "heatindex_c": 9.5, + "heatindex_f": 49.1, + "dewpoint_c": 5.7, + "dewpoint_f": 42.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.4, + "gust_kph": 37.7, + "uv": 0 + }, + { + "time_epoch": 1732410000, + "time": "2024-11-24 02:00", + "temp_c": 9.7, + "temp_f": 49.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 12.3, + "wind_kph": 19.8, + "wind_degree": 139, + "wind_dir": "SE", + "pressure_mb": 1016, + "pressure_in": 30, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 77, + "cloud": 22, + "feelslike_c": 7, + "feelslike_f": 44.5, + "windchill_c": 7, + "windchill_f": 44.5, + "heatindex_c": 9.7, + "heatindex_f": 49.4, + "dewpoint_c": 5.8, + "dewpoint_f": 42.4, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.2, + "gust_kph": 37.3, + "uv": 0 + }, + { + "time_epoch": 1732413600, + "time": "2024-11-24 03:00", + "temp_c": 9.7, + "temp_f": 49.5, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 12.8, + "wind_kph": 20.5, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1016, + "pressure_in": 30, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 76, + "cloud": 14, + "feelslike_c": 7, + "feelslike_f": 44.6, + "windchill_c": 7, + "windchill_f": 44.6, + "heatindex_c": 9.7, + "heatindex_f": 49.5, + "dewpoint_c": 5.7, + "dewpoint_f": 42.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.3, + "gust_kph": 39.2, + "uv": 0 + }, + { + "time_epoch": 1732417200, + "time": "2024-11-24 04:00", + "temp_c": 9.8, + "temp_f": 49.6, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13, + "wind_kph": 20.9, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 75, + "cloud": 10, + "feelslike_c": 7, + "feelslike_f": 44.6, + "windchill_c": 7, + "windchill_f": 44.6, + "heatindex_c": 9.8, + "heatindex_f": 49.6, + "dewpoint_c": 5.7, + "dewpoint_f": 42.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.6, + "gust_kph": 39.6, + "uv": 0 + }, + { + "time_epoch": 1732420800, + "time": "2024-11-24 05:00", + "temp_c": 9.7, + "temp_f": 49.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13.4, + "wind_kph": 21.6, + "wind_degree": 136, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 76, + "cloud": 10, + "feelslike_c": 6.8, + "feelslike_f": 44.3, + "windchill_c": 6.8, + "windchill_f": 44.3, + "heatindex_c": 9.7, + "heatindex_f": 49.4, + "dewpoint_c": 5.7, + "dewpoint_f": 42.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25.3, + "gust_kph": 40.7, + "uv": 0 + }, + { + "time_epoch": 1732424400, + "time": "2024-11-24 06:00", + "temp_c": 9.7, + "temp_f": 49.5, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13.6, + "wind_kph": 22, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 77, + "cloud": 11, + "feelslike_c": 6.8, + "feelslike_f": 44.3, + "windchill_c": 6.8, + "windchill_f": 44.3, + "heatindex_c": 9.7, + "heatindex_f": 49.5, + "dewpoint_c": 5.8, + "dewpoint_f": 42.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25.7, + "gust_kph": 41.4, + "uv": 0 + }, + { + "time_epoch": 1732428000, + "time": "2024-11-24 07:00", + "temp_c": 9.7, + "temp_f": 49.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13.6, + "wind_kph": 22, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.97, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 78, + "cloud": 8, + "feelslike_c": 6.8, + "feelslike_f": 44.2, + "windchill_c": 6.8, + "windchill_f": 44.2, + "heatindex_c": 9.7, + "heatindex_f": 49.4, + "dewpoint_c": 6, + "dewpoint_f": 42.7, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25.5, + "gust_kph": 41, + "uv": 0 + }, + { + "time_epoch": 1732431600, + "time": "2024-11-24 08:00", + "temp_c": 9.7, + "temp_f": 49.5, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13.2, + "wind_kph": 21.2, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 78, + "cloud": 7, + "feelslike_c": 6.9, + "feelslike_f": 44.4, + "windchill_c": 6.9, + "windchill_f": 44.4, + "heatindex_c": 9.7, + "heatindex_f": 49.5, + "dewpoint_c": 6.1, + "dewpoint_f": 43, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.8, + "gust_kph": 40, + "uv": 0 + }, + { + "time_epoch": 1732435200, + "time": "2024-11-24 09:00", + "temp_c": 10.1, + "temp_f": 50.1, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 13.6, + "wind_kph": 22, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.98, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 78, + "cloud": 7, + "feelslike_c": 7.3, + "feelslike_f": 45.1, + "windchill_c": 7.3, + "windchill_f": 45.1, + "heatindex_c": 10.1, + "heatindex_f": 50.1, + "dewpoint_c": 6.4, + "dewpoint_f": 43.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.5, + "gust_kph": 39.5, + "uv": 0 + }, + { + "time_epoch": 1732438800, + "time": "2024-11-24 10:00", + "temp_c": 11.4, + "temp_f": 52.5, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 14.5, + "wind_kph": 23.4, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.97, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 74, + "cloud": 5, + "feelslike_c": 8.9, + "feelslike_f": 47.9, + "windchill_c": 8.9, + "windchill_f": 47.9, + "heatindex_c": 11.4, + "heatindex_f": 52.5, + "dewpoint_c": 7, + "dewpoint_f": 44.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.2, + "gust_kph": 37.3, + "uv": 0.4 + }, + { + "time_epoch": 1732442400, + "time": "2024-11-24 11:00", + "temp_c": 13.2, + "temp_f": 55.7, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 15.7, + "wind_kph": 25.2, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1015, + "pressure_in": 29.96, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 70, + "cloud": 4, + "feelslike_c": 11, + "feelslike_f": 51.8, + "windchill_c": 11, + "windchill_f": 51.8, + "heatindex_c": 13.2, + "heatindex_f": 55.7, + "dewpoint_c": 7.8, + "dewpoint_f": 46, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.5, + "gust_kph": 36.3, + "uv": 0.8 + }, + { + "time_epoch": 1732446000, + "time": "2024-11-24 12:00", + "temp_c": 15, + "temp_f": 58.9, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 16.1, + "wind_kph": 25.9, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1014, + "pressure_in": 29.95, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 65, + "cloud": 4, + "feelslike_c": 13.3, + "feelslike_f": 55.9, + "windchill_c": 13.3, + "windchill_f": 55.9, + "heatindex_c": 15, + "heatindex_f": 58.9, + "dewpoint_c": 8.4, + "dewpoint_f": 47.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 21.9, + "gust_kph": 35.2, + "uv": 1.3 + }, + { + "time_epoch": 1732449600, + "time": "2024-11-24 13:00", + "temp_c": 16.4, + "temp_f": 61.6, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 16.1, + "wind_kph": 25.9, + "wind_degree": 142, + "wind_dir": "SE", + "pressure_mb": 1013, + "pressure_in": 29.91, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 60, + "cloud": 5, + "feelslike_c": 16.4, + "feelslike_f": 61.6, + "windchill_c": 16.4, + "windchill_f": 61.6, + "heatindex_c": 16.4, + "heatindex_f": 61.6, + "dewpoint_c": 8.8, + "dewpoint_f": 47.8, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 21.6, + "gust_kph": 34.7, + "uv": 1.4 + }, + { + "time_epoch": 1732453200, + "time": "2024-11-24 14:00", + "temp_c": 17.2, + "temp_f": 62.9, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 16.3, + "wind_kph": 26.3, + "wind_degree": 143, + "wind_dir": "SE", + "pressure_mb": 1012, + "pressure_in": 29.89, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 59, + "cloud": 4, + "feelslike_c": 17.2, + "feelslike_f": 62.9, + "windchill_c": 17.2, + "windchill_f": 62.9, + "heatindex_c": 17.2, + "heatindex_f": 62.9, + "dewpoint_c": 9, + "dewpoint_f": 48.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.9, + "gust_kph": 36.8, + "uv": 1.3 + }, + { + "time_epoch": 1732456800, + "time": "2024-11-24 15:00", + "temp_c": 17.2, + "temp_f": 63, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 16.3, + "wind_kph": 26.3, + "wind_degree": 145, + "wind_dir": "SE", + "pressure_mb": 1012, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 59, + "cloud": 1, + "feelslike_c": 17.2, + "feelslike_f": 63, + "windchill_c": 17.2, + "windchill_f": 63, + "heatindex_c": 17.2, + "heatindex_f": 63, + "dewpoint_c": 9.2, + "dewpoint_f": 48.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25, + "gust_kph": 40.2, + "uv": 0.8 + }, + { + "time_epoch": 1732460400, + "time": "2024-11-24 16:00", + "temp_c": 16.6, + "temp_f": 61.9, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 15.7, + "wind_kph": 25.2, + "wind_degree": 147, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 61, + "cloud": 3, + "feelslike_c": 16.6, + "feelslike_f": 61.9, + "windchill_c": 16.6, + "windchill_f": 61.9, + "heatindex_c": 16.6, + "heatindex_f": 61.9, + "dewpoint_c": 9.2, + "dewpoint_f": 48.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 25.9, + "gust_kph": 41.7, + "uv": 0.4 + }, + { + "time_epoch": 1732464000, + "time": "2024-11-24 17:00", + "temp_c": 15.7, + "temp_f": 60.3, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 15.4, + "wind_kph": 24.8, + "wind_degree": 147, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 65, + "cloud": 22, + "feelslike_c": 15.7, + "feelslike_f": 60.3, + "windchill_c": 15.7, + "windchill_f": 60.3, + "heatindex_c": 15.7, + "heatindex_f": 60.3, + "dewpoint_c": 9.1, + "dewpoint_f": 48.4, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 27, + "gust_kph": 43.5, + "uv": 0 + }, + { + "time_epoch": 1732467600, + "time": "2024-11-24 18:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 15.4, + "wind_kph": 24.8, + "wind_degree": 149, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 66, + "cloud": 15, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 9.1, + "dewpoint_f": 48.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 27.8, + "gust_kph": 44.8, + "uv": 0 + }, + { + "time_epoch": 1732471200, + "time": "2024-11-24 19:00", + "temp_c": 15.2, + "temp_f": 59.4, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 15.7, + "wind_kph": 25.2, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 67, + "cloud": 47, + "feelslike_c": 15.2, + "feelslike_f": 59.4, + "windchill_c": 15.2, + "windchill_f": 59.4, + "heatindex_c": 15.2, + "heatindex_f": 59.4, + "dewpoint_c": 9.1, + "dewpoint_f": 48.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 28.4, + "gust_kph": 45.7, + "uv": 0 + }, + { + "time_epoch": 1732474800, + "time": "2024-11-24 20:00", + "temp_c": 15.2, + "temp_f": 59.4, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 14.8, + "wind_kph": 23.8, + "wind_degree": 149, + "wind_dir": "SSE", + "pressure_mb": 1012, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 67, + "cloud": 56, + "feelslike_c": 15.2, + "feelslike_f": 59.4, + "windchill_c": 15.2, + "windchill_f": 59.4, + "heatindex_c": 15.2, + "heatindex_f": 59.4, + "dewpoint_c": 9.2, + "dewpoint_f": 48.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.5, + "gust_kph": 42.6, + "uv": 0 + }, + { + "time_epoch": 1732478400, + "time": "2024-11-24 21:00", + "temp_c": 15.4, + "temp_f": 59.7, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 14.3, + "wind_kph": 23, + "wind_degree": 151, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 67, + "cloud": 49, + "feelslike_c": 15.4, + "feelslike_f": 59.7, + "windchill_c": 15.4, + "windchill_f": 59.7, + "heatindex_c": 15.4, + "heatindex_f": 59.7, + "dewpoint_c": 9.3, + "dewpoint_f": 48.8, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.7, + "gust_kph": 39.8, + "uv": 0 + }, + { + "time_epoch": 1732482000, + "time": "2024-11-24 22:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 13, + "wind_kph": 20.9, + "wind_degree": 155, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 67, + "cloud": 47, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 9.2, + "dewpoint_f": 48.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.7, + "gust_kph": 36.5, + "uv": 0 + }, + { + "time_epoch": 1732485600, + "time": "2024-11-24 23:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 13.4, + "wind_kph": 21.6, + "wind_degree": 151, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.87, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 65, + "cloud": 66, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 8.8, + "dewpoint_f": 47.9, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23.8, + "gust_kph": 38.3, + "uv": 0 + } + ] + }, + { + "date": "2024-11-25", + "date_epoch": 1732492800, + "day": { + "maxtemp_c": 15.5, + "maxtemp_f": 59.8, + "mintemp_c": 9.5, + "mintemp_f": 49.1, + "avgtemp_c": 12.7, + "avgtemp_f": 54.8, + "maxwind_mph": 15, + "maxwind_kph": 24.1, + "totalprecip_mm": 7.56, + "totalprecip_in": 0.3, + "totalsnow_cm": 0, + "avgvis_km": 8.6, + "avgvis_miles": 5, + "avghumidity": 80, + "daily_will_it_rain": 1, + "daily_chance_of_rain": 89, + "daily_will_it_snow": 0, + "daily_chance_of_snow": 0, + "condition": { + "text": "Moderate rain", + "icon": "//cdn.weatherapi.com/weather/64x64/day/302.png", + "code": 1189 + }, + "uv": 0 + }, + "astro": { + "sunrise": "08:13 AM", + "sunset": "05:26 PM", + "moonrise": "02:17 AM", + "moonset": "02:46 PM", + "moon_phase": "Waning Crescent", + "moon_illumination": 32, + "is_moon_up": 0, + "is_sun_up": 0 + }, + "hour": [ + { + "time_epoch": 1732489200, + "time": "2024-11-25 00:00", + "temp_c": 15.5, + "temp_f": 59.8, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 13.4, + "wind_kph": 21.6, + "wind_degree": 153, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.85, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 63, + "cloud": 66, + "feelslike_c": 15.5, + "feelslike_f": 59.8, + "windchill_c": 15.5, + "windchill_f": 59.8, + "heatindex_c": 15.5, + "heatindex_f": 59.8, + "dewpoint_c": 8.5, + "dewpoint_f": 47.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 24.7, + "gust_kph": 39.7, + "uv": 0 + }, + { + "time_epoch": 1732492800, + "time": "2024-11-25 01:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 15, + "wind_kph": 24.1, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1011, + "pressure_in": 29.86, + "precip_mm": 0.04, + "precip_in": 0, + "snow_cm": 0, + "humidity": 64, + "cloud": 56, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 8.5, + "dewpoint_f": 47.3, + "will_it_rain": 0, + "chance_of_rain": 69, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.1, + "gust_kph": 42.1, + "uv": 0 + }, + { + "time_epoch": 1732496400, + "time": "2024-11-25 02:00", + "temp_c": 15.3, + "temp_f": 59.5, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 14.5, + "wind_kph": 23.4, + "wind_degree": 148, + "wind_dir": "SSE", + "pressure_mb": 1010, + "pressure_in": 29.82, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 62, + "cloud": 67, + "feelslike_c": 15.3, + "feelslike_f": 59.5, + "windchill_c": 15.3, + "windchill_f": 59.5, + "heatindex_c": 15.3, + "heatindex_f": 59.5, + "dewpoint_c": 8.1, + "dewpoint_f": 46.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.6, + "gust_kph": 42.7, + "uv": 0 + }, + { + "time_epoch": 1732500000, + "time": "2024-11-25 03:00", + "temp_c": 15.5, + "temp_f": 60, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 15, + "wind_kph": 24.1, + "wind_degree": 154, + "wind_dir": "SSE", + "pressure_mb": 1010, + "pressure_in": 29.81, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 59, + "cloud": 82, + "feelslike_c": 15.5, + "feelslike_f": 60, + "windchill_c": 15.5, + "windchill_f": 60, + "heatindex_c": 15.5, + "heatindex_f": 60, + "dewpoint_c": 7.5, + "dewpoint_f": 45.4, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.2, + "gust_kph": 42.1, + "uv": 0 + }, + { + "time_epoch": 1732503600, + "time": "2024-11-25 04:00", + "temp_c": 16.4, + "temp_f": 61.6, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 15, + "wind_kph": 24.1, + "wind_degree": 160, + "wind_dir": "SSE", + "pressure_mb": 1009, + "pressure_in": 29.79, + "precip_mm": 0.01, + "precip_in": 0, + "snow_cm": 0, + "humidity": 54, + "cloud": 85, + "feelslike_c": 16.4, + "feelslike_f": 61.6, + "windchill_c": 16.4, + "windchill_f": 61.6, + "heatindex_c": 16.4, + "heatindex_f": 61.6, + "dewpoint_c": 7, + "dewpoint_f": 44.7, + "will_it_rain": 0, + "chance_of_rain": 70, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 26.5, + "gust_kph": 42.7, + "uv": 0 + }, + { + "time_epoch": 1732507200, + "time": "2024-11-25 05:00", + "temp_c": 15.5, + "temp_f": 59.9, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 154, + "wind_dir": "SSE", + "pressure_mb": 1009, + "pressure_in": 29.8, + "precip_mm": 0.01, + "precip_in": 0, + "snow_cm": 0, + "humidity": 59, + "cloud": 86, + "feelslike_c": 15.5, + "feelslike_f": 59.9, + "windchill_c": 15.5, + "windchill_f": 59.9, + "heatindex_c": 15.5, + "heatindex_f": 59.9, + "dewpoint_c": 7.5, + "dewpoint_f": 45.5, + "will_it_rain": 0, + "chance_of_rain": 67, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 21.5, + "gust_kph": 34.5, + "uv": 0 + }, + { + "time_epoch": 1732510800, + "time": "2024-11-25 06:00", + "temp_c": 15.5, + "temp_f": 59.8, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 8.5, + "wind_kph": 13.7, + "wind_degree": 181, + "wind_dir": "S", + "pressure_mb": 1010, + "pressure_in": 29.83, + "precip_mm": 0.04, + "precip_in": 0, + "snow_cm": 0, + "humidity": 60, + "cloud": 85, + "feelslike_c": 15.5, + "feelslike_f": 59.8, + "windchill_c": 15.5, + "windchill_f": 59.8, + "heatindex_c": 15.5, + "heatindex_f": 59.8, + "dewpoint_c": 7.8, + "dewpoint_f": 46.1, + "will_it_rain": 0, + "chance_of_rain": 64, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 15.4, + "gust_kph": 24.8, + "uv": 0 + }, + { + "time_epoch": 1732514400, + "time": "2024-11-25 07:00", + "temp_c": 15.1, + "temp_f": 59.1, + "is_day": 0, + "condition": { + "text": "Patchy light drizzle", + "icon": "//cdn.weatherapi.com/weather/64x64/night/263.png", + "code": 1150 + }, + "wind_mph": 7.2, + "wind_kph": 11.5, + "wind_degree": 238, + "wind_dir": "WSW", + "pressure_mb": 1011, + "pressure_in": 29.84, + "precip_mm": 0.32, + "precip_in": 0.01, + "snow_cm": 0, + "humidity": 73, + "cloud": 71, + "feelslike_c": 15.1, + "feelslike_f": 59.1, + "windchill_c": 15.1, + "windchill_f": 59.1, + "heatindex_c": 15.1, + "heatindex_f": 59.1, + "dewpoint_c": 10.2, + "dewpoint_f": 50.3, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 5, + "vis_miles": 3, + "gust_mph": 12.5, + "gust_kph": 20.1, + "uv": 0 + }, + { + "time_epoch": 1732518000, + "time": "2024-11-25 08:00", + "temp_c": 13.6, + "temp_f": 56.5, + "is_day": 0, + "condition": { + "text": "Light rain", + "icon": "//cdn.weatherapi.com/weather/64x64/night/296.png", + "code": 1183 + }, + "wind_mph": 8.5, + "wind_kph": 13.7, + "wind_degree": 301, + "wind_dir": "WNW", + "pressure_mb": 1012, + "pressure_in": 29.88, + "precip_mm": 0.84, + "precip_in": 0.03, + "snow_cm": 0, + "humidity": 91, + "cloud": 100, + "feelslike_c": 12.5, + "feelslike_f": 54.5, + "windchill_c": 12.5, + "windchill_f": 54.5, + "heatindex_c": 13.6, + "heatindex_f": 56.5, + "dewpoint_c": 12.2, + "dewpoint_f": 53.9, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 9, + "vis_miles": 5, + "gust_mph": 12.6, + "gust_kph": 20.3, + "uv": 0 + }, + { + "time_epoch": 1732521600, + "time": "2024-11-25 09:00", + "temp_c": 12.4, + "temp_f": 54.3, + "is_day": 1, + "condition": { + "text": "Light drizzle", + "icon": "//cdn.weatherapi.com/weather/64x64/day/266.png", + "code": 1153 + }, + "wind_mph": 6.7, + "wind_kph": 10.8, + "wind_degree": 316, + "wind_dir": "NW", + "pressure_mb": 1013, + "pressure_in": 29.92, + "precip_mm": 0.73, + "precip_in": 0.03, + "snow_cm": 0, + "humidity": 92, + "cloud": 100, + "feelslike_c": 11.4, + "feelslike_f": 52.5, + "windchill_c": 11.4, + "windchill_f": 52.5, + "heatindex_c": 12.4, + "heatindex_f": 54.3, + "dewpoint_c": 11.1, + "dewpoint_f": 52.1, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 2, + "vis_miles": 1, + "gust_mph": 9.8, + "gust_kph": 15.7, + "uv": 0 + }, + { + "time_epoch": 1732525200, + "time": "2024-11-25 10:00", + "temp_c": 12.4, + "temp_f": 54.4, + "is_day": 1, + "condition": { + "text": "Light rain", + "icon": "//cdn.weatherapi.com/weather/64x64/day/296.png", + "code": 1183 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 290, + "wind_dir": "WNW", + "pressure_mb": 1014, + "pressure_in": 29.95, + "precip_mm": 0.89, + "precip_in": 0.04, + "snow_cm": 0, + "humidity": 92, + "cloud": 100, + "feelslike_c": 11.8, + "feelslike_f": 53.3, + "windchill_c": 11.8, + "windchill_f": 53.3, + "heatindex_c": 12.5, + "heatindex_f": 54.4, + "dewpoint_c": 11.2, + "dewpoint_f": 52.1, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 9, + "vis_miles": 5, + "gust_mph": 7.5, + "gust_kph": 12.1, + "uv": 0 + }, + { + "time_epoch": 1732528800, + "time": "2024-11-25 11:00", + "temp_c": 12.5, + "temp_f": 54.4, + "is_day": 1, + "condition": { + "text": "Light rain", + "icon": "//cdn.weatherapi.com/weather/64x64/day/296.png", + "code": 1183 + }, + "wind_mph": 6, + "wind_kph": 9.7, + "wind_degree": 311, + "wind_dir": "NW", + "pressure_mb": 1015, + "pressure_in": 29.96, + "precip_mm": 1.36, + "precip_in": 0.05, + "snow_cm": 0, + "humidity": 93, + "cloud": 100, + "feelslike_c": 11.6, + "feelslike_f": 52.9, + "windchill_c": 11.6, + "windchill_f": 52.9, + "heatindex_c": 12.5, + "heatindex_f": 54.4, + "dewpoint_c": 11.3, + "dewpoint_f": 52.3, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 9, + "vis_miles": 5, + "gust_mph": 8.6, + "gust_kph": 13.8, + "uv": 0.1 + }, + { + "time_epoch": 1732532400, + "time": "2024-11-25 12:00", + "temp_c": 11.9, + "temp_f": 53.4, + "is_day": 1, + "condition": { + "text": "Light rain", + "icon": "//cdn.weatherapi.com/weather/64x64/day/296.png", + "code": 1183 + }, + "wind_mph": 8.3, + "wind_kph": 13.3, + "wind_degree": 308, + "wind_dir": "NW", + "pressure_mb": 1016, + "pressure_in": 29.99, + "precip_mm": 2.14, + "precip_in": 0.08, + "snow_cm": 0, + "humidity": 93, + "cloud": 100, + "feelslike_c": 10.4, + "feelslike_f": 50.8, + "windchill_c": 10.4, + "windchill_f": 50.8, + "heatindex_c": 11.9, + "heatindex_f": 53.4, + "dewpoint_c": 10.8, + "dewpoint_f": 51.4, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 9, + "vis_miles": 5, + "gust_mph": 11.6, + "gust_kph": 18.6, + "uv": 0.1 + }, + { + "time_epoch": 1732536000, + "time": "2024-11-25 13:00", + "temp_c": 11.3, + "temp_f": 52.4, + "is_day": 1, + "condition": { + "text": "Light rain shower", + "icon": "//cdn.weatherapi.com/weather/64x64/day/353.png", + "code": 1240 + }, + "wind_mph": 6.7, + "wind_kph": 10.8, + "wind_degree": 302, + "wind_dir": "WNW", + "pressure_mb": 1016, + "pressure_in": 30.01, + "precip_mm": 0.24, + "precip_in": 0.01, + "snow_cm": 0, + "humidity": 89, + "cloud": 100, + "feelslike_c": 10.1, + "feelslike_f": 50.2, + "windchill_c": 10.1, + "windchill_f": 50.2, + "heatindex_c": 11.3, + "heatindex_f": 52.4, + "dewpoint_c": 9.6, + "dewpoint_f": 49.3, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 9.5, + "gust_kph": 15.2, + "uv": 0.1 + }, + { + "time_epoch": 1732539600, + "time": "2024-11-25 14:00", + "temp_c": 11.3, + "temp_f": 52.4, + "is_day": 1, + "condition": { + "text": "Light drizzle", + "icon": "//cdn.weatherapi.com/weather/64x64/day/266.png", + "code": 1153 + }, + "wind_mph": 5.6, + "wind_kph": 9, + "wind_degree": 283, + "wind_dir": "WNW", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0.37, + "precip_in": 0.01, + "snow_cm": 0, + "humidity": 89, + "cloud": 100, + "feelslike_c": 10.4, + "feelslike_f": 50.7, + "windchill_c": 10.4, + "windchill_f": 50.7, + "heatindex_c": 11.3, + "heatindex_f": 52.4, + "dewpoint_c": 9.5, + "dewpoint_f": 49.2, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 2, + "vis_miles": 1, + "gust_mph": 8, + "gust_kph": 12.9, + "uv": 0.1 + }, + { + "time_epoch": 1732543200, + "time": "2024-11-25 15:00", + "temp_c": 11.3, + "temp_f": 52.3, + "is_day": 1, + "condition": { + "text": "Light drizzle", + "icon": "//cdn.weatherapi.com/weather/64x64/day/266.png", + "code": 1153 + }, + "wind_mph": 7.4, + "wind_kph": 11.9, + "wind_degree": 269, + "wind_dir": "W", + "pressure_mb": 1018, + "pressure_in": 30.06, + "precip_mm": 0.45, + "precip_in": 0.02, + "snow_cm": 0, + "humidity": 88, + "cloud": 100, + "feelslike_c": 9.9, + "feelslike_f": 49.7, + "windchill_c": 9.9, + "windchill_f": 49.7, + "heatindex_c": 11.3, + "heatindex_f": 52.3, + "dewpoint_c": 9.4, + "dewpoint_f": 49, + "will_it_rain": 1, + "chance_of_rain": 100, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 2, + "vis_miles": 1, + "gust_mph": 11, + "gust_kph": 17.6, + "uv": 0.1 + }, + { + "time_epoch": 1732546800, + "time": "2024-11-25 16:00", + "temp_c": 11.4, + "temp_f": 52.5, + "is_day": 1, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/day/119.png", + "code": 1006 + }, + "wind_mph": 3.6, + "wind_kph": 5.8, + "wind_degree": 244, + "wind_dir": "WSW", + "pressure_mb": 1018, + "pressure_in": 30.07, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 82, + "cloud": 65, + "feelslike_c": 11.2, + "feelslike_f": 52.1, + "windchill_c": 11.2, + "windchill_f": 52.1, + "heatindex_c": 11.4, + "heatindex_f": 52.5, + "dewpoint_c": 8.4, + "dewpoint_f": 47.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 5.6, + "gust_kph": 9, + "uv": 0.1 + }, + { + "time_epoch": 1732550400, + "time": "2024-11-25 17:00", + "temp_c": 11.4, + "temp_f": 52.4, + "is_day": 1, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/day/176.png", + "code": 1063 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 191, + "wind_dir": "SSW", + "pressure_mb": 1019, + "pressure_in": 30.09, + "precip_mm": 0.02, + "precip_in": 0, + "snow_cm": 0, + "humidity": 82, + "cloud": 58, + "feelslike_c": 10.5, + "feelslike_f": 51, + "windchill_c": 10.5, + "windchill_f": 51, + "heatindex_c": 11.4, + "heatindex_f": 52.4, + "dewpoint_c": 8.4, + "dewpoint_f": 47, + "will_it_rain": 1, + "chance_of_rain": 89, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 8.4, + "gust_kph": 13.5, + "uv": 0 + }, + { + "time_epoch": 1732554000, + "time": "2024-11-25 18:00", + "temp_c": 11.1, + "temp_f": 51.9, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 5.6, + "wind_kph": 9, + "wind_degree": 207, + "wind_dir": "SSW", + "pressure_mb": 1020, + "pressure_in": 30.11, + "precip_mm": 0.02, + "precip_in": 0, + "snow_cm": 0, + "humidity": 85, + "cloud": 89, + "feelslike_c": 10.1, + "feelslike_f": 50.1, + "windchill_c": 10.1, + "windchill_f": 50.1, + "heatindex_c": 11.1, + "heatindex_f": 51.9, + "dewpoint_c": 8.6, + "dewpoint_f": 47.4, + "will_it_rain": 1, + "chance_of_rain": 76, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 9.4, + "gust_kph": 15.2, + "uv": 0 + }, + { + "time_epoch": 1732557600, + "time": "2024-11-25 19:00", + "temp_c": 10.6, + "temp_f": 51.1, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 6, + "wind_kph": 9.7, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1020, + "pressure_in": 30.13, + "precip_mm": 0.04, + "precip_in": 0, + "snow_cm": 0, + "humidity": 88, + "cloud": 88, + "feelslike_c": 9.4, + "feelslike_f": 48.9, + "windchill_c": 9.4, + "windchill_f": 48.9, + "heatindex_c": 10.6, + "heatindex_f": 51.1, + "dewpoint_c": 8.8, + "dewpoint_f": 47.8, + "will_it_rain": 1, + "chance_of_rain": 76, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 10.6, + "gust_kph": 17.1, + "uv": 0 + }, + { + "time_epoch": 1732561200, + "time": "2024-11-25 20:00", + "temp_c": 10.1, + "temp_f": 50.2, + "is_day": 0, + "condition": { + "text": "Patchy rain nearby", + "icon": "//cdn.weatherapi.com/weather/64x64/night/176.png", + "code": 1063 + }, + "wind_mph": 5.6, + "wind_kph": 9, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1021, + "pressure_in": 30.16, + "precip_mm": 0.04, + "precip_in": 0, + "snow_cm": 0, + "humidity": 92, + "cloud": 87, + "feelslike_c": 8.9, + "feelslike_f": 48.1, + "windchill_c": 8.9, + "windchill_f": 48.1, + "heatindex_c": 10.1, + "heatindex_f": 50.2, + "dewpoint_c": 8.8, + "dewpoint_f": 47.9, + "will_it_rain": 1, + "chance_of_rain": 75, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 10.5, + "gust_kph": 16.9, + "uv": 0 + }, + { + "time_epoch": 1732564800, + "time": "2024-11-25 21:00", + "temp_c": 9.8, + "temp_f": 49.6, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1022, + "pressure_in": 30.17, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 93, + "cloud": 18, + "feelslike_c": 8.7, + "feelslike_f": 47.7, + "windchill_c": 8.7, + "windchill_f": 47.7, + "heatindex_c": 9.8, + "heatindex_f": 49.6, + "dewpoint_c": 8.7, + "dewpoint_f": 47.7, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 10.2, + "gust_kph": 16.3, + "uv": 0 + }, + { + "time_epoch": 1732568400, + "time": "2024-11-25 22:00", + "temp_c": 9.6, + "temp_f": 49.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 5.1, + "wind_kph": 8.3, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1022, + "pressure_in": 30.19, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 93, + "cloud": 24, + "feelslike_c": 8.5, + "feelslike_f": 47.4, + "windchill_c": 8.5, + "windchill_f": 47.4, + "heatindex_c": 9.6, + "heatindex_f": 49.4, + "dewpoint_c": 8.6, + "dewpoint_f": 47.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 10.2, + "gust_kph": 16.5, + "uv": 0 + }, + { + "time_epoch": 1732572000, + "time": "2024-11-25 23:00", + "temp_c": 9.5, + "temp_f": 49.1, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 4.9, + "wind_kph": 7.9, + "wind_degree": 198, + "wind_dir": "SSW", + "pressure_mb": 1023, + "pressure_in": 30.2, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 93, + "cloud": 26, + "feelslike_c": 8.4, + "feelslike_f": 47.2, + "windchill_c": 8.4, + "windchill_f": 47.2, + "heatindex_c": 9.5, + "heatindex_f": 49.1, + "dewpoint_c": 8.5, + "dewpoint_f": 47.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 9.8, + "gust_kph": 15.8, + "uv": 0 + } + ] + }, + { + "date": "2024-11-23", + "date_epoch": 1732320000, + "day": { + "maxtemp_c": 13.1, + "maxtemp_f": 55.7, + "mintemp_c": 4, + "mintemp_f": 39.3, + "avgtemp_c": 8.1, + "avgtemp_f": 46.6, + "maxwind_mph": 13, + "maxwind_kph": 20.9, + "totalprecip_mm": 0, + "totalprecip_in": 0, + "totalsnow_cm": 0, + "avgvis_km": 10, + "avgvis_miles": 6, + "avghumidity": 69, + "daily_will_it_rain": 0, + "daily_chance_of_rain": 0, + "daily_will_it_snow": 0, + "daily_chance_of_snow": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/day/116.png", + "code": 1003 + }, + "uv": 0.3 + }, + "astro": { + "sunrise": "08:10 AM", + "sunset": "05:27 PM", + "moonrise": "12:08 AM", + "moonset": "02:13 PM", + "moon_phase": "Last Quarter", + "moon_illumination": 51, + "is_moon_up": 0, + "is_sun_up": 0 + }, + "hour": [ + { + "time_epoch": 1732316400, + "time": "2024-11-23 00:00", + "temp_c": 5.6, + "temp_f": 42, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 6.7, + "wind_kph": 10.8, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1022, + "pressure_in": 30.19, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 81, + "cloud": 17, + "feelslike_c": 3.2, + "feelslike_f": 37.7, + "windchill_c": 3.2, + "windchill_f": 37.7, + "heatindex_c": 5.6, + "heatindex_f": 42, + "dewpoint_c": 2.6, + "dewpoint_f": 36.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 13.7, + "gust_kph": 22, + "uv": 0 + }, + { + "time_epoch": 1732320000, + "time": "2024-11-23 01:00", + "temp_c": 5.8, + "temp_f": 42.4, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 6.9, + "wind_kph": 11.2, + "wind_degree": 141, + "wind_dir": "SE", + "pressure_mb": 1022, + "pressure_in": 30.17, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 80, + "cloud": 47, + "feelslike_c": 3.3, + "feelslike_f": 38, + "windchill_c": 3.3, + "windchill_f": 38, + "heatindex_c": 5.8, + "heatindex_f": 42.4, + "dewpoint_c": 2.5, + "dewpoint_f": 36.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 13.4, + "gust_kph": 21.6, + "uv": 0 + }, + { + "time_epoch": 1732323600, + "time": "2024-11-23 02:00", + "temp_c": 5.6, + "temp_f": 42.1, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 8.3, + "wind_kph": 13.3, + "wind_degree": 137, + "wind_dir": "SE", + "pressure_mb": 1021, + "pressure_in": 30.14, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 79, + "cloud": 56, + "feelslike_c": 2.8, + "feelslike_f": 37, + "windchill_c": 2.8, + "windchill_f": 37, + "heatindex_c": 5.6, + "heatindex_f": 42.1, + "dewpoint_c": 2.3, + "dewpoint_f": 36.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 15.3, + "gust_kph": 24.7, + "uv": 0 + }, + { + "time_epoch": 1732327200, + "time": "2024-11-23 03:00", + "temp_c": 5.1, + "temp_f": 41.3, + "is_day": 0, + "condition": { + "text": "Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/119.png", + "code": 1006 + }, + "wind_mph": 9.8, + "wind_kph": 15.8, + "wind_degree": 133, + "wind_dir": "SE", + "pressure_mb": 1020, + "pressure_in": 30.13, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 79, + "cloud": 86, + "feelslike_c": 1.8, + "feelslike_f": 35.3, + "windchill_c": 1.8, + "windchill_f": 35.3, + "heatindex_c": 5.2, + "heatindex_f": 41.3, + "dewpoint_c": 1.9, + "dewpoint_f": 35.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 17.6, + "gust_kph": 28.4, + "uv": 0 + }, + { + "time_epoch": 1732330800, + "time": "2024-11-23 04:00", + "temp_c": 4.8, + "temp_f": 40.7, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 10.5, + "wind_kph": 16.9, + "wind_degree": 130, + "wind_dir": "SE", + "pressure_mb": 1020, + "pressure_in": 30.12, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 79, + "cloud": 44, + "feelslike_c": 1.3, + "feelslike_f": 34.3, + "windchill_c": 1.3, + "windchill_f": 34.3, + "heatindex_c": 4.9, + "heatindex_f": 40.7, + "dewpoint_c": 1.5, + "dewpoint_f": 34.7, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 18.1, + "gust_kph": 29.1, + "uv": 0 + }, + { + "time_epoch": 1732334400, + "time": "2024-11-23 05:00", + "temp_c": 4.3, + "temp_f": 39.7, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11, + "wind_kph": 17.6, + "wind_degree": 130, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.1, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 80, + "cloud": 46, + "feelslike_c": 0.5, + "feelslike_f": 32.8, + "windchill_c": 0.5, + "windchill_f": 32.8, + "heatindex_c": 4.3, + "heatindex_f": 39.7, + "dewpoint_c": 1.2, + "dewpoint_f": 34.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19.1, + "gust_kph": 30.8, + "uv": 0 + }, + { + "time_epoch": 1732338000, + "time": "2024-11-23 06:00", + "temp_c": 4, + "temp_f": 39.3, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.08, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 80, + "cloud": 39, + "feelslike_c": 0.1, + "feelslike_f": 32.2, + "windchill_c": 0.1, + "windchill_f": 32.2, + "heatindex_c": 4, + "heatindex_f": 39.3, + "dewpoint_c": 0.9, + "dewpoint_f": 33.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19.8, + "gust_kph": 31.8, + "uv": 0 + }, + { + "time_epoch": 1732341600, + "time": "2024-11-23 07:00", + "temp_c": 4, + "temp_f": 39.3, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 138, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.08, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 78, + "cloud": 26, + "feelslike_c": 0.1, + "feelslike_f": 32.2, + "windchill_c": 0.1, + "windchill_f": 32.2, + "heatindex_c": 4, + "heatindex_f": 39.3, + "dewpoint_c": 0.6, + "dewpoint_f": 33, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19.9, + "gust_kph": 32, + "uv": 0 + }, + { + "time_epoch": 1732345200, + "time": "2024-11-23 08:00", + "temp_c": 4.1, + "temp_f": 39.4, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 10.5, + "wind_kph": 16.9, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.09, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 75, + "cloud": 7, + "feelslike_c": 0.4, + "feelslike_f": 32.6, + "windchill_c": 0.4, + "windchill_f": 32.6, + "heatindex_c": 4.1, + "heatindex_f": 39.4, + "dewpoint_c": 0.1, + "dewpoint_f": 32.1, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 18.8, + "gust_kph": 30.2, + "uv": 0 + }, + { + "time_epoch": 1732348800, + "time": "2024-11-23 09:00", + "temp_c": 4.6, + "temp_f": 40.3, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 10.7, + "wind_kph": 17.3, + "wind_degree": 143, + "wind_dir": "SE", + "pressure_mb": 1019, + "pressure_in": 30.09, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 71, + "cloud": 13, + "feelslike_c": 1, + "feelslike_f": 33.7, + "windchill_c": 1, + "windchill_f": 33.7, + "heatindex_c": 4.6, + "heatindex_f": 40.4, + "dewpoint_c": -0.2, + "dewpoint_f": 31.7, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 19, + "gust_kph": 30.5, + "uv": 0 + }, + { + "time_epoch": 1732352400, + "time": "2024-11-23 10:00", + "temp_c": 6.6, + "temp_f": 43.9, + "is_day": 1, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/day/116.png", + "code": 1003 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 146, + "wind_dir": "SSE", + "pressure_mb": 1019, + "pressure_in": 30.08, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 63, + "cloud": 49, + "feelslike_c": 3.4, + "feelslike_f": 38, + "windchill_c": 3.4, + "windchill_f": 38, + "heatindex_c": 6.6, + "heatindex_f": 43.9, + "dewpoint_c": 0.2, + "dewpoint_f": 32.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 17.5, + "gust_kph": 28.2, + "uv": 0.4 + }, + { + "time_epoch": 1732356000, + "time": "2024-11-23 11:00", + "temp_c": 7.4, + "temp_f": 45.3, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.4, + "wind_kph": 18.4, + "wind_degree": 148, + "wind_dir": "SSE", + "pressure_mb": 1018, + "pressure_in": 30.06, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 76, + "cloud": 0, + "feelslike_c": 6, + "feelslike_f": 42.7, + "windchill_c": 6, + "windchill_f": 42.7, + "heatindex_c": 8.7, + "heatindex_f": 47.7, + "dewpoint_c": 1.3, + "dewpoint_f": 34.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 15.9, + "gust_kph": 25.5, + "uv": 0.9 + }, + { + "time_epoch": 1732359600, + "time": "2024-11-23 12:00", + "temp_c": 10.4, + "temp_f": 50.8, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11, + "wind_kph": 17.6, + "wind_degree": 149, + "wind_dir": "SSE", + "pressure_mb": 1018, + "pressure_in": 30.07, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 56, + "cloud": 21, + "feelslike_c": 8.2, + "feelslike_f": 46.7, + "windchill_c": 8.2, + "windchill_f": 46.7, + "heatindex_c": 10.5, + "heatindex_f": 50.8, + "dewpoint_c": 2.2, + "dewpoint_f": 35.9, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 14.7, + "gust_kph": 23.6, + "uv": 1.3 + }, + { + "time_epoch": 1732363200, + "time": "2024-11-23 13:00", + "temp_c": 12.3, + "temp_f": 54.2, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.4, + "wind_kph": 18.4, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1017, + "pressure_in": 30.04, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 52, + "cloud": 22, + "feelslike_c": 10.5, + "feelslike_f": 50.8, + "windchill_c": 10.5, + "windchill_f": 50.8, + "heatindex_c": 12.3, + "heatindex_f": 54.2, + "dewpoint_c": 2.8, + "dewpoint_f": 37, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 14.9, + "gust_kph": 23.9, + "uv": 1.6 + }, + { + "time_epoch": 1732366800, + "time": "2024-11-23 14:00", + "temp_c": 13, + "temp_f": 55.4, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 10.3, + "wind_kph": 16.6, + "wind_degree": 149, + "wind_dir": "SSE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 54, + "cloud": 12, + "feelslike_c": 11.5, + "feelslike_f": 52.7, + "windchill_c": 11.5, + "windchill_f": 52.7, + "heatindex_c": 13, + "heatindex_f": 55.4, + "dewpoint_c": 3.8, + "dewpoint_f": 38.9, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 14, + "gust_kph": 22.6, + "uv": 1.4 + }, + { + "time_epoch": 1732370400, + "time": "2024-11-23 15:00", + "temp_c": 13.1, + "temp_f": 55.7, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.4, + "wind_kph": 18.4, + "wind_degree": 150, + "wind_dir": "SSE", + "pressure_mb": 1016, + "pressure_in": 30.01, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 54, + "cloud": 22, + "feelslike_c": 11.5, + "feelslike_f": 52.7, + "windchill_c": 11.5, + "windchill_f": 52.7, + "heatindex_c": 13.2, + "heatindex_f": 55.7, + "dewpoint_c": 4.2, + "dewpoint_f": 39.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 16.8, + "gust_kph": 27.1, + "uv": 0.9 + }, + { + "time_epoch": 1732374000, + "time": "2024-11-23 16:00", + "temp_c": 12.5, + "temp_f": 54.4, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 10.7, + "wind_kph": 17.3, + "wind_degree": 148, + "wind_dir": "SSE", + "pressure_mb": 1017, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 57, + "cloud": 14, + "feelslike_c": 10.7, + "feelslike_f": 51.3, + "windchill_c": 10.7, + "windchill_f": 51.3, + "heatindex_c": 12.5, + "heatindex_f": 54.4, + "dewpoint_c": 4.1, + "dewpoint_f": 39.5, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 17.5, + "gust_kph": 28.1, + "uv": 0.4 + }, + { + "time_epoch": 1732377600, + "time": "2024-11-23 17:00", + "temp_c": 11.2, + "temp_f": 52.1, + "is_day": 1, + "condition": { + "text": "Sunny", + "icon": "//cdn.weatherapi.com/weather/64x64/day/113.png", + "code": 1000 + }, + "wind_mph": 11.2, + "wind_kph": 18, + "wind_degree": 141, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 61, + "cloud": 22, + "feelslike_c": 9, + "feelslike_f": 48.2, + "windchill_c": 9, + "windchill_f": 48.2, + "heatindex_c": 11.2, + "heatindex_f": 52.1, + "dewpoint_c": 4, + "dewpoint_f": 39.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 20.2, + "gust_kph": 32.5, + "uv": 0 + }, + { + "time_epoch": 1732381200, + "time": "2024-11-23 18:00", + "temp_c": 10.2, + "temp_f": 50.4, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 11.6, + "wind_kph": 18.7, + "wind_degree": 141, + "wind_dir": "SE", + "pressure_mb": 1016, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 64, + "cloud": 47, + "feelslike_c": 7.8, + "feelslike_f": 46, + "windchill_c": 7.8, + "windchill_f": 46, + "heatindex_c": 10.2, + "heatindex_f": 50.4, + "dewpoint_c": 3.8, + "dewpoint_f": 38.9, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.2, + "gust_kph": 35.7, + "uv": 0 + }, + { + "time_epoch": 1732384800, + "time": "2024-11-23 19:00", + "temp_c": 10, + "temp_f": 50.1, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.3, + "wind_kph": 19.8, + "wind_degree": 144, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.02, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 66, + "cloud": 62, + "feelslike_c": 7.5, + "feelslike_f": 45.4, + "windchill_c": 7.5, + "windchill_f": 45.4, + "heatindex_c": 10, + "heatindex_f": 50.1, + "dewpoint_c": 4, + "dewpoint_f": 39.2, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.8, + "gust_kph": 36.8, + "uv": 0 + }, + { + "time_epoch": 1732388400, + "time": "2024-11-23 20:00", + "temp_c": 10, + "temp_f": 50, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 143, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 68, + "cloud": 57, + "feelslike_c": 7.3, + "feelslike_f": 45.2, + "windchill_c": 7.3, + "windchill_f": 45.2, + "heatindex_c": 10, + "heatindex_f": 50, + "dewpoint_c": 4.3, + "dewpoint_f": 39.8, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.6, + "gust_kph": 36.3, + "uv": 0 + }, + { + "time_epoch": 1732392000, + "time": "2024-11-23 21:00", + "temp_c": 9.7, + "temp_f": 49.5, + "is_day": 0, + "condition": { + "text": "Partly Cloudy ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/116.png", + "code": 1003 + }, + "wind_mph": 12.5, + "wind_kph": 20.2, + "wind_degree": 142, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 71, + "cloud": 46, + "feelslike_c": 7, + "feelslike_f": 44.6, + "windchill_c": 7, + "windchill_f": 44.6, + "heatindex_c": 9.7, + "heatindex_f": 49.5, + "dewpoint_c": 4.6, + "dewpoint_f": 40.3, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 22.3, + "gust_kph": 35.9, + "uv": 0 + }, + { + "time_epoch": 1732395600, + "time": "2024-11-23 22:00", + "temp_c": 9.5, + "temp_f": 49.1, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 13, + "wind_kph": 20.9, + "wind_degree": 139, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 73, + "cloud": 24, + "feelslike_c": 6.6, + "feelslike_f": 44, + "windchill_c": 6.6, + "windchill_f": 44, + "heatindex_c": 9.5, + "heatindex_f": 49.1, + "dewpoint_c": 5, + "dewpoint_f": 41, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23, + "gust_kph": 37, + "uv": 0 + }, + { + "time_epoch": 1732399200, + "time": "2024-11-23 23:00", + "temp_c": 9.3, + "temp_f": 48.8, + "is_day": 0, + "condition": { + "text": "Clear ", + "icon": "//cdn.weatherapi.com/weather/64x64/night/113.png", + "code": 1000 + }, + "wind_mph": 12.8, + "wind_kph": 20.5, + "wind_degree": 140, + "wind_dir": "SE", + "pressure_mb": 1017, + "pressure_in": 30.03, + "precip_mm": 0, + "precip_in": 0, + "snow_cm": 0, + "humidity": 76, + "cloud": 21, + "feelslike_c": 6.5, + "feelslike_f": 43.7, + "windchill_c": 6.5, + "windchill_f": 43.7, + "heatindex_c": 9.3, + "heatindex_f": 48.8, + "dewpoint_c": 5.3, + "dewpoint_f": 41.6, + "will_it_rain": 0, + "chance_of_rain": 0, + "will_it_snow": 0, + "chance_of_snow": 0, + "vis_km": 10, + "vis_miles": 6, + "gust_mph": 23, + "gust_kph": 37, + "uv": 0 + } + ] + } + ] + } +} \ No newline at end of file diff --git a/src/test/resources/WeatherAPI/wrong-apikey.json b/src/test/resources/WeatherAPI/wrong-apikey.json new file mode 100644 index 0000000..2e08784 --- /dev/null +++ b/src/test/resources/WeatherAPI/wrong-apikey.json @@ -0,0 +1,6 @@ +{ + "error": { + "code": 2008, + "message": "API key has been disabled." + } +} \ No newline at end of file diff --git a/weather-app.png b/weather-app.png new file mode 100644 index 0000000..c1756d9 Binary files /dev/null and b/weather-app.png differ