EOS/modules/class_strompreis.py
NormannK 8959bd8693 Update class_strompreis.py
initial clean up, translations, os.makedirs improved
2024-10-01 07:16:13 +02:00

129 lines
5.2 KiB
Python

import json
import os
import hashlib
import requests
from datetime import datetime, timedelta
import numpy as np
import pytz
# Example: Converting a UTC timestamp to local time
utc_time = datetime.strptime('2024-03-28T01:00:00.000Z', '%Y-%m-%dT%H:%M:%S.%fZ')
utc_time = utc_time.replace(tzinfo=pytz.utc)
# Replace 'Europe/Berlin' with your own timezone
local_time = utc_time.astimezone(pytz.timezone('Europe/Berlin'))
print(local_time)
def repeat_to_shape(array, target_shape):
# Check if the array fits the target shape
if len(target_shape) != array.ndim:
raise ValueError("Array and target shape must have the same number of dimensions")
# Number of repetitions per dimension
repeats = tuple(target_shape[i] // array.shape[i] for i in range(array.ndim))
# Use np.tile to expand the array
expanded_array = np.tile(array, repeats)
return expanded_array
class HourlyElectricityPriceForecast:
def __init__(self, source, cache_dir='cache', charges=0.000228, prediction_hours=24): # 228
self.cache_dir = cache_dir
os.makedirs(self.cache_dir, exist_ok=True)
self.cache_time_file = os.path.join(self.cache_dir, 'cache_timestamp.txt')
self.prices = self.load_data(source)
self.charges = charges
self.prediction_hours = prediction_hours
def load_data(self, source):
cache_filename = self.get_cache_filename(source)
if source.startswith('http'):
if os.path.exists(cache_filename) and not self.is_cache_expired():
print("Loading data from cache...")
with open(cache_filename, 'r') as file:
json_data = json.load(file)
else:
print("Loading data from the URL...")
response = requests.get(source)
if response.status_code == 200:
json_data = response.json()
with open(cache_filename, 'w') as file:
json.dump(json_data, file)
self.update_cache_timestamp()
else:
raise Exception(f"Error fetching data: {response.status_code}")
else:
with open(source, 'r') as file:
json_data = json.load(file)
return json_data['values']
def get_cache_filename(self, url):
hash_object = hashlib.sha256(url.encode())
hex_dig = hash_object.hexdigest()
return os.path.join(self.cache_dir, f"cache_{hex_dig}.json")
def is_cache_expired(self):
if not os.path.exists(self.cache_time_file):
return True
with open(self.cache_time_file, 'r') as file:
timestamp_str = file.read()
last_cache_time = datetime.strptime(timestamp_str, '%Y-%m-%d %H:%M:%S')
return datetime.now() - last_cache_time > timedelta(hours=1)
def update_cache_timestamp(self):
with open(self.cache_time_file, 'w') as file:
file.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
def get_price_for_date(self, date_str):
"""Returns all prices for the specified date, including the price from 00:00 of the previous day."""
# Convert date string to datetime object
date_obj = datetime.strptime(date_str, '%Y-%m-%d')
# Calculate the previous day
previous_day = date_obj - timedelta(days=1)
previous_day_str = previous_day.strftime('%Y-%m-%d')
# Extract the price from 00:00 of the previous day
last_price_of_previous_day = [
entry["marketpriceEurocentPerKWh"] + self.charges
for entry in self.prices if previous_day_str in entry['end']
][-1]
# Extract all prices for the specified date
date_prices = [
entry["marketpriceEurocentPerKWh"] + self.charges
for entry in self.prices if date_str in entry['end']
]
print(f"getPrice: {len(date_prices)}")
# Add the last price of the previous day at the start of the list
if len(date_prices) == 23:
date_prices.insert(0, last_price_of_previous_day)
return np.array(date_prices) / (1000.0 * 100.0) + self.charges
def get_price_for_daterange(self, start_date_str, end_date_str):
"""Returns all prices between the start and end dates."""
print(start_date_str)
print(end_date_str)
start_date_utc = datetime.strptime(start_date_str, "%Y-%m-%d").replace(tzinfo=pytz.utc)
end_date_utc = datetime.strptime(end_date_str, "%Y-%m-%d").replace(tzinfo=pytz.utc)
start_date = start_date_utc.astimezone(pytz.timezone('Europe/Berlin'))
end_date = end_date_utc.astimezone(pytz.timezone('Europe/Berlin'))
price_list = []
while start_date < end_date:
date_str = start_date.strftime("%Y-%m-%d")
daily_prices = self.get_price_for_date(date_str)
if daily_prices.size == 24:
price_list.extend(daily_prices)
start_date += timedelta(days=1)
# If prediction hours are greater than 0, reshape the price list
if self.prediction_hours > 0:
price_list = repeat_to_shape(np.array(price_list), (self.prediction_hours,))
return price_list