File size: 5,458 Bytes
d8e79ee
 
 
 
 
 
0fe02ae
2ae2c79
f38f576
d8e79ee
 
 
0fe02ae
f38f576
2ae2c79
 
 
 
 
d8e79ee
 
 
2ae2c79
 
 
 
d8e79ee
 
c6ce0ae
2ae2c79
 
d8e79ee
2ae2c79
d8e79ee
0fe02ae
2ae2c79
0fe02ae
c6ce0ae
 
d8e79ee
0fe02ae
2ae2c79
 
 
 
0fe02ae
 
2ae2c79
 
0fe02ae
 
c6ce0ae
0fe02ae
 
 
2ae2c79
0fe02ae
2ae2c79
d8e79ee
 
 
c6ce0ae
2ae2c79
d8e79ee
 
 
 
 
 
 
 
 
 
 
 
 
c6ce0ae
2ae2c79
 
d8e79ee
c6ce0ae
 
 
 
 
d8e79ee
 
0fe02ae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2ae2c79
0fe02ae
c6ce0ae
d8e79ee
c6ce0ae
 
 
 
 
 
 
 
 
 
d8e79ee
f38f576
c6ce0ae
d8e79ee
 
 
 
 
 
 
 
 
 
 
f38f576
d8e79ee
 
 
 
0fe02ae
 
 
 
 
 
 
 
 
 
 
2ae2c79
0fe02ae
 
 
2ae2c79
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import requests
import pandas as pd
import xgboost as xgb
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
import gradio as gr
import datetime
import os

# API Endpoints
WEATHER_API = "https://api.open-meteo.com/v1/forecast"
ELECTRICITY_PRICE_API = "https://www.elprisetjustnu.se/api/v1/prices"
ENERGY_CHARTS_API = "https://energy-charts.info/api/public_power"

# Fetch historical weather data
def fetch_weather_data(start_date="2023-01-01", end_date=None):
    if end_date is None:
        end_date = datetime.datetime.now().strftime('%Y-%m-%d')

    params = {
        "latitude": 59.3293,  # Stockholm latitude
        "longitude": 18.0686,  # Stockholm longitude
        "daily": "temperature_2m_mean,precipitation_sum,wind_speed_10m_max,wind_direction_10m_dominant",
        "start_date": start_date,
        "end_date": end_date,
        "timezone": "Europe/Stockholm"
    }
    response = requests.get(WEATHER_API, params=params)
    response.raise_for_status()
    daily_data = response.json()["daily"]
    return pd.DataFrame(daily_data)

# Fetch historical electricity prices
def fetch_electricity_prices():
    today = datetime.datetime.now().strftime('%Y/%m-%d')
    url = f"{ELECTRICITY_PRICE_API}/{today}_SE3.json"
    response = requests.get(url)
    response.raise_for_status()
    return pd.DataFrame(response.json())

# Fetch energy production data using Energy-Charts API
def fetch_energy_production_data(start_date="2023-01-01", end_date=None):
    if end_date is None:
        end_date = datetime.datetime.now().strftime('%Y-%m-%d')

    params = {
        "country": "se",  # Sweden country code
        "start": start_date,
        "end": end_date
    }
    response = requests.get(ENERGY_CHARTS_API, params=params)
    response.raise_for_status()
    data = response.json()
    production_data = {
        "unix_seconds": data["unix_seconds"],
        **{ptype["name"]: ptype["data"] for ptype in data["production_types"]}
    }
    return pd.DataFrame(production_data)

# Prepare the dataset
def prepare_dataset(weather_data, electricity_data, energy_data):
    dataset = pd.concat([weather_data, electricity_data, energy_data], axis=1)
    dataset = dataset.dropna()
    return dataset

# Train the model
def train_model(dataset):
    X = dataset.drop("price", axis=1)
    y = dataset["price"]
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

    model = xgb.XGBRegressor(objective="reg:squarederror", n_estimators=100, learning_rate=0.1)
    model.fit(X_train, y_train)
    predictions = model.predict(X_test)

    rmse = mean_squared_error(y_test, predictions, squared=False)
    model.save_model("electricity_price_model.json")
    print(f"Model trained with RMSE: {rmse}")
    return model

# Load the model and make predictions
def predict_price(features):
    model = xgb.XGBRegressor()
    model.load_model("electricity_price_model.json")
    prediction = model.predict(pd.DataFrame([features]))
    return prediction[0]

# Update predictions and save to file
def update_predictions():
    # Fetch the latest data
    weather_data = fetch_weather_data()
    electricity_data = fetch_electricity_prices()
    energy_data = fetch_energy_production_data()

    # Prepare dataset
    dataset = prepare_dataset(weather_data, electricity_data, energy_data)

    # Load the model
    model = xgb.XGBRegressor()
    model.load_model("electricity_price_model.json")

    # Generate predictions
    predictions = model.predict(dataset.drop("price", axis=1))

    # Save predictions to file
    predictions_output = dataset.copy()
    predictions_output["predicted_price"] = predictions
    predictions_output.to_json("predictions.json", orient="records")
    print("Predictions updated and saved.")

# Gradio Interface
def gradio_interface():
    def wrapper(temp, precip, wind_speed, humidity, energy_price, electricity_price):
        features = {
            "temperature_2m": temp,
            "precipitation": precip,
            "wind_speed_10m": wind_speed,
            "humidity": humidity,
            "energy_price": energy_price,
            "electricity_price": electricity_price
        }
        return predict_price(features)

    interface = gr.Interface(
        fn=wrapper,
        inputs=[
            gr.inputs.Number(label="Temperature (°C)"),
            gr.inputs.Number(label="Precipitation (mm)"),
            gr.inputs.Number(label="Wind Speed (m/s)"),
            gr.inputs.Number(label="Humidity (%)"),
            gr.inputs.Number(label="Energy Production Price"),
            gr.inputs.Number(label="Historical Electricity Price")
        ],
        outputs=gr.outputs.Textbox(label="Predicted Electricity Price"),
        title="Electricity Price Prediction",
        description="Predict future electricity prices based on weather and energy data."
    )

    interface.launch()

if __name__ == "__main__":
    import sys
    if len(sys.argv) > 1 and sys.argv[1] == "update":
        update_predictions()
    else:
        # Fetch data
        weather_data = fetch_weather_data()
        electricity_data = fetch_electricity_prices()
        energy_data = fetch_energy_production_data()

        # Prepare dataset and train the model
        dataset = prepare_dataset(weather_data, electricity_data, energy_data)
        train_model(dataset)

        # Launch Gradio interface
        gradio_interface()