Implementing an EMS strategy

Energy Management Strategies are handled by Energy Management Systems (EMS). To implement a new strategy, additions in multiple places are necessary.

1. Adapt the EMS_model.py file and implement the operating strategy

Create a new class that is inheriting from the general HEMS class.

eelib/core/control/EMS/EMS_model.py (01/24)
290 class HEMS_default(HEMS):
291     """Default strategy for Energy Management System.
292     Should be copied and adapted for the use of a specific EMS concept.
293     """
294
295     @classmethod
296     def get_valid_parameters(cls):
297         """Returns dictionary containing valid parameter types and values.
298
299         Returns:
300             dict: valid parameters for this model
301         """
302
303         # use parent's parameter list and modify them for this class
304         result = HEMS.get_valid_parameters().copy()
305         result.update({})
306         return result
307
308     def __init__(self, ename: str, step_size: int = 900, **kwargs):
309         """Initializes the eELib HEMS default model.
310
311         Args:
312             ename (str): name of the entity to create
313             step_size (int): length of a simulation step in seconds
314             **kwargs: initial values for the HEMS entity
315
316         Raises:
317             ValueError: Error if selected strategy does not comply with model type.
318         """
319
320         # check given strategy
321         if "strategy" in kwargs.keys() and kwargs["strategy"] != "HEMS_default":
322             raise ValueError("Created a HEMS_default entity with strategy not 'HEMS_default'!")
323         else:
324             kwargs["strategy"] = "HEMS_default"  # set strategy if not already given
325
326         # call init function of super HEMS class
327         super().__init__(ename=ename, step_size=step_size, **kwargs)

Add a step() function that first calls the HEMS step() and afterwards implement the functionalities of your operating strategy

eelib/core/control/EMS/EMS_model.py (01/24)
329 def step(self, time):
330     """Calculates power set values for each connected component according to the strategy.
331
332     Args:
333         time (int): Current simulation time
334     """
335
336     # execute general processes (aggregation of power values etc.)
337     super().step(time)
338
339     # from here on: execute strategy-specific processes
340     ...

2. Add the strategy and its input to the model_data of the scenarios

examples/data/model_data_scenario/model_data_building.json (01/24)
1{
2    "ems": [
3        {
4            "strategy": "HEMS_default",
5            "cs_strategy": "balanced"
6        }
7    ],
8    ...

3. Add your EMS class to the model_connections/model_connect_config.json file

Add the data that is sent out

eelib/model_connections/model_connect_config.json (01/24)
10"HEMS_default": {
11    "HouseholdCSV": [],
12    "PvCSV": [],
13    "PVLib": [["p_set_pv", "p_set"]],
14    "PVLibExact": [["p_set_pv", "p_set"]],
15    "BSS": [
16        [
17            "p_set_storage",
18            "p_set"
19        ]
20    ],
21    "ChargingStation": [
22        [
23            "p_set_charging_station",
24            "p_set"
25        ]
26    ],
27    "ChargingStationCSV": [],
28    "EV": [],
29    "HouseholdThermalCSV": [],
30    "HeatpumpCSV": [],
31    "Heatpump": [
32        [
33            "p_th_set_heatpump",
34            "p_th_set"
35        ]
36    ],
37    "grid_load": [["p_balance", "p_w"], ["q_balance", "q_var"]]
38},

… but also to every model, which data is sent to your HEMS!

e.g. but not only the BSS
111"BSS": {
112    "HEMS_default": [
113        [
114            "p_discharge_max",
115            "p_min"
116        ],
117        [
118            "p_charge_max",
119            "p_max"
120        ],
121        [
122            "p",
123            "p"
124        ]
125    ],
126    "HouseholdCSV": [],
127    "PvCSV": [],
128    "PVLib": [],
129    "PVLibExact": [],
130    "ChargingStation": [],
131    "ChargingStationCSV": [],
132    "EV": [],
133    "HouseholdThermalCSV": [],
134    "HeatpumpCSV": [],
135    "Heatpump": []
136},

As you can see, also connections that do not share data are added.


4. Add the model with its name and (input/output) attributes to the META of the EMS_simulator

eelib/core/control/EMS/EMS_simulator.py (01/24)
14META = {
15    "type": "hybrid",
16    "models": {
50        "HEMS_default": {
51            "public": True,
52            "params": ["init_vals"],
53            "attrs": [
54                "q",
55                "p",
56                "p_max",
57                "p_min",
58                "p_set_storage",
59                "p_set_charging_station",
60                "p_set_pv",
61                "p_balance",
62                "q_balance",
63                "appearance_end_step",
64                "discharge_cs_efficiency",
65                "charge_cs_efficiency",
66                "e_bat_car",
67                "e_bat_max_car",
68                "p_th_room",
69                "p_th_water",
70                "p_th_dem",
71                "p_th_dev",
72                "p_th_balance",
73                "p_th_min",
74                "p_th_max",
75                "p_th_min_on",
76                "p_th_set_heatpump",
77            ],