You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
4.1 KiB
120 lines
4.1 KiB
from astral import LocationInfo
|
|
from astral.sun import sun
|
|
import pytz
|
|
from datetime import datetime
|
|
import requests
|
|
|
|
|
|
def fetch_weather_data(api_key, location, logger):
|
|
"""
|
|
Haalt de weersvoorspelling op van OpenWeatherMap.
|
|
|
|
Parameters:
|
|
- api_key: API sleutel voor OpenWeatherMap
|
|
- location: Locatienaam (stad)
|
|
- logger: Logger instance
|
|
|
|
Returns:
|
|
- JSON data van de weersvoorspelling
|
|
"""
|
|
base_url = "https://api.openweathermap.org/data/2.5/forecast"
|
|
params = {
|
|
'q': location,
|
|
'appid': api_key,
|
|
'units': 'metric'
|
|
}
|
|
|
|
try:
|
|
response = requests.get(base_url, params=params)
|
|
response.raise_for_status()
|
|
logger.info(f"Weather data fetched successfully for {location}.")
|
|
return response.json()
|
|
except requests.RequestException as e:
|
|
logger.error(f"Error fetching weather data: {e}")
|
|
return None
|
|
|
|
|
|
def get_sun_times(utc_datetime, location_name="Rijswijk", country="Netherlands", logger=None):
|
|
"""
|
|
Haalt de zonsopgang en zonsondergang op voor een bepaalde UTC tijd en locatie.
|
|
|
|
Returns:
|
|
- sunrise, sunset (beide datetime objects in UTC).
|
|
"""
|
|
location = LocationInfo(location_name, country,
|
|
"Europe/Amsterdam", 52.0345, 4.3186)
|
|
|
|
# Bereken zon-op/zon-onder tijden met Astral
|
|
sun_times = sun(location.observer,
|
|
date=utc_datetime.date(), tzinfo=pytz.utc)
|
|
|
|
# Overtuig dat het datetime-objecten zijn
|
|
sunrise = sun_times["sunrise"]
|
|
sunset = sun_times["sunset"]
|
|
|
|
if isinstance(sunrise, str): # Als het toch een string is, fix het
|
|
sunrise = datetime.fromisoformat(sunrise).replace(tzinfo=pytz.utc)
|
|
if isinstance(sunset, str):
|
|
sunset = datetime.fromisoformat(sunset).replace(tzinfo=pytz.utc)
|
|
|
|
if logger:
|
|
logger.debug(
|
|
f"For {utc_datetime.date()} in {location_name}: Sunrise at {sunrise} , Sunset at {sunset} ")
|
|
|
|
return sunrise, sunset
|
|
|
|
|
|
def estimate_solar_performance(entry, utc_dt, location, sunrise, sunset, logger):
|
|
"""
|
|
Schat de zonne-energieproductie op basis van de zonshoogte en weersfactoren.
|
|
|
|
Parameters:
|
|
- entry: JSON entry met de weerdata
|
|
- utc_dt: Tijdstip van de voorspelling (UTC)
|
|
- location: Naam van de locatie voor berekening van zonsopgang/zonsondergang
|
|
- logger: Logger voor debugging
|
|
|
|
Returns:
|
|
- Een percentage (0-100) dat de zonne-energieproductie schat.
|
|
"""
|
|
|
|
# 🚀 Zorg ervoor dat sunrise en sunset datetime-objecten zijn
|
|
if isinstance(sunrise, str):
|
|
sunrise = datetime.fromisoformat(sunrise).replace(tzinfo=pytz.utc)
|
|
if isinstance(sunset, str):
|
|
sunset = datetime.fromisoformat(sunset).replace(tzinfo=pytz.utc)
|
|
# Temperatuur en bewolking ophalen
|
|
temperature = entry["main"]["temp"]
|
|
cloudiness = entry["clouds"]["all"] # % bewolking
|
|
weather_desc = entry["weather"][0]["description"]
|
|
|
|
# Logging
|
|
logger.debug(
|
|
f"UTC: {utc_dt}, Temp: {temperature}, Clouds: {cloudiness}%, Weather: {weather_desc}")
|
|
|
|
# Stap 1: Bereken een initiële waarde op basis van zonshoogte (factor van 0 tot 1)
|
|
if utc_dt < sunrise or utc_dt > sunset:
|
|
sun_factor = 0.0 # Nacht
|
|
elif utc_dt == sunrise or utc_dt == sunset:
|
|
sun_factor = 0.1 # 10% bij zonsopkomst/ondergang
|
|
else:
|
|
# Bereken de relatieve tijd binnen de zonnedag (0 = zonsopgang, 1 = zonsondergang)
|
|
day_fraction = (utc_dt - sunrise) / (sunset - sunrise)
|
|
# Gebruik een parabolische curve voor maximale intensiteit op het midden van de dag
|
|
sun_factor = -4 * (day_fraction - 0.5) ** 2 + 1
|
|
|
|
sun_factor = max(0, min(sun_factor, 1)) # Beperken tot 0-1
|
|
|
|
# Stap 2: Pas weerfactoren toe (bewolking beïnvloedt zonne-intensiteit)
|
|
# Omrekenen van % naar 0-1 schaal
|
|
weather_factor = (100 - cloudiness) / 100
|
|
|
|
# Totale zonneprestaties berekenen
|
|
solar_performance = sun_factor * weather_factor * 100 # Omzetten naar percentage
|
|
|
|
# Logging
|
|
logger.debug(
|
|
f"Sun factor: {sun_factor}, Weather factor: {weather_factor}, Solar performance: {solar_performance:.2f}%")
|
|
|
|
return round(solar_performance, 2)
|