Spaces:
Sleeping
Sleeping
| 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] | |