Section 2 : Données et Production énergétique
2.1. Données météorologiques
2.1.1. OpenWeatherMap - Données météo en temps réel
Le module OpenWeatherMap permet d’accéder aux données météorologiques actuelles et prévisionnelles.
from energysystemmodels.OpenWeatherMap import OpenWeatherMapClient
# Initialiser le client
api_key = "votre_clé_api"
client = OpenWeatherMapClient(api_key)
# Données météo actuelles
meteo_actuelle = client.get_current_weather(
city="Paris",
country="FR"
)
print(f"Température : {meteo_actuelle['temperature']}°C")
print(f"Humidité : {meteo_actuelle['humidity']}%")
print(f"Vitesse du vent : {meteo_actuelle['wind_speed']} m/s")
# Prévisions sur 5 jours
previsions = client.get_forecast(
city="Paris",
country="FR",
days=5
)
for jour in previsions:
print(f"{jour['date']}: {jour['temperature']}°C, {jour['description']}")
Exemple : Analyse des données météo horaires
from energysystemmodels.OpenWeatherMap import OpenWeatherMapClient
import pandas as pd
client = OpenWeatherMapClient(api_key="votre_clé")
# Récupérer les prévisions horaires
forecast = client.get_hourly_forecast(
lat=48.8566,
lon=2.3522,
hours=48
)
# Convertir en DataFrame
df_meteo = pd.DataFrame(forecast)
df_meteo['datetime'] = pd.to_datetime(df_meteo['timestamp'], unit='s')
# Analyses
temp_moyenne = df_meteo['temperature'].mean()
temp_min = df_meteo['temperature'].min()
temp_max = df_meteo['temperature'].max()
print(f"Température moyenne : {temp_moyenne:.1f}°C")
print(f"Température minimale : {temp_min:.1f}°C")
print(f"Température maximale : {temp_max:.1f}°C")
2.1.2. MeteoCiel - Données historiques et DJU
Le module MeteoCiel permet d’accéder aux données historiques et de calculer les Degrés-Jours Unifiés (DJU).
from energysystemmodels.MeteoCiel import MeteoCielClient
# Initialiser le client
client = MeteoCielClient()
# Données historiques
historique = client.get_historical_data(
station="Paris-Montsouris",
date_debut="2024-01-01",
date_fin="2024-12-31"
)
print(f"Nombre de jours : {len(historique)}")
Calcul des Degrés-Jours Unifiés (DJU)
from energysystemmodels.MeteoCiel import DJUCalculator
import pandas as pd
# Données de température
dates = pd.date_range('2024-01-01', '2024-12-31', freq='D')
temperatures = pd.Series([5, 8, 10, 12, 15, 18, 20, 22, 25, 23] * 36,
index=dates[:360])
# Calculer les DJU
calculator = DJUCalculator(temperature_reference=18.0)
# DJU Chauffage (DJU18)
dju_chauffage = calculator.calculer_dju_chauffage(temperatures)
# DJU Refroidissement (DJU21)
calculator_clim = DJUCalculator(temperature_reference=21.0)
dju_refroidissement = calculator_clim.calculer_dju_refroidissement(temperatures)
print(f"DJU Chauffage annuel : {dju_chauffage.sum():.0f}")
print(f"DJU Refroidissement annuel : {dju_refroidissement.sum():.0f}")
Exemple : Analyse mensuelle des DJU
from energysystemmodels.MeteoCiel import DJUCalculator
import pandas as pd
# Simuler des températures moyennes mensuelles
temperatures_mensuelles = pd.Series(
[5, 6, 9, 12, 16, 19, 22, 21, 18, 13, 8, 5],
index=pd.date_range('2024-01-01', periods=12, freq='MS')
)
calculator = DJUCalculator(temperature_reference=18.0)
# Calculer DJU mensuels
dju_mensuels = calculator.calculer_dju_chauffage_mensuel(temperatures_mensuelles)
print("DJU Chauffage par mois :")
for mois, dju in dju_mensuels.items():
print(f" {mois}: {dju:.1f}")
print(f"\nDJU annuel : {dju_mensuels.sum():.0f}")
Exemple issu des tests : Scraping MeteoCiel
from datetime import datetime
from MeteoCiel.MeteoCiel_Scraping import MeteoCiel_histoScraping
code2 = 480 # station météo
date_debut = datetime(2023, 10, 1)
date_fin = datetime.now()
df_histo, df_day, df_month, df_year = MeteoCiel_histoScraping(
code2, date_debut, date_fin, base_chauffage=18, base_refroidissement=23
)
df_month.to_excel(
"month_Meteociel.fr_station_" + str(date_debut.date()) +
"_to_" + str(date_fin.date()) + ".xlsx"
)
2.2. Production solaire photovoltaïque
Le module PV utilise pvlib pour simuler la production photovoltaïque avec une grande précision.
Configuration d’un système PV
from energysystemmodels.PV import PVSystem
# Définir le système PV
pv_system = PVSystem(
latitude=48.8566,
longitude=2.3522,
surface_m2=30,
puissance_crete_kWc=5.0,
orientation=180, # Plein sud
inclinaison=30, # degrés
rendement=0.18,
pertes_systeme=0.14
)
# Calculer la production annuelle
production_annuelle = pv_system.calculer_production_annuelle(annee=2024)
print(f"Production annuelle : {production_annuelle:.0f} kWh")
Exemple : Simulation horaire de production PV
from energysystemmodels.PV import PVSystem
import pandas as pd
import matplotlib.pyplot as plt
# Système PV
pv = PVSystem(
latitude=43.6047, # Toulouse
longitude=1.4442,
surface_m2=40,
puissance_crete_kWc=6.5,
orientation=180,
inclinaison=35,
rendement=0.19,
pertes_systeme=0.12
)
# Production horaire sur une année
production_horaire = pv.calculer_production_horaire(
date_debut='2024-01-01',
date_fin='2024-12-31'
)
# Convertir en DataFrame
df_prod = pd.DataFrame({
'datetime': production_horaire.index,
'production_kW': production_horaire.values
})
# Statistiques
print(f"Production totale : {df_prod['production_kW'].sum():.0f} kWh")
print(f"Production moyenne : {df_prod['production_kW'].mean():.2f} kW")
print(f"Puissance maximale : {df_prod['production_kW'].max():.2f} kW")
# Visualisation
df_prod_janvier = df_prod[df_prod['datetime'].dt.month == 1]
plt.figure(figsize=(12, 6))
plt.plot(df_prod_janvier['datetime'], df_prod_janvier['production_kW'])
plt.title('Production PV - Janvier 2024')
plt.xlabel('Date')
plt.ylabel('Puissance (kW)')
plt.grid(True)
plt.show()
Exemple : Optimisation de l’orientation
from energysystemmodels.PV import PVSystem
import numpy as np
# Paramètres fixes
config_base = {
'latitude': 48.8566,
'longitude': 2.3522,
'surface_m2': 30,
'puissance_crete_kWc': 5.0,
'rendement': 0.18,
'pertes_systeme': 0.14
}
# Tester différentes orientations et inclinaisons
orientations = np.arange(90, 270, 30) # Est à Ouest
inclinaisons = np.arange(0, 60, 10)
resultats_optimisation = []
for orient in orientations:
for inclin in inclinaisons:
pv = PVSystem(
orientation=orient,
inclinaison=inclin,
**config_base
)
production = pv.calculer_production_annuelle(2024)
resultats_optimisation.append({
'orientation': orient,
'inclinaison': inclin,
'production_kWh': production
})
# Trouver l'optimum
df_optim = pd.DataFrame(resultats_optimisation)
optimum = df_optim.loc[df_optim['production_kWh'].idxmax()]
print(f"Configuration optimale :")
print(f" Orientation : {optimum['orientation']:.0f}°")
print(f" Inclinaison : {optimum['inclinaison']:.0f}°")
print(f" Production : {optimum['production_kWh']:.0f} kWh/an")
Exemple : Production PV avec ombrage
from energysystemmodels.PV import PVSystem, ShadingProfile
# Définir le profil d'ombrage
ombrage = ShadingProfile()
ombrage.add_obstacle(
azimuth=180, # Direction de l'obstacle
elevation=30, # Hauteur angulaire
width=45 # Largeur angulaire
)
# Système PV avec ombrage
pv = PVSystem(
latitude=48.8566,
longitude=2.3522,
surface_m2=30,
puissance_crete_kWc=5.0,
orientation=180,
inclinaison=30,
rendement=0.18,
pertes_systeme=0.14,
shading_profile=ombrage
)
# Comparer avec et sans ombrage
prod_avec_ombrage = pv.calculer_production_annuelle(2024)
pv_sans_ombrage = PVSystem(
latitude=48.8566,
longitude=2.3522,
surface_m2=30,
puissance_crete_kWc=5.0,
orientation=180,
inclinaison=30,
rendement=0.18,
pertes_systeme=0.14
)
prod_sans_ombrage = pv_sans_ombrage.calculer_production_annuelle(2024)
perte_ombrage = (prod_sans_ombrage - prod_avec_ombrage) / prod_sans_ombrage * 100
print(f"Production sans ombrage : {prod_sans_ombrage:.0f} kWh")
print(f"Production avec ombrage : {prod_avec_ombrage:.0f} kWh")
print(f"Perte due à l'ombrage : {perte_ombrage:.1f}%")
Exemple : Dimensionnement d’une installation PV
from energysystemmodels.PV import PVSystem
import pandas as pd
# Objectif de production
consommation_annuelle = 5000 # kWh
taux_autoconsommation_vise = 0.70
# Localisation
lat, lon = 45.7640, 4.8357 # Lyon
# Tester différentes puissances
puissances_test = [3, 4, 5, 6, 7, 8, 9] # kWc
print(f"Consommation annuelle : {consommation_annuelle} kWh")
print(f"Taux d'autoconsommation visé : {taux_autoconsommation_vise*100}%")
print("\nDimensionnement :")
print("-" * 60)
for puissance in puissances_test:
surface = puissance / 0.18 # Rendement 18%
pv = PVSystem(
latitude=lat,
longitude=lon,
surface_m2=surface,
puissance_crete_kWc=puissance,
orientation=180,
inclinaison=35,
rendement=0.18,
pertes_systeme=0.14
)
production = pv.calculer_production_annuelle(2024)
taux_couverture = min(production / consommation_annuelle, 1.0)
print(f"{puissance} kWc ({surface:.1f} m²) -> "
f"Production: {production:.0f} kWh/an, "
f"Couverture: {taux_couverture*100:.1f}%")
Exemples issus des tests PV
from PV.ProductionElectriquePV import SolarSystem
system = SolarSystem(48.8566, 2.3522, 'Paris', 34, 'Etc/GMT-1', 170, 38)
system.retrieve_module_inverter_data()
system.retrieve_weather_data()
system.calculate_solar_parameters()
system.plot_annual_energy()
from PV.ProductionElectriquePV import SolarSystem
import numpy as np
from scipy.optimize import minimize
def objective(x, latitude, longitude, altitude, timezone):
azimut, inclinaison = x
system = SolarSystem(latitude, longitude, 'Optimized', altitude, timezone, azimut, inclinaison)
system.retrieve_module_inverter_data()
system.retrieve_weather_data()
system.calculate_solar_parameters()
return system.annual_energy
x0 = np.array([169.10944664521642, 38.12087673517409])
bounds = [(0, 360), (0, 90)]
result = minimize(
objective, x0, bounds=bounds,
args=(48.8566, 2.3522, 34, 'Etc/GMT-1'),
method='trust-constr',
options={'maxiter': 50, 'xtol': 1e-0, 'gtol': 1e-0}
)
if result.success:
optimized_azimut, optimized_inclinaison = result.x
print("Optimal orientation:", optimized_azimut)
print("Optimal inclination:", optimized_inclinaison)
print("Maximal annual energy:", -result.fun)