Coverage for examples/OneRoom_CIA/main_cia_flex.py: 98%
96 statements
« prev ^ index » next coverage.py v7.4.4, created at 2026-03-26 09:43 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2026-03-26 09:43 +0000
1import matplotlib.pyplot as plt
2from matplotlib.ticker import FormatStrFormatter
3from agentlib.utils.multi_agent_system import LocalMASAgency
4import numpy as np
5import agentlib_mpc.utils.plotting.basic as mpcplot
6from agentlib_mpc.utils.analysis import mpc_at_time_step
7from agentlib_flexquant.generate_flex_agents import FlexAgentGenerator
8import logging
9from agentlib_flexquant.utils.interactive import Dashboard
11# Set the log-level
12logging.basicConfig(level=logging.WARN)
13until = 12000
15time_of_activation = 9000
17ENV_CONFIG = {"rt": False, "factor": 0.01, "t_sample": 10}
20def run_example(until=until, with_plots=False, with_dashboard=False):
21 """
22 Runs with the CIA algorithm for solving MINLPs. AgentLib-FlexQuant implements a
23 custom optimization backend, that also enables rounding instead of CIA for solving
24 these problems, which sometimes shows better performance. To toggle this option set
25 use_rounding in the config.
27 mpc_config:
28 Sets inputs, outputs, states, and parameters for the MPC agent.
29 It points to the path of the MPC problem definition file (simple_building.py) and defines the MPC parameters.
30 sim_config:
31 Sets inputs, outputs, and states for the simulation agent.
32 It points to the path of the FMU file and defines the simulation parameters.
33 predictor_config:
34 Sets parameters for the predictor agent and points to the path of the predictor formulation file (predictor.py).
35 flex_config:
36 Sets various options for the flexibility quantification framework:
37 - characteristic times for the indicator module (e.g. market time, preparation time, flex event duration)
38 - options for the cost calculation
39 - whether to use a constant electricity price or to input a time series sent by the predictor agent
40 - whether to use a constant feed-in tariff or to input a time series sent by the predictor agent
41 - if no feed-in is required (e.g. for a house without electricity generation), use a constant feed-in tariff with value 0
42 - option to correct the cost for stored energy at the end of the prediction horizon
43 - option to include a market config (points to a market config file)
44 - options for the flexibility agent generator:
45 - power variable of the baseline agent
46 - cost functions of PF-MPC and NF-MPC agents, including custom parameters and variables for the shadow MPCs
47 - general options such as results paths
48 """
49 results = []
50 mpc_config = "mpc_and_sim/simple_cia_mpc.json"
51 sim_config = "mpc_and_sim/simple_cia_sim.json"
52 predictor_config = "predictor/predictor_config.json"
53 flex_config = "flex_configs/flexibility_agent_config.json"
54 agent_configs = [sim_config, predictor_config]
56 config_list = FlexAgentGenerator(
57 flex_config=flex_config, mpc_agent_config=mpc_config
58 ).generate_flex_agents()
59 agent_configs.extend(config_list)
61 mas = LocalMASAgency(
62 agent_configs=agent_configs, env=ENV_CONFIG, variable_logging=False
63 )
65 mas.run(until=until)
66 results = mas.get_results(cleanup=False)
68 if with_plots:
69 # disturbances
70 fig, axs = mpcplot.make_fig(style=mpcplot.Style(use_tex=False), rows=1)
71 ax1 = axs[0]
72 # load
73 ax1.set_ylabel("$dot{Q}_{Room}$ in W")
74 results["SimAgent"]["room"]["load"].dropna().plot(ax=ax1, drawstyle="steps-post")
75 x_ticks = np.arange(0, 3600 * 6 + 1, 3600)
76 x_tick_labels = [int(tick / 3600) for tick in x_ticks]
77 ax1.set_xticks(x_ticks)
78 ax1.set_xticklabels(x_tick_labels)
79 ax1.set_xlabel("Time in hours")
80 for ax in axs:
81 mpcplot.make_grid(ax)
82 ax.set_xlim(0, 3600 * 6)
84 # room temp
85 fig, axs = mpcplot.make_fig(style=mpcplot.Style(use_tex=False), rows=1)
86 ax1 = axs[0]
87 # T out
88 ax1.set_ylabel("$T_{room}$ in K")
89 results["SimAgent"]["room"]["T_upper"].plot(ax=ax1, color="0.5")
90 results["SimAgent"]["room"]["T_out"].plot(ax=ax1,
91 color=mpcplot.EBCColors.dark_grey)
92 mpc_at_time_step(
93 data=results["Baseline"]["Baseline"], time_step=time_of_activation,
94 variable="T"
95 ).plot(ax=ax1, label="base", linestyle="--", color=mpcplot.EBCColors.dark_grey)
96 mpc_at_time_step(
97 data=results["NegFlexMPC"]["NegFlexMPC"], time_step=time_of_activation,
98 variable="T"
99 ).plot(ax=ax1, label="neg", linestyle="--", color=mpcplot.EBCColors.red)
100 mpc_at_time_step(
101 data=results["PosFlexMPC"]["PosFlexMPC"], time_step=time_of_activation,
102 variable="T"
103 ).plot(ax=ax1, label="pos", linestyle="--", color=mpcplot.EBCColors.blue)
105 ax1.legend()
106 ax1.vlines(time_of_activation, ymin=0, ymax=500, colors="black")
107 ax1.vlines(time_of_activation + 300, ymin=0, ymax=500, colors="black")
108 ax1.vlines(time_of_activation + 600, ymin=0, ymax=500, colors="black")
109 ax1.vlines(time_of_activation + 3000, ymin=0, ymax=500, colors="black")
111 ax1.set_ylim(289, 299)
112 x_ticks = np.arange(0, 3600 * 6 + 1, 3600)
113 x_tick_labels = [int(tick / 3600) for tick in x_ticks]
114 ax1.set_xticks(x_ticks)
115 ax1.set_xticklabels(x_tick_labels)
116 ax1.set_xlabel("Time in hours")
117 for ax in axs:
118 mpcplot.make_grid(ax)
119 ax.set_xlim(0, 3600 * 6)
121 # predictions
122 fig, axs = mpcplot.make_fig(style=mpcplot.Style(use_tex=False), rows=1)
123 ax1 = axs[0]
124 # P_el
125 ax1.set_ylabel("$P_{el}$ in W")
126 results["SimAgent"]["room"]["P_el"].plot(ax=ax1,
127 color=mpcplot.EBCColors.dark_grey)
128 mpc_at_time_step(
129 data=results["NegFlexMPC"]["NegFlexMPC"], time_step=time_of_activation,
130 variable="P_el"
131 ).ffill().plot(
132 ax=ax1,
133 drawstyle="steps-post",
134 label="neg",
135 linestyle="--",
136 color=mpcplot.EBCColors.red,
137 )
138 mpc_at_time_step(
139 data=results["PosFlexMPC"]["PosFlexMPC"], time_step=time_of_activation,
140 variable="P_el"
141 ).ffill().plot(
142 ax=ax1,
143 drawstyle="steps-post",
144 label="pos",
145 linestyle="--",
146 color=mpcplot.EBCColors.blue,
147 )
148 mpc_at_time_step(
149 data=results["Baseline"]["Baseline"], time_step=time_of_activation,
150 variable="P_el"
151 ).ffill().plot(
152 ax=ax1,
153 drawstyle="steps-post",
154 label="base",
155 linestyle="--",
156 color=mpcplot.EBCColors.dark_grey,
157 )
158 ax1.legend()
159 ax1.vlines(time_of_activation, ymin=0, ymax=500, colors="black")
160 ax1.vlines(time_of_activation + 300, ymin=0, ymax=500, colors="black")
161 ax1.vlines(time_of_activation + 600, ymin=0, ymax=500, colors="black")
162 ax1.vlines(time_of_activation + 3000, ymin=0, ymax=500, colors="black")
164 # flexibility
165 # get only the first prediction time of each time step
166 ind_res = results["FlexibilityIndicator"]["FlexibilityIndicator"]
167 energy_flex_neg = ind_res.xs("negative_energy_flex", axis=1).droplevel(
168 1).dropna()
169 energy_flex_pos = ind_res.xs("positive_energy_flex", axis=1).droplevel(
170 1).dropna()
171 fig, axs = mpcplot.make_fig(style=mpcplot.Style(use_tex=False), rows=1)
172 ax1 = axs[0]
173 ax1.set_ylabel("$epsilon$ in kWh")
174 energy_flex_neg.plot(ax=ax1, label="neg", color=mpcplot.EBCColors.red)
175 energy_flex_pos.plot(ax=ax1, label="pos", color=mpcplot.EBCColors.blue)
176 ax1.yaxis.set_major_formatter(FormatStrFormatter("%.4f"))
178 ax1.legend()
180 x_ticks = np.arange(0, 3600 * 6 + 1, 3600)
181 x_tick_labels = [int(tick / 3600) for tick in x_ticks]
182 ax1.set_xticks(x_ticks)
183 ax1.set_xticklabels(x_tick_labels)
184 ax1.set_xlabel("Time in hours")
185 for ax in axs:
186 mpcplot.make_grid(ax)
187 ax.set_xlim(0, 3600 * 6)
188 plt.show()
190 if with_dashboard:
191 Dashboard(
192 flex_config="flex_configs/flexibility_agent_config.json",
193 simulator_agent_config="mpc_and_sim/simple_cia_sim.json",
194 results=results
195 ).show()
197 return results
200if __name__ == "__main__":
201 run_example(until, with_plots=True, with_dashboard=False)