From 270eca6104af5860192b23ece1b7b9da8b85b1fa Mon Sep 17 00:00:00 2001 From: Bla Bla Date: Sun, 25 Feb 2024 15:12:10 +0100 Subject: [PATCH] =?UTF-8?q?PV=20Forecast=20mit=20URL=20m=C3=B6glich=20=20+?= =?UTF-8?q?=20persistenter=20Cache=20eingebaut?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/class_ems.py | 14 +++- modules/class_pv_forecast.py | 128 +++++++++++++++++++++++------------ test.py | 16 +++-- 3 files changed, 106 insertions(+), 52 deletions(-) diff --git a/modules/class_ems.py b/modules/class_ems.py index 344c109..ee74ee8 100644 --- a/modules/class_ems.py +++ b/modules/class_ems.py @@ -45,7 +45,7 @@ class EnergieManagementSystem: def reset(self): self.akku.reset() - def simuliere(self): + def simuliere(self, start_stunde): eigenverbrauch_wh_pro_stunde = [] netzeinspeisung_wh_pro_stunde = [] netzbezug_wh_pro_stunde = [] @@ -53,10 +53,18 @@ class EnergieManagementSystem: einnahmen_euro_pro_stunde = [] akku_soc_pro_stunde = [] - for stunde in range(len(self.lastkurve_wh)): + ende = len(self.lastkurve_wh) # Berechnet das Ende basierend auf der Länge der Lastkurve + for stunde in range(start_stunde, ende): + # Anpassung, um sicherzustellen, dass Indizes korrekt sind verbrauch = self.lastkurve_wh[stunde] erzeugung = self.pv_prognose_wh[stunde] - strompreis = self.strompreis_cent_pro_wh[stunde] + strompreis = self.strompreis_cent_pro_wh[stunde] if stunde < len(self.strompreis_cent_pro_wh) else self.strompreis_cent_pro_wh[-1] + + + # for stunde in range(len(self.lastkurve_wh)): + # verbrauch = self.lastkurve_wh[stunde] + # erzeugung = self.pv_prognose_wh[stunde] + # strompreis = self.strompreis_cent_pro_wh[stunde] stündlicher_netzbezug_wh = 0 stündliche_kosten_euro = 0 diff --git a/modules/class_pv_forecast.py b/modules/class_pv_forecast.py index 1071cc4..7f957eb 100644 --- a/modules/class_pv_forecast.py +++ b/modules/class_pv_forecast.py @@ -2,54 +2,98 @@ from flask import Flask, jsonify, request import numpy as np from datetime import datetime from pprint import pprint -import json, sys +import json, sys, os +import requests, hashlib + + +class ForecastData: + def __init__(self, date_time, dc_power, ac_power, windspeed_10m, temperature): + self.date_time = date_time + self.dc_power = dc_power + self.ac_power = ac_power + self.windspeed_10m = windspeed_10m + self.temperature = temperature + + # Getter für die ForecastData-Attribute + def get_date_time(self): + return self.date_time + + def get_dc_power(self): + return self.dc_power + + def get_ac_power(self): + return self.ac_power + + def get_windspeed_10m(self): + return self.windspeed_10m + + def get_temperature(self): + return self.temperature class PVForecast: - class ForecastData: - def __init__(self, date_time, dc_power, ac_power, windspeed_10m, temperature): - self.date_time = date_time - self.dc_power = dc_power - self.ac_power = ac_power - self.windspeed_10m = windspeed_10m - self.temperature = temperature - - # Getter für die ForecastData-Attribute - def get_date_time(self): - return self.date_time - - def get_dc_power(self): - return self.dc_power - - def get_ac_power(self): - return self.ac_power - - def get_windspeed_10m(self): - return self.windspeed_10m - - def get_temperature(self): - return self.temperature - - def __init__(self, filepath): - self.filepath = filepath + def __init__(self, filepath=None, url=None, cache_dir='cache'): self.meta = {} self.forecast_data = [] - self.load_data() + self.cache_dir = cache_dir + if not os.path.exists(self.cache_dir): + os.makedirs(self.cache_dir) + if filepath: + self.load_data_from_file(filepath) + elif url: + self.load_data_with_caching(url) - def load_data(self): - with open(self.filepath, 'r') as file: + + def process_data(self, data): + self.meta = data.get('meta', {}) + values = data.get('values', [])[0] + for value in values: + forecast = ForecastData( + date_time=value.get('datetime'), + dc_power=value.get('dcPower'), + ac_power=value.get('power'), + windspeed_10m=value.get('windspeed_10m'), + temperature=value.get('temperature') + ) + self.forecast_data.append(forecast) + + def load_data_from_file(self, filepath): + with open(filepath, 'r') as file: data = json.load(file) - self.meta = data.get('meta', {}) - values = data.get('values', [])[0] - for value in values: - # Erstelle eine ForecastData-Instanz für jeden Wert in der Liste - forecast = self.ForecastData( - date_time=value.get('datetime'), - dc_power=value.get('dcPower'), - ac_power=value.get('power'), - windspeed_10m=value.get('windspeed_10m'), - temperature=value.get('temperature') - ) - self.forecast_data.append(forecast) + self.process_data(data) + + def load_data_from_url(self, url): + response = requests.get(url) + if response.status_code == 200: + data = response.json() + pprint(data) + self.process_data(data) + else: + print(f"Failed to load data from {url}. Status Code: {response.status_code}") + self.load_data_from_url(url) + + def load_data_with_caching(self, url): + cache_file = os.path.join(self.cache_dir, self.generate_cache_filename(url)) + if os.path.exists(cache_file): + with open(cache_file, 'r') as file: + data = json.load(file) + print("Loading data from cache.") + else: + response = requests.get(url) + if response.status_code == 200: + data = response.json() + with open(cache_file, 'w') as file: + json.dump(data, file) + print("Data fetched from URL and cached.") + else: + print(f"Failed to load data from {url}. Status Code: {response.status_code}") + return + self.process_data(data) + + def generate_cache_filename(self, url): + # Erzeugt einen SHA-256 Hash der URL als Dateinamen + hash_object = hashlib.sha256(url.encode()) + hex_dig = hash_object.hexdigest() + return f"cache_{hex_dig}.json" def get_forecast_data(self): return self.forecast_data diff --git a/test.py b/test.py index ec868c3..2a66459 100644 --- a/test.py +++ b/test.py @@ -16,7 +16,7 @@ import random import os -date = "2024-02-16" +date = "2024-02-26" akku_size = 1000 # Wh year_energy = 2000*1000 #Wh einspeiseverguetung_cent_pro_wh = np.full(24, 7/1000.0) @@ -33,11 +33,13 @@ leistung_haushalt = lf.get_daily_stats(date)[0,...] # Datum anpassen pprint(leistung_haushalt.shape) # PV Forecast -PVforecast = PVForecast(os.path.join(r'test_data', r'pvprognose.json')) +#PVforecast = PVForecast(filepath=os.path.join(r'test_data', r'pvprognose.json')) + +PVforecast = PVForecast(url="https://api.akkudoktor.net/forecast?lat=50.8588&lon=7.3747&power=5400&azimuth=-10&tilt=7&powerInvertor=2500&horizont=20,40,30,30&power=4800&azimuth=-90&tilt=7&powerInvertor=2500&horizont=20,40,45,50&power=1480&azimuth=-90&tilt=70&powerInvertor=1120&horizont=60,45,30,70&power=1600&azimuth=5&tilt=60&powerInvertor=1200&horizont=60,45,30,70&past_days=5&cellCoEff=-0.36&inverterEfficiency=0.8&albedo=0.25&timezone=Europe%2FBerlin&hourly=relativehumidity_2m%2Cwindspeed_10m") pv_forecast = PVforecast.get_forecast_for_date(date) temperature_forecast = PVforecast.get_temperature_forecast_for_date(date) -pprint(pv_forecast.shape) - +pprint(pv_forecast) +sys.exit() # Strompreise filepath = os.path.join (r'test_data', r'strompreis.json') # Pfad zur JSON-Datei anpassen price_forecast = HourlyElectricityPriceForecast(filepath) @@ -45,11 +47,11 @@ specific_date_prices = price_forecast.get_prices_for_date(date) # WP leistung_wp = wp.simulate_24h(temperature_forecast) -# pprint(leistung_haushalt) -# pprint(leistung_wp) -# sys.exit() + +# LOAD load = leistung_haushalt + leistung_wp + # EMS / Stromzähler Bilanz ems = EnergieManagementSystem(akku, load, pv_forecast, specific_date_prices, einspeiseverguetung_cent_pro_wh) o = ems.simuliere()