import gradio as gr import pandas as pd import numpy as np import hopsworks import joblib import os import json from entsoe import EntsoePandasClient from datetime import datetime, timedelta, date from pandas import json_normalize import tensorflow as tf from keras.layers import LSTM from urllib.request import urlopen from sklearn.preprocessing import LabelEncoder, StandardScaler # from keras.layers import * # from keras.models import Sequential # from keras.layers import Dense # from keras.layers import LSTM # from keras.layers import Dropout project = hopsworks.login() fs = project.get_feature_store() mr = project.get_model_registry() model = mr.get_model("SE3_elec_price_model", version=2) model_dir = model.download() model = joblib.load(model_dir + "/electricity_price.pkl") def get_price_forecast(): today, tomorrow = get_date() df_entsoe = get_entsoe_data(today, tomorrow) # get timestamps that temp dataset should match on entsoe_earliest = df_entsoe["datetime"].iloc[0] entsoe_latest = df_entsoe["datetime"].iloc[-1] df_temp = get_temp(entsoe_earliest, entsoe_latest) df = df_entsoe.merge(df_temp, how='inner', on='datetime') df.set_index('datetime',inplace=True) ## pre-process before predict sc_x=StandardScaler() df_scaled=sc_x.fit_transform(df) sc_y=StandardScaler() sc_y=sc_y.fit(df[['day_ahead_price']]) step_back=24 no_records=len(df_scaled) no_cols=4 X_train_shape_pred=[] for i in range(step_back,no_records): X_train_shape_pred.append(df_scaled[i-step_back:i]) X_train_shape_pred=np.array(X_train_shape_pred) print(X_train_shape_pred.shape) ## predict pred_price = model.predict(X_train_shape_pred) final_pred=sc_y.inverse_transform(pred_price) print(final_pred.shape) # append time for prediction predict_time_from = datetime.fromtimestamp(entsoe_latest / 1e3) # calculating timestamps for the next 24 h timestamp_list = [predict_time_from + timedelta(hours=x) for x in range(len(final_pred))] # iterating through timestamp_list # for i, x in enumerate(timestamp_list): # print(x, final_pred[i]) # print(final_pred.shape) df_prediction = pd.DataFrame( {'Datetime': timestamp_list, 'Price forecast [EUR/MWh]': final_pred.flatten(), }) #df_predictions = pd.DataFrame([timestamp_list, final_pred], columns=["datetime", "Price prediction"]) # print(len(final_pred), len(timestamp_list), len(final_pred), len(final_pred[0])) return df_prediction #[today, temp, day_ahead_price, pred_price, total_load, total_generation] # # Returns yesterday and tomorrows date def get_date(): # yesterday = datetime.today() - timedelta(days=1) # yesterday = yesterday.date().strftime('%Y%m%d') # tomorrow = (datetime.strptime(yesterday, '%Y%m%d') + timedelta(days=2)).strftime('%Y%m%d') date_from = datetime.now() - timedelta(days=3) date_from = date_from.date().strftime('%Y%m%d') date_to = (datetime.strptime(date_from, '%Y%m%d') + timedelta(days=4)).strftime('%Y%m%d') return date_from, date_to def get_entsoe_data(date_from, date_to): # Client client = EntsoePandasClient(api_key="cb3a29b2-3276-4a4c-aba3-6507120d99be") # Date and country start = pd.Timestamp(date_from, tz='Europe/Stockholm') end = pd.Timestamp(date_to, tz='Europe/Stockholm') country_code = 'SE_3' df_day_price = client.query_day_ahead_prices(country_code, start=start,end=end) df_generation_per_prod = client.query_generation(country_code, start=start,end=end, psr_type=None) df_load = client.query_load(country_code, start=start,end=end) df_entsoe = df_generation_per_prod.join(df_day_price.rename("day_ahead_price")) df_entsoe = df_entsoe.join(df_load) df_entsoe_clean = df_entsoe.reset_index() df_entsoe_clean = df_entsoe_clean.rename(columns = {'index':'DateTime'}) df_entsoe_clean['DateTime'] = df_entsoe_clean.DateTime.values.astype('int64') // 10 ** 6 col_list = ["Hydro Water Reservoir", "Nuclear", "Other", "Solar", "Wind Onshore"] df_entsoe_clean['total_generation'] = df_entsoe_clean[list(col_list)].sum(axis=1) df_entsoe_clean.drop(col_list + ["Fossil Gas"], axis=1, inplace=True) df_entsoe_clean.rename(columns={"Actual Load": "total_load", "DateTime":"datetime"}, inplace=True) return df_entsoe_clean.tail(48) def get_temp(timeseries_from, timeseries_to): url = "https://opendata-download-metobs.smhi.se/api/version/latest/parameter/1/station/71420/period/latest-months/data.json" response = urlopen(url) # convert response to json, to dataframe data_json = json.loads(response.read()) df_smhi_data = json_normalize(data_json['value']) # extract only the temperature in the time stamp interval df_smhi_data = df_smhi_data.loc[(df_smhi_data['date'] >= timeseries_from) & (df_smhi_data['date'] <= timeseries_to)] df_smhi_data = df_smhi_data.reset_index().rename(columns = {'date':'datetime'}) df_smhi_data.drop(["index", "quality"], axis=1, inplace=True) df_smhi_data["value"] = df_smhi_data["value"].astype(float) df_smhi_data.rename(columns={"value": "temperature"}, inplace=True) return df_smhi_data demo = gr.Interface( fn = get_price_forecast, title = "SE3 Electricity Day-Ahead Price Prediction", description ="SE3 Electricity Day-Ahead Price Prediction, based on electricity production, generation and temperature", allow_flagging = "never", inputs = [], outputs = [ gr.DataFrame(x="datetime", y="Price prediction [EUR/MWh]") # gr.Textbox(label="Date"), # gr.Textbox(label="Temperature Forecast [℃]"), # gr.Textbox(label="Total Load Forecast [MWh]"), # gr.Textbox(label="Total Generation Forecast [MWh]"), # gr.Textbox(label="Predicted Day-Ahead Price [EUR/MWh]"), ] ) demo.launch()