FVEABA / meteo_functions.py
Kubas126cz's picture
JHA_Solarmon_API
696a9b4
import pandas as pd
import requests
import numpy as np
import streamlit as st
import json
from datetime import date, timedelta
lat = 49.13114
lon = 15.18067
def get_meteo_data(start_date, end_date):
url = f"https://archive-api.open-meteo.com/v1/archive?latitude={lat}&longitude={lon}&start_date={start_date}&end_date={end_date}&hourly=temperature_2m,relative_humidity_2m,surface_pressure,cloudcover,windspeed_10m,wind_direction_10m,direct_normal_irradiance,diffuse_radiation,shortwave_radiation&timezone=UTC"
response = requests.get(url)
if response.status_code == 200:
weather_data = response.json()
if "hourly" in weather_data:
df_weather = pd.DataFrame({
"DT": pd.to_datetime(weather_data["hourly"]["time"]),
"Temperature_2m": weather_data["hourly"].get("temperature_2m", []),
"Relative_Humidity_2m": weather_data["hourly"].get("relative_humidity_2m", []),
"Surface_Pressure": weather_data["hourly"].get("surface_pressure", []),
"Cloud_Cover": weather_data["hourly"].get("cloudcover", []),
"Wind_Speed_10m": weather_data["hourly"].get("windspeed_10m", []),
"Wind_Direction_10m": weather_data["hourly"].get("wind_direction_10m", []),
"RAD": weather_data["hourly"].get("shortwave_radiation", [])
})
df_weather["DT"] = df_weather["DT"].dt.tz_localize(None)
df_weather["wind_u"] = df_weather["Wind_Speed_10m"] * np.sin(np.radians(df_weather["Wind_Direction_10m"]))
df_weather["wind_v"] = df_weather["Wind_Speed_10m"] * np.cos(np.radians(df_weather["Wind_Direction_10m"]))
df_weather.drop(columns=["Wind_Speed_10m", "Wind_Direction_10m"], inplace=True)
else:
print("Chyba: Odpověď neobsahuje klíč 'hourly'.")
else:
print(f"Chyba při stahování dat: {response.status_code}, odpověď: {response.text}")
return df_weather
def get_air_quality_data(start_date, end_date):
url = f"https://air-quality-api.open-meteo.com/v1/air-quality?latitude={lat}&longitude={lon}&start_date={start_date}&end_date={end_date}&hourly=pm10,ozone&timezone=UTC"
response = requests.get(url)
if response.status_code == 200:
air_quality_data = response.json()
if "hourly" in air_quality_data:
df_air_quality = pd.DataFrame({
"DT": pd.to_datetime(air_quality_data["hourly"]["time"]),
"PM10": air_quality_data["hourly"].get("pm10", []),
"Ozone": air_quality_data["hourly"].get("ozone", [])
})
df_air_quality["DT"] = df_air_quality["DT"].dt.tz_localize(None)
else:
print("Chyba: Odpověď neobsahuje klíč 'hourly'.")
else:
print(f"Chyba při stahování dat: {response.status_code}, odpověď: {response.text}")
return df_air_quality
def create_time_cycles(weather_dataset):
weather_dataset["hour"] = weather_dataset["DT"].dt.hour
weather_dataset["day_of_year"] = weather_dataset["DT"].dt.dayofyear
weather_dataset["sin_hour"] = np.sin(2 * np.pi * weather_dataset["hour"] / 24)
weather_dataset["cos_hour"] = np.cos(2 * np.pi * weather_dataset["hour"] / 24)
weather_dataset["sin_day_of_year"] = np.sin(2 * np.pi * weather_dataset["day_of_year"] / 365)
weather_dataset["cos_day_of_year"] = np.cos(2 * np.pi * weather_dataset["day_of_year"] / 365)
weather_dataset.drop(columns=["hour", "day_of_year"], inplace=True)
return weather_dataset
def get_forecast_meteo_data(start_date, end_date):
url = f"https://api.open-meteo.com/v1/forecast?latitude={lat}&longitude={lon}&start_date={start_date}&end_date={end_date}&hourly=temperature_2m,relative_humidity_2m,surface_pressure,cloudcover,windspeed_10m,wind_direction_10m,direct_normal_irradiance,diffuse_radiation,shortwave_radiation&timezone=UTC"
# Odeslání požadavku
response = requests.get(url)
if response.status_code == 200:
weather_data = response.json()
if "hourly" in weather_data:
df_weather = pd.DataFrame({
"DT": pd.to_datetime(weather_data["hourly"]["time"]),
"Temperature_2m": weather_data["hourly"].get("temperature_2m", []),
"Relative_Humidity_2m": weather_data["hourly"].get("relative_humidity_2m", []),
"Surface_Pressure": weather_data["hourly"].get("surface_pressure", []),
"Cloud_Cover": weather_data["hourly"].get("cloudcover", []),
"Wind_Speed_10m": weather_data["hourly"].get("windspeed_10m", []),
"Wind_Direction_10m": weather_data["hourly"].get("wind_direction_10m", []),
"RAD": weather_data["hourly"].get("shortwave_radiation", [])
})
df_weather["DT"] = df_weather["DT"].dt.tz_localize(None)
df_weather["wind_u"] = df_weather["Wind_Speed_10m"] * np.sin(np.radians(df_weather["Wind_Direction_10m"]))
df_weather["wind_v"] = df_weather["Wind_Speed_10m"] * np.cos(np.radians(df_weather["Wind_Direction_10m"]))
df_weather.drop(columns=["Wind_Speed_10m", "Wind_Direction_10m"], inplace=True)
else:
print("Chyba: Odpověď neobsahuje klíč 'hourly'.")
else:
print(f"Chyba při stahování dat: {response.status_code}, odpověď: {response.text}")
return df_weather
def get_air_quality_forecast(start_date, end_date):
url = f"https://air-quality-api.open-meteo.com/v1/air-quality?latitude={lat}&longitude={lon}&start_date={start_date}&end_date={end_date}&hourly=pm10,ozone&timezone=UTC"
response = requests.get(url)
if response.status_code == 200:
air_quality_data = response.json()
if "hourly" in air_quality_data:
times = air_quality_data["hourly"].get("time", [])
pm10 = air_quality_data["hourly"].get("pm10", [])
ozone = air_quality_data["hourly"].get("ozone", [])
if len(times) == len(pm10) == len(ozone):
df_air_quality = pd.DataFrame({
"DT": pd.to_datetime(times),
"PM10": pm10,
"Ozone": ozone
})
df_air_quality["DT"] = df_air_quality["DT"].dt.tz_localize(None)
else:
print("Chyba: Pola mají různé délky!")
print(f"Počet časových údajů: {len(times)}, Počet PM10: {len(pm10)}, Počet Ozone: {len(ozone)}")
df_air_quality = pd.DataFrame()
else:
print("Chyba: Odpověď neobsahuje klíč 'hourly'.")
df_air_quality = pd.DataFrame()
else:
print(f"Chyba při stahování dat: {response.status_code}, odpověď: {response.text}")
df_air_quality = pd.DataFrame()
return df_air_quality
def get_data_for_day(day: date, username: str, password: str) -> list[dict]:
"""
Stáhne data z API pomocí POST požadavku pro daný den.
:param day: Datum typu `datetime.date`
:param username: Uživatelské jméno pro API
:param password: Heslo pro API
:return: Seznam měření (dictů) pro daný den
"""
url = f"https://aba.solarmon.eu/rest-server/?q=getDataPredMod&date={day.strftime('%Y-%m-%d')}"
payload = {
'username': username,
'password': password
}
try:
response = requests.post(url, data=payload)
response.raise_for_status()
data = response.json()
data = json.loads(data)
return data.get("data", [])
except (requests.RequestException, ValueError) as e:
st.error(f"Chyba při načítání dat pro {day}: {e}")
return []
def load_and_check_data_solarmon(start_date: date, end_date: date, username: str, password: str) -> pd.DataFrame:
current_date = start_date
all_data = []
while current_date <= end_date + timedelta(days=1):# pridame dalsi den kvuli poslednim 2 hodinam
daily_data = pd.DataFrame(get_data_for_day(current_date, username, password))
all_data.append(daily_data)
current_date += timedelta(days=1)
solarmon_meteo = pd.concat(all_data).sort_index()
solarmon_meteo = pd.DataFrame(solarmon_meteo)
solarmon_meteo["time"] = pd.to_datetime(solarmon_meteo["time"]) # + pd.Timedelta(minutes=5) # experimentalne zjistit zda je potreba
solarmon_meteo["time"] = solarmon_meteo["time"].dt.tz_localize("Europe/Prague").dt.tz_convert("UTC")
solarmon_meteo = solarmon_meteo.set_index("time")
# převody typů a kontrola
solarmon_meteo["int_sol_irr"] = pd.to_numeric(solarmon_meteo["int_sol_irr"], errors='coerce')
solarmon_meteo["tmp_module"] = pd.to_numeric(solarmon_meteo["tmp_module"], errors='coerce')
solarmon_meteo["energy"] = pd.to_numeric(solarmon_meteo["energy"], errors='coerce')
# Resample na hodinové intervaly
solarmon_meteo = solarmon_meteo.resample('1h').agg({
'int_sol_irr': 'mean',
'wind_vel': 'mean',
'tmp_amb': 'mean',
'tmp_module': 'mean',
'energy': 'sum'
})
solarmon_meteo['energy'] = solarmon_meteo['energy'] / 1000
solarmon_meteo.rename_axis("DT", inplace=True)
solarmon_meteo.rename(
columns={
'int_sol_irr': 'Me',
'tmp_module': 'tp',
'energy': 'output',
'tmp_amb': 'to'
},
inplace=True
)
solarmon_meteo.drop(['wind_vel'], axis=1, inplace=True)
solarmon_meteo.index = pd.to_datetime(solarmon_meteo.index)
start_datetime = pd.to_datetime(start_date).tz_localize('UTC')
end_datetime = pd.to_datetime(end_date).tz_localize('UTC') + pd.Timedelta(days=1)
solarmon_meteo = solarmon_meteo[(solarmon_meteo.index >= start_datetime) & (solarmon_meteo.index < end_datetime)]
# solarmon_meteo.isnull().values.any() kontroluje zda neni NaN hodnota
solarmon_meteo = solarmon_meteo.reset_index(drop=False) # resetovani indexu
# df_meteo["DT"] = df_meteo["DT"].dt.tz_localize("UTC")
#df_meteo = get_meteo_data(previous_date, selected_date)
#df_air_quality = get_air_quality_data(previous_date, selected_date)
#df_meteo = df_meteo.merge(df_air_quality, on="DT", how="inner")
#df = df.merge(df_meteo, on="DT", how="inner")
#df = create_time_cycles(df)
return solarmon_meteo
# return df[2:26]