Skip to content

Commit

Permalink
Merge pull request #19 from MarekWadinger/paper-review
Browse files Browse the repository at this point in the history
Paper review and latest results
  • Loading branch information
MarekWadinger authored Oct 20, 2024
2 parents b827920 + 9726c65 commit 6a7873c
Show file tree
Hide file tree
Showing 13 changed files with 840 additions and 505 deletions.
70 changes: 30 additions & 40 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
from stqdm import stqdm
from streamlit_theme import st_theme

from core.controller import EconomicMPC, GreenHouseModel, GreenhouseSimulator
from core.greenhouse_model import GreenHouse, x_init_dict
from core.lettuce_model import DRY_TO_WET_RATIO, RATIO_SDW_NSDW
from core.openmeteo_query import (
from core.api_queries import (
Entsoe,
OpenMeteo,
get_city_geocoding,
get_co2_intensity,
)
from core.controller import EconomicMPC, GreenHouseModel, GreenhouseSimulator
from core.greenhouse_model import GreenHouse, x_init_dict
from core.lettuce_model import DRY_TO_WET_RATIO, RATIO_SDW_NSDW
from core.plot import plotly_greenhouse, plotly_response

# --- Page Config ---
Expand Down Expand Up @@ -58,14 +59,14 @@ def export_fig(fig) -> bytes:
return buf.getvalue()


@st.cache_resource(ttl=5 * 60, max_entries=10)
@st.cache_resource(ttl=5 * 60, max_entries=2)
def plotly_greenhouse_(length, width, height, roof_tilt, azimuth):
return plotly_greenhouse(length, width, height, roof_tilt, azimuth)


@st.cache_resource(ttl=5 * 60, max_entries=2)
def plotly_weather_(climate):
fig = climate.resample("1H").median().plot(backend="plotly")
fig = climate.resample("1h").median().plot(backend="plotly")
# Hide all traces after the first 4
for i in range(4, len(fig.data)):
fig.data[
Expand Down Expand Up @@ -226,16 +227,12 @@ def set_params_form_submit():
altitude,
) = get_city_geocoding(city_)
try:
if st.secrets.load_if_toml_exists():
secret = st.secrets["ELECTRICITYMAP_API_KEY"]
else:
secret = None
co2_intensity = get_co2_intensity(
country_code,
)
co2_source = "Current"
except ValueError:
co2_intensity = 100.0
co2_intensity = 200.0
co2_source = "Default"
st.markdown(
f"{co2_source} carbon intensity: **{co2_intensity} gCO₂/kWh**",
Expand Down Expand Up @@ -408,20 +405,27 @@ def set_params_form_submit():
start_date_, # type: ignore
start_time,
)
end_date = start_date + pd.Timedelta(
days=min(15, (sim_steps_max + N_max) * Ts // (3600 * 24))
)
climate = (
openmeteo.get_weather_data(
start_date=start_date,
end_date=(
start_date
+ pd.Timedelta(
days=min(15, (sim_steps_max + N_max) * Ts // (3600 * 24))
)
),
)
openmeteo.get_weather_data(start_date=start_date, end_date=end_date)
.tz_localize(tz, ambiguous=True)
.asfreq(f"{Ts}s")
.interpolate(method="time")
)
start_date = pd.Timestamp(climate.index[0])
entsoe = Entsoe()
energy_cost = entsoe.get_electricity_price(
country_code=country_code,
start_date=start_date.tz_localize(tz),
end_date=end_date.tz_localize(tz),
tz=tz,
)
energy_cost = pd.concat([pd.Series(index=climate.index), energy_cost])
energy_cost = energy_cost[~energy_cost.index.duplicated(keep="first")]
climate["energy_cost"] = energy_cost.sort_index().interpolate(
method="time", limit_direction="both"
)
runtime_info.info("Plotting forecast ...")

weather_plot = st.empty()
Expand Down Expand Up @@ -512,7 +516,7 @@ def set_params_form_submit():
mpc.climate = climate
simulator.climate = climate
weather_plot.plotly_chart(
climate.resample("1H").median().plot(backend="plotly")
climate.resample("1h").median().plot(backend="plotly")
)
runtime_info.info("Simulating ...")

Expand All @@ -535,25 +539,11 @@ def set_params_form_submit():
)

# Export results to table
profit = pd.Series(
mpc.lettuce_price
* (x0[-2:].sum() - x_sn_init.sum())
/ DRY_TO_WET_RATIO
* mpc.cultivated_area,
index=["Lettuce profit "],
)
costs = pd.Series(
index=[f"Energy ({i})" for i in u0s.columns]
+ [f"CO2 ({i})" for i in u0s.columns]
profit_costs = model.analyze_profit_and_costs(
x0.flatten()[-2:] - x_sn_init,
u0s,
climate["energy_cost"].values[: len(u0s)],
)
for act in [
act for act, active in model.gh.active_actuators.items() if active
]:
actuator = getattr(model.gh, act.lower().replace(" ", ""))
costs[f"Energy ({act})"] = -actuator.signal_to_eur(u0s[act]).sum()
costs[f"CO2 ({act})"] = -actuator.signal_to_co2_eur(u0s[act]).sum()
profit_costs = pd.concat([profit, costs]).rename("EUR")
profit_costs["Total"] = profit_costs.sum()

st.table(profit_costs.to_frame().style.format("{:.2f}"))

Expand Down
26 changes: 16 additions & 10 deletions core/actuators.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,31 +58,37 @@ def signal_to_power(
)

def signal_to_eur(
self, signal: float | ca.GenericExpressionCommon
self,
signal: float | ca.GenericExpressionCommon,
energy_cost: float | None = None,
) -> float | ca.GenericExpressionCommon:
if energy_cost is None:
energy_cost = self.energy_cost
return (
self.energy_cost
* self.signal_to_power(signal)
/ 1000
* self.dt
/ 3600
energy_cost * self.signal_to_power(signal) / 1000 * self.dt / 3600
)

def signal_to_co2(
self, signal: float | ca.GenericExpressionCommon
self,
signal: float | ca.GenericExpressionCommon,
co2_intensity: float | None = None,
) -> float | ca.GenericExpressionCommon:
if co2_intensity is None:
co2_intensity = self.co2_intensity
return (
self.co2_intensity
co2_intensity
* self.signal_to_power(signal)
/ 1000
* self.dt
/ 3600
)

def signal_to_co2_eur(
self, signal: float | ca.GenericExpressionCommon
self,
signal: float | ca.GenericExpressionCommon,
co2_intensity: float | None = None,
) -> float | ca.GenericExpressionCommon:
return self.co2_cost * self.signal_to_co2(signal)
return self.co2_cost * self.signal_to_co2(signal, co2_intensity)


class SimpleHeater(Actuator):
Expand Down
Loading

0 comments on commit 6a7873c

Please sign in to comment.