While implementing this task this error keeps appearing:
Traceback (most recent call last):
File ~\anaconda3\envs\oemof_052_2\lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec
exec(code, globals, locals)
File c:\users\arian\desktop\1________________\versuch_12_.py:33
from oemof.solph.custom import SinkDSM
ModuleNotFoundError: No module named 'oemof.solph.custom'
Can someone tell me why this is? Thank you!
How can I implement SinkDSM into my model?
Kind regards,
Armend
here is my model:
###########################################################################
# imports
###########################################################################
import pandas as pd
import matplotlib.pyplot as plt
import logging
import os
import pprint as pp
from datetime import datetime
from oemof.tools import logger
from oemof.solph import flows
from oemof.solph import EnergySystem
from oemof.solph import Model
from oemof.solph import buses
from oemof.solph import components as cmp
from oemof.solph import helpers
from oemof.solph import processing
from oemof.solph import views
from oemof.solph.custom import SinkDSM
def main():
# *************************************************************************
# ********** PART 1 - Define and optimise the energy system ***************
# *************************************************************************
# Read data file
verbrauchsdaten_mit_pv_file = os.path.join(os.getcwd(), 'verbrauchsdaten_mit_pv.csv')
strom_co2_preise_file = os.path.join(os.getcwd(), 'strom_co2_preise_täglich.csv')
verbrauchsdaten_mit_pv_data = pd.read_csv(verbrauchsdaten_mit_pv_file)
strom_co2_preise_data = pd.read_csv(strom_co2_preise_file)
solver = "cbc" # 'glpk', 'gurobi',....
debug = False # Set number_of_timesteps to 3 to get a readable lp-file.
solver_verbose = False # show/hide solver output
# initiate the logger (see the API docs for more information)
logger.define_logging(
logfile="oemof_example.log",
screen_level=logging.INFO,
file_level=logging.INFO,
)
date_time_index = pd.date_range('1/1/2024 00:00:00', periods=336, freq='30min')
# create the energysystem and assign the time index
energysystem = EnergySystem(
timeindex=date_time_index, infer_last_interval=False
)
##########################################################################
# Create oemof objects
##########################################################################
logging.info("Create oemof objects")
# The bus objects were assigned to variables which makes it easier to
# connect components to these buses (see below).
# create electricity bus
bel = buses.Bus(label="electricity")
# adding the buses to the energy system
energysystem.add(bel)
# create excess component for the electricity bus to allow overproduction
energysystem.add(
cmp.Sink(label="excess_bel",
inputs={bel: flows.Flow(variable_costs=(strom_co2_preise_data["Strompreis (€/kWh)"]*-1))}, #strom verkauf = *-1
)
)
energysystem.add(
cmp.Source(
label="supplier",
outputs={
bel: flows.Flow(
nominal_value=1, # 1.000 W = hier 1kwh
variable_costs=strom_co2_preise_data["Strompreis (€/kWh)"],
custom_attributes={"emission_factor": 0.20},
)
},
)
)
# create fixed source object representing pv power plants
energysystem.add(
cmp.Source(
label="pv",
outputs={bel: flows.Flow(fix=verbrauchsdaten_mit_pv_data["pv"], variable_costs=0, nominal_value=1)},
) # werte in csv sind in kW also x 1000 = W
)
# create simple sink object representing the electrical demand 1
energysystem.add(
cmp.Sink(
label="consumer1",
inputs={bel: flows.Flow(fix=verbrauchsdaten_mit_pv_data["consumer1"], nominal_value=0.001, variable_costs=1, custom_attributes={"emission_factor": 0.60},)},
) # beudeutet wert in csv x 1 W # Beispiel: Variable Kosten von 0,25 €/kWh
)
# create simple sink object representing the electrical demand 2
energysystem.add(
cmp.Sink(
label="consumer2",
inputs={bel: flows.Flow(fix=verbrauchsdaten_mit_pv_data["consumer2"], nominal_value=0.001, variable_costs=1 ,custom_attributes={"emission_factor": 0.30},)}
) # beudeutet wert in csv x 1 # Beispiel: Variable Kosten von 0,25 €/kWh
)
data_dict_dsm = {
"demand_el": [3] * len(date_time_index),
"Cap_up": [0.5] * len(date_time_index),
"Cap_do": [0.5] * len(date_time_index)
}
data_dsm = pd.DataFrame.from_dict(data_dict_dsm)
demand_dsm = custom.SinkDSM(
label="DSM",
inputs={bel: flows.Flow()},
demand=data_dsm['demand_el'],
capacity_up=data_dsm["Cap_up"],
capacity_down=data_dsm["Cap_do"],
delay_time=6, # Beispielwert
max_demand=1, # Beispielwert
max_capacity_up=1, # Beispielwert
max_capacity_down=1, # Beispielwert
approach="DIW", # Beispielwert
cost_dsm_down=5 # Beispielwert
)
energysystem.add(demand_dsm)
# create storage object representing a battery
storage = cmp.GenericStorage(
nominal_storage_capacity=25,# 25.000 Wh = 25 kWh oder 10,08 MWh
label="storage",
inputs={bel: flows.Flow(nominal_value=25 / 6)},# 10,08 Mwh/6 = 1,68 MW
outputs={
bel: flows.Flow(nominal_value=25 / 6, variable_costs=0.001) # kosten von 0.001 pro entladen Wh
},
loss_rate=0.00,
initial_storage_level=0,
balanced=True,
inflow_conversion_factor=1,
outflow_conversion_factor=0.8,
)
energysystem.add(storage)
##########################################################################
# Optimise the energy system and plot the results
##########################################################################
logging.info("Optimise the energy system")
# initialise the operational model
model = Model(energysystem)
# This is for debugging only. It is not(!) necessary to solve the problem
# and should be set to False to save time and disc space in normal use. For
# debugging the timesteps should be set to 3, to increase the readability
# of the lp-file.
if debug:
filename = os.path.join(
helpers.extend_basic_path("lp_files"), "basic_example.lp"
)
logging.info("Store lp-file in {0}.".format(filename))
model.write(filename, io_options={"symbolic_solver_labels": False})
# if tee_switch is true solver messages will be displayed
logging.info("Solve the optimization problem")
model.solve(solver=solver, solve_kwargs={"tee": solver_verbose})
logging.info("Store the energy system with the results.")
# The processing module of the outputlib can be used to extract the results
# from the model transfer them into a homogeneous structured dictionary.
# add results to the energy system to make it possible to store them.
energysystem.results["main"] = processing.results(model)
energysystem.results["meta"] = processing.meta_results(model)
# The default path is the '.oemof' folder in your $HOME directory.
# The default filename is 'es_dump.oemof'.
# You can omit the attributes (as None is the default value) for testing
# cases. You should use unique names/folders for valuable results to avoid
# overwriting.
# store energy system with results
energysystem.dump(dpath=None, filename=None)
# *************************************************************************
# ********** PART 2 - Processing the results ******************************
# *************************************************************************
logging.info("**** The script can be divided into two parts here.")
logging.info("Restore the energy system and the results.")
energysystem = EnergySystem()
energysystem.restore(dpath=None, filename=None)
# define an alias for shorter calls below (optional)
results = energysystem.results["main"]
storage = energysystem.groups["storage"]
# print a time slice of the state of charge
print("")
print("********* State of Charge (slice) *********")
print(
results[(storage, None)]["sequences"][
datetime(2024, 1, 1, 0, 0, 0) : datetime(2024, 1, 8, 0, 0, 0)
]
)
print("")
# get all variables of a specific component/bus
custom_storage = views.node(results, "storage")
electricity_bus = views.node(results, "electricity")
# plot the time series (sequences) of a specific component/bus
fig, ax = plt.subplots(figsize=(10, 5))
custom_storage["sequences"].plot(
ax=ax, kind="line", drawstyle="steps-post"
)
plt.legend(
loc="upper center",
prop={"size": 8},
bbox_to_anchor=(0.5, 1.25),
ncol=2,
)
fig.subplots_adjust(top=0.8)
plt.show()
fig, ax = plt.subplots(figsize=(10, 5))
electricity_bus["sequences"].plot(
ax=ax, kind="line", drawstyle="steps-post"
)
plt.legend(
loc="upper center", prop={"size": 8}, bbox_to_anchor=(0.5, 1.3), ncol=2
)
fig.subplots_adjust(top=0.8)
plt.show()
# electricity_bus_flows
# Convert the flow results to a DataFrame
df_electricity_bus = pd.DataFrame(electricity_bus["sequences"])
# Reset the index and rename the column
df_electricity_bus.reset_index(inplace=True)
df_electricity_bus.rename(columns={"index": "Timestep"}, inplace=True)
# Save the DataFrame to a CSV file
df_electricity_bus.to_csv("electricity_bus_flows.csv", index=False)
# custom_storage_flows
# Convert the flow results to a DataFrame
df_custom_storage = pd.DataFrame(custom_storage["sequences"])
# Save the DataFrame to a CSV file with the first column named "Timestep"
df_custom_storage.to_csv("custom_storage_flows.csv", index_label="Timestep")
# print the solver results
print("********* Meta results *********")
pp.pprint(energysystem.results["meta"])
print("")
# print the sums of the flows around the electricity bus
print("********* Main results *********")
print(electricity_bus["sequences"].sum(axis=0))
# Ergebnisse in csv-Speichern
# Metaergebnisse in DataFrame konvertieren
meta_results = energysystem.results["meta"]
df_meta = pd.DataFrame(meta_results.items(), columns=["Parameter", "Value"])
# CSV-Datei fĂĽr Metaergebnisse speichern
df_meta.to_csv("meta_results.csv", index=False)
# Hauptergebnisse in DataFrame konvertieren
main_results = electricity_bus["sequences"].sum(axis=0)
df_main = pd.DataFrame({"Time": main_results.index, "Sum of Flows": main_results.values})
# CSV-Datei fĂĽr Hauptergebnisse speichern
df_main.to_csv("main_results.csv", index=False)
if __name__ == "__main__":
main()