#!/usr/bin python3 # -*- coding: utf-8 -*- """ This part of the code exposes functions to fetch data from the open-meteo.com API. The bellow code is the generated by the https://open-meteo.com/en/docs itself. It has been slighly modified to return a dictionary with all the information nedeed. """ import openmeteo_requests import requests_cache #import pandas as pd from retry_requests import retry class WeatherHelper: def __init__(self, latitude: float, longitude: float, timezone: str): self.latitude = latitude self.longitude = longitude self.timezone = timezone def fetch_open_meteo_data(self) -> dict: # Setup the Open-Meteo API client with cache and retry on error cache_session = requests_cache.CachedSession('.cache', expire_after = 3600) retry_session = retry(cache_session, retries = 5, backoff_factor = 0.2) openmeteo = openmeteo_requests.Client(session = retry_session) # Make sure all required weather variables are listed here # The order of variables in hourly or daily is important to assign them correctly below url = "https://api.open-meteo.com/v1/forecast" params = { "latitude": self.latitude, "longitude": self.longitude, "current": ["temperature_2m", "is_day", "weather_code"], "daily": ["weather_code", "temperature_2m_max", "temperature_2m_min"], "timezone": self.timezone, "forecast_days": 3 } responses = openmeteo.weather_api(url, params=params) # Process first location. Add a for-loop for multiple locations or weather models response = responses[0] #print(f"Coordinates {response.Latitude()}°N {response.Longitude()}°E") #print(f"Elevation {response.Elevation()} m asl") #print(f"Timezone {response.Timezone()} {response.TimezoneAbbreviation()}") #print(f"Timezone difference to GMT+0 {response.UtcOffsetSeconds()} s") # Current values. The order of variables needs to be the same as requested. current = response.Current() current_temperature_2m = current.Variables(0).Value() current_is_day = current.Variables(1).Value() current_weather_code = current.Variables(2).Value() #print(f"Current time {current.Time()}") #print(f"Current temperature_2m {current_temperature_2m}") #print(f"Current is_day {current_is_day}") #print(f"Current weather_code {current_weather_code}") # Process daily data. The order of variables needs to be the same as requested. daily = response.Daily() daily_weather_code = daily.Variables(0).ValuesAsNumpy() daily_temperature_2m_max = daily.Variables(1).ValuesAsNumpy() daily_temperature_2m_min = daily.Variables(2).ValuesAsNumpy() #daily_data = {"date": pd.date_range( # start = pd.to_datetime(daily.Time(), unit = "s", utc = True), # end = pd.to_datetime(daily.TimeEnd(), unit = "s", utc = True), # freq = pd.Timedelta(seconds = daily.Interval()), # inclusive = "left" #)} #daily_data["weather_code"] = daily_weather_code #daily_data["temperature_2m_max"] = daily_temperature_2m_max #daily_data["temperature_2m_min"] = daily_temperature_2m_min #daily_dataframe = pd.DataFrame(data = daily_data) #print(daily_dataframe) # Here we are creating the dictionary that will be returned weather_data = {} weather_data['current_temperature_2m'] = int(current_temperature_2m) weather_data['current_is_day'] = int(current_is_day) weather_data['current_weather_code'] = int(current_weather_code) weather_data['tomorrow_temperature_2m_max'] = int(daily_temperature_2m_max[1]) weather_data['tomorrow_temperature_2m_min'] = int(daily_temperature_2m_min[1]) weather_data['tomorrow_weather_code'] = int(daily_weather_code[1]) weather_data['day_after_temperature_2m_max'] = int(daily_temperature_2m_max[2]) weather_data['day_after_temperature_2m_min'] = int(daily_temperature_2m_min[2]) weather_data['day_after_weather_code'] = int(daily_weather_code[2]) return weather_data def iconize_weather(self, weather_code: int) -> str: # This are the WMO Weather interpretation codes (WW) # More info in: https://open-meteo.com/en/docs at the end of the page. # Here we only put the name of the icons, the path will be handle in main() if weather_code >= 100: weather_icon = "placeholder32.bmp" return weather_icon if weather_code in [0]: weather_icon = "sunny-icon32.bmp" elif weather_code in [1, 2, 3]: weather_icon = "None" elif weather_code in [45, 48]: weather_icon = "None" elif weather_code in [51, 53, 55]: weather_icon = "None" elif weather_code in [56, 57]: weather_icon = "None" elif weather_code in [61, 63, 65]: weather_icon = "None" elif weather_code in [66, 67]: weather_icon = "None" elif weather_code in [71, 73, 75]: weather_icon = "None" elif weather_code in [77]: weather_icon = "None" elif weather_code in [80, 81, 82]: weather_icon = "None" elif weather_code in [85, 86]: weather_icon = "None" elif weather_code in [95]: weather_icon = "None" elif weather_code in [96, 99]: weather_icon = "None" else: weather_icon = "None" # If there is no an icon for that code, search the next highest icon if weather_icon == "None": weather_icon = self.iconize_weather(weather_code + 1) return weather_icon