File size: 5,690 Bytes
961a934
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a714bca
07d9d06
a714bca
961a934
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a714bca
961a934
 
 
 
a714bca
 
 
961a934
 
 
 
 
 
 
 
 
 
 
a714bca
961a934
 
 
 
 
a714bca
 
961a934
 
 
6ae2b2a
961a934
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6ae2b2a
 
07d9d06
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6ae2b2a
 
 
 
 
 
 
 
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
# port of
# https://colab.research.google.com/drive/1PJgcJ4ly7x5GuZy344eJeYSODo8trbM4#scrollTo=39F2u-4hvwLU

import numpy as np
import pandas as pd
import gradio as gr

# from simulation import *
from data_processing import *
from visualization import *
from supplier import Supplier, precalculate_supplier
from architecture import simulator, add_dummy_predictions
from decider import Decider, RandomDecider
from bess import BatteryModel

#@title ### Downloading the data
# !wget "https://static.renyi.hu/ai-shared/daniel/pq/PL_44527.19-21.csv.gz"
# !wget "https://static.renyi.hu/ai-shared/daniel/pq/pq_terheles_2021_adatok.tsv"


met_2021_data, cons_2021_data = read_datasets()


# TODO move out everything that should not be recalculated.
# TODO actually use uiParameters. (base_price and peak_price were just to mock up the Accordion gui.)
# TODO ui_refresh spawns its own Supplier, which is just dumb.
def recalculate(**uiParameters):
    fixed_consumption = uiParameters['fixed_consumption']
    del uiParameters['fixed_consumption']

    parameters = SolarParameters()
    for k, v in uiParameters.items():
        setattr(parameters, k, v)

    np.random.seed(1)

    supplier = Supplier(price=100) # Ft/kWh
    # nine-to-five increased price.
    supplier.set_price_for_daily_interval(9, 17, 150)
    # midnight-to-three decreased price, to test network charge.
    supplier.set_price_for_daily_interval(0, 3, 20)
    # peak_demand dimension is kWh, but it's interpreted as the full consumption
    # during a 15 minute timestep.
    supplier.set_demand_charge(peak_demand=2.5, surcharge_per_kwh=500) # kWh in a 15 minutes interval, Ft/kWh

    solar_parameters = SolarParameters()

    add_production_field(met_2021_data, solar_parameters)
    all_data = interpolate_and_join(met_2021_data, cons_2021_data)

    time_interval_min = all_data.index.freq.n
    time_interval_h = time_interval_min / 60

    # for faster testing:
    DATASET_TRUNCATED_SIZE = None
    if DATASET_TRUNCATED_SIZE is not None:
        print("Truncating dataset to", DATASET_TRUNCATED_SIZE, "datapoints, that is", DATASET_TRUNCATED_SIZE * time_interval_h / 24, "days")
        all_data = all_data.iloc[:DATASET_TRUNCATED_SIZE]

    if fixed_consumption:
        all_data['Consumption'] = 10

    print("Working with", solar_parameters.solar_cell_num, "solar cells, that's a maximum production of", all_data['Production'].max(), "kW.")

    all_data_with_predictions = all_data.copy()
    add_dummy_predictions(all_data_with_predictions)

    precalculated_supplier = precalculate_supplier(supplier, all_data.index)
    # we delete the supplier to avoid accidentally calling it instead of precalculated_supplier
    supplier = None

    all_data_with_predictions['Consumption_fees'] = precalculated_supplier.consumption_fees # [HUF / kWh]

    battery_model = BatteryModel(capacity_Ah=600, time_interval_h=time_interval_h)

    # param_1 is prob of choosing PASSIVE
    # param_2 is prob of choosing NETWORK_CHARGE
    decider = RandomDecider(np.array([0.0, 0.0]), precalculated_supplier)

    results, total_network_fee = simulator(battery_model, all_data_with_predictions, decider)
    print(f"{total_network_fee=}")
    return results


def ui_refresh(solar_cell_num, bess_nominal_capacity, fixed_consumption, base_price, peak_price):
    results = recalculate(solar_cell_num=solar_cell_num, bess_nominal_capacity=bess_nominal_capacity, fixed_consumption=fixed_consumption)

    fig1 = plotly_visualize_simulation(results, date_range=("2021-02-01", "2021-02-07"))
    fig2 = plotly_visualize_simulation(results, date_range=("2021-08-02", "2021-08-08"))

    # (12, 3), the 3 indexed with (network, solar, bess):
    consumptions_in_mwh = monthly_analysis(results)

    fig_monthly = plotly_visualize_monthly(consumptions_in_mwh)

    network, solar, bess = consumptions_in_mwh.sum(axis=0)
    html = "<table>\n"
    for column, column_name in zip((network, solar, bess), ("Network", "Solar directly", "Solar via BESS")):
        html += f"<tr><td>Yearly consumption served by {column_name}:&nbsp;&nbsp;&nbsp;</td><td>{column:0.2f} MWh</td></tr>\n"

    supplier = Supplier(price=70) # HUF/kWh
    supplier.set_price_for_daily_interval_on_workdays(start=6, end=22, price=100)

    # not realistic, just for testing the effect
    # supplier.set_demand_charge(peak_demand=100, surcharge_per_kw=1000)

    fee = supplier.fee(results["consumption_from_network"])
    html += f"<tr><td>{fee/1e6:.3f} million HUF billed by energy supplier</td></tr>\n"

    html += "</table>"

    return (html, fig_monthly, fig1, fig2)


with gr.Blocks() as ui:
    with gr.Row():
        # LEFT: Input controls
        with gr.Column(scale=1):  # narrower column
            solar_slider = gr.Slider(0, 2000, 114, label="Solar cell number")
            bess_slider = gr.Slider(0, 2000, 330, label="BESS nominal capacity in [Ah]")
            fixed_consumption = gr.Checkbox(value=False, label="Use fixed consumption (10 kW)")

            with gr.Accordion("Advanced Pricing Settings", open=False):
                base_price = gr.Number(value=0.1, label="Base energy price [€/kWh]")
                peak_price = gr.Number(value=0.3, label="Peak energy price [€/kWh]")

            run_btn = gr.Button("Run Simulation")

        # RIGHT: Output display
        with gr.Column(scale=2):  # wider column
            html_out = gr.HTML()
            plot1 = gr.Plot()
            plot2 = gr.Plot()
            plot3 = gr.Plot()

    run_btn.click(
        ui_refresh,
        inputs=[solar_slider, bess_slider, fixed_consumption, base_price, peak_price],
        outputs=[html_out, plot1, plot2, plot3],
    )

ui.launch()