Implementing an Operating Strategy

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

Add your strategy to the hems_model package

The convention is to use one file and one class per strategy, named in the following way. hems_<strategy name>.py contains the class HEMS_<strategy name>. E.g. the Operating Strategy for user-based multi-use is abbreviated as “mu_user” from which follows that the file hems_mu_user.py contains only the class HEMS_mu_user(HEMS).

You also have to list your strategy in the package to expose it to the simulator, by adding

from .hems_<strategy name> import HEMS_<strategy name>

to the hems_model/__init__.py.

Inherit existing methods and add your behaviour

Let your class inherit from the base class HEMS. You can also inherit from subclasses of the HEMS class like HEMS_default to gain access to their methods and properties.

eelib/core/control/hems/hems_model/hems_default.py (12/24)
13 class HEMS_default(HEMS):
14     """Default strategy for Energy Management System.
15     Should be copied and adapted for the use of a specific HEMS concept.
16     """
17
18     @classmethod
19     def get_valid_parameters(cls):
20         """Returns dictionary containing valid parameter types and values.
21
22         Returns:
23             dict: valid parameters for this model
24         """
25
26         # use parent's parameter list and modify them for this class
27         result = HEMS.get_valid_parameters().copy()
28         result.update({})
29         return result
30
31     def __init__(self, eid: str, step_size: int = 900, **kwargs):
32         """Initializes the eELib HEMS default model.
33
34         Args:
35             eid (str): name of the entity to create
36             step_size (int): length of a simulation step in seconds
37             **kwargs: initial values for the HEMS entity
38         """
39
40         # call init function of super HEMS class
41         super().__init__(eid=eid, 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/hems/hems_model/hems_default.py (12/24)
43     def step(self, timestep: int):
44         """Calculates power set values for each connected component according to the strategy.
45
46         Args:
47             timestep (int): Current simulation time
48         """
49
50         # execute general processes (aggregation of power values etc.)
51         super().step(timestep)
52
53         # from here on: execute strategy-specific processes
54         ...

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

If you want to use your strategy in an (example) scenario, add a HEMS in the following way.

examples/data_input/model_data_scenario/model_data_building.json (12/24)
 1 {
 2     "HEMS_default": {
 3         "HEMS_default_0": {
 4             "cs_strategy": "max_p",
 5             "bss_strategy": "surplus"
 6         }
 7     },
 8     "HouseholdCSV": {
 9         "HouseholdCSV_0": {
10     ...

Add your connections to the eelib/model_connections/model_connect_config.json

Add the data that is sent out

eelib/model_connections/model_connect_config.json (12/24)
40    "HEMS_default": {
41        "PVLib": [
42            [
43                "p_set_pv",
44                "p_set"
45            ]
46        ],
47        "PVLibExact": [
48            [
49                "p_set_pv",
50                "p_set"
51            ]
52        ],
53        "BSS": [
54            [
55                "p_set_storage",
56                "p_set"
57            ]
58        ],
59        ...

… 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    ...
127},

Hint

Check all entries of "HEMS_default":. You likely need all these connections for your strategy as well, extended by your specific additions.


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

eelib/core/control/hems/hems_simulator.py (12/24)
20 META = {
21     "type": "hybrid",
22     "models": {
28         "HEMS_default": {
29             "public": True,
30             "params": ["init_vals"],
31             "attrs": [
32                 "q",
33                 "p",
34                 "p_max",
35                 "p_min",
36                 "p_set_storage",
37                 ...