File size: 4,513 Bytes
c63bfc4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
from fastapi import FastAPI
from apscheduler.schedulers.background import BackgroundScheduler
import pandas as pd
import requests
import xgboost as xgb
from datetime import datetime, timedelta
import os
import matplotlib.pyplot as plt
app = FastAPI()
# Scheduler
scheduler = BackgroundScheduler()
scheduler.start()
# Load the trained model
model = xgb.XGBRegressor()
model.load_model("electricity_price_model.json")
# Constants
WEATHER_API = "https://api.open-meteo.com/v1/forecast"
ELECTRICITY_PRICE_API = "https://www.elprisetjustnu.se/api/v1/prices"
ENERGY_CHARTS_API = "https://api.energy-charts.info/public_power?"
PREDICTIONS_FILE = "predicted_prices.csv"
# Fetch weather data for the next day
def fetch_weather_data_for_tomorrow():
tomorrow = (datetime.now() + timedelta(days=1)).strftime('%Y-%m-%d')
params = {
"latitude": 59.3293,
"longitude": 18.0686,
"daily": "temperature_2m_mean,precipitation_sum,wind_speed_10m_max,wind_direction_10m_dominant",
"start_date": tomorrow,
"end_date": tomorrow,
"timezone": "Europe/Stockholm"
}
response = requests.get(WEATHER_API, params=params)
response.raise_for_status()
data = response.json()["daily"]
return pd.DataFrame(data)
# Fetch energy production data for the current day
def fetch_energy_production_data():
today = datetime.now().strftime('%Y-%m-%d')
params = {"country": "se", "start": today, "end": today}
response = requests.get(ENERGY_CHARTS_API, params=params)
response.raise_for_status()
data = response.json()
if "production_types" in data:
production_data = {
"unix_seconds": data["unix_seconds"],
**{ptype["name"]: ptype["data"] for ptype in data["production_types"]}
}
energy_df = pd.DataFrame(production_data)
energy_df = energy_df.rename(columns={"unix_seconds": "time"})
energy_df["time"] = pd.to_datetime(energy_df["time"], unit="s", errors="coerce").dt.tz_localize(None)
return energy_df
else:
return pd.DataFrame()
# Fetch electricity prices for the current day
def fetch_current_electricity_prices():
today = datetime.now().strftime('%Y/%m-%d')
url = f"{ELECTRICITY_PRICE_API}/{today}_SE3.json"
response = requests.get(url)
response.raise_for_status()
data = response.json()
electricity_df = pd.DataFrame(data)
electricity_df = electricity_df.rename(columns={"time_start": "time"})
electricity_df["time"] = pd.to_datetime(electricity_df["time"], errors="coerce").dt.tz_localize(None)
return electricity_df
# Prepare dataset for prediction
def prepare_prediction_data():
energy_data = fetch_energy_production_data()
electricity_data = fetch_current_electricity_prices()
weather_data = fetch_weather_data_for_tomorrow()
dataset = pd.merge(energy_data, electricity_data, on="time", how="inner")
dataset = pd.merge(dataset, weather_data, on="time", how="outer")
dataset = dataset.dropna()
return dataset
# Predict electricity prices for the next day
def predict_next_day_price():
dataset = prepare_prediction_data()
X = dataset.drop(["SEK_per_kWh", "time"], axis=1, errors="ignore")
predictions = model.predict(X)
dataset["predicted_price"] = predictions
dataset.to_csv(PREDICTIONS_FILE, index=False)
generate_dashboard(dataset)
print("Predictions saved to 'predicted_prices.csv'.")
# Generate a dashboard for visualization
def generate_dashboard(data):
plt.figure(figsize=(10, 6))
plt.plot(data["time"], data["predicted_price"], label="Predicted Price", linestyle="--")
if "SEK_per_kWh" in data.columns:
plt.plot(data["time"], data["SEK_per_kWh"], label="Actual Price")
plt.xlabel("Time")
plt.ylabel("Electricity Price (SEK/kWh)")
plt.title("Electricity Prices: Predicted vs Actual")
plt.legend()
plt.grid()
plt.savefig("dashboard.png")
plt.close()
# Schedule daily updates
scheduler.add_job(predict_next_day_price, "cron", hour=23, minute=59)
# API: Get predictions
@app.get("/predictions")
def get_predictions():
if not os.path.exists(PREDICTIONS_FILE):
return {"error": "Predictions not available"}
predictions = pd.read_csv(PREDICTIONS_FILE)
return predictions.to_dict()
# API: Get dashboard
@app.get("/dashboard")
def get_dashboard():
if not os.path.exists("dashboard.png"):
return {"error": "Dashboard not available"}
return {"dashboard_url": "/dashboard.png"}
|