# MIDAS Powergrid Module

The powergrid module, provided by the midas-powergrid package, contains a simulator for pandapower networks, which will be called grids in the context of MIDAS.

## Installation

This package will usually installed automatically together with midas-mosaik. It is available on pypi, so you can install it manually with

    pip install midas-powergrids

## Usage

The intended use-case for the time simulator is to be used inside of MIDAS. However, it only depends on the midas-util package and be used in any mosaik simulation scenario.

### Inside of MIDAS

To use the store inside of MIDAS, simply add powergrid to your modules

    my_scenario:
      modules:
        - powergrid
        # - ...

and provide a scope and a gridfile:

    my_scenario:
      # ...
      powergrid_params:
        my_grid_scope:
          gridfile: midasmv

Other, data-providing simulators with the same scope will output their data to this grid. Possible values for gridfile will be described in the Keys section below.

### Any Mosaik Scenario

If you don’t use MIDAS, you can add the powergrid manually to your mosaik scenario file. First, the entry in the sim_config:

    sim_config = {
        "Powergrid": {"python": "midas.modules.powergrid:PandapowerSimulator"},
        # ...
    }

Next, you need to start the simulator (assuming a step_size of 900):

    grid_sim = world.start("Powergrid", step_size=900)

Finally, the model needs to be started:

    grid = grid_sim.Grid(gridfile="midasmv")

To connect the output of the grids’ buses to another model, you have to get the list of bus models from the powergrids’ children like

    bus_models = [e for e in grid.children if "bus" in e.eid]

and then connect those models either individually or in a loop, e.g.,

    for bus in bus_models:
        world.connect(bus, other_entity, "vm_pu", "va_degree", "p_mw", "q_mvar")

The inputs are generally handled in the same way. Have a look at grid.children to get the required entity eids.

## The Keys of the Powergrid Simulator

This section gives a short description for all of the keys of the powergrid module. Keys that are part of every upgrade module will only be mentioned if the actual behavior might be unexpected.

step_size

  This key is mainly ignored by the grid model itself, since the model has no time-based internal state.

plotting

  This key allows to enable grid plotting for certain grids. The value is of type bool and defaults to false.

plot_path

  This key specifies where the plotted grid images will be stored. The value is of type string and the default value is plots, which will create a directory called plots in the _outputs directory defined in midas-runtime-conf.yaml.

save_grid_json

  The value of this key is of type bool. If set to true, the grid model will serialize the pandapower grid to json and send it to the database. Since the resulting string is rather long, this option is set to false by default.

use_constraints

  This key allows to enable the experimental feature of grid constraints. The value is of type bool and defaults to false.

constraints

  If use_constraints is set to true, this key allows to define the constraints to be used. Once the feature is more evaluated, it will get its own section. The constrainted_grids.yml scenario file in the MIDAS source code contains examples for different grids.

All above keys can be overwritten (or solely defined) within a certain scope. However, available on scope level only are the following keys:

gridfile

  This keys defines the grid topology to be loaded. The type of the value is string but there are different semantics to that string. First, there are a few pandapower grid topologies that can be directly accessed with aliases. Those are cigre_hv, cigre_mv and cigre_lv for the corresponding grids. Second, a few more aliases are midasmv, midaslv, and bhv, which load certain custom grids defined inside of MIDAS (bhv is the Bremerhaven Grid developed by a students’ project group at the University of Oldenburg). Next, any Simbench code can be entered to load the corresponding grid (to get the data set of that grid, you have to modify the midas-runtime-conf.yaml, see the sbdata module for more information). Finally, a python import string to a function can be entered that returns a pandapower grid. This allows to define custom grids even outside of MIDAS. The last segment of the import string needs to be the function to be called. Parameters to that function can be passed with the grid_params key. Additionally, grids can be loaded from .json or .xlsx files can be loaded. The full (absolute or relative) path to those files needs to be entered.

grid_params

  This key allows to pass additional parameters to grids that are neither .json nor .xlsx nor Simbench grids. The value is of type dictionary and the values will be passed without further checking. The default value is an empty dictionary.

## Inputs of the Powergrid Simulator

The exact number of inputs depends on the grid topology that is used. The grid has a number of children models, representing different components of the grid.

The most important attributes of loads, sgens, and storages (not available in every grid) are:

p_mw

  Active power in Mega Watt of the grid node. The behavior depends on the role (load, sgen, or storage) and multiple inputs to the same node will be summed up. The value is of type float.

q_mvar

  Reactive power in Mega Volt-Ampere reactive of the grid node. The behavior depends on the role (load, sgen, or storage) and multiple inputs to the same node will be summed up. The value is of type float.

Transformators have an input as well:

tap_pos

  The currently active tap position. The value is of type integer and defaults to 0. The tap_pos can be between tap_min and tap_max, defined in the grid itself. Currently, there is no MIDAS simulator that makes use of this input.

Finally, there are the switches which have an input:

closed

  Controls the current state of the switch. The default setting is closed, i.e., closed is set to true. Currently, there is no MIDAS simulator that makes use of this input.

## Outputs of the Powergrid Simulator

The grid itself has two outputs:

health

  The average voltage magnitude per unit of all the buses in the grid. The value is of type float.

grid_json

  A string containing the json-serialized grid.

The bus nodes of the grid have four outputs:

vm_pu

  The voltage magnitude per unit in relation to the slack node in the grid. The value is of type float.

va_degree

  The angle between voltage and current. The value is of type float.

p_mw

  The active power that arives at the bus. The value is of type float.

q_mvar

  The reactive power that arives at the bus. The value is of type float.

Lines and transformators have (among others) the following output:

loading_percent

  The load utilization relative to the rated power. The value is of type float.

Additionally, the nodes that are listed in the inputs section, will send there current input to the database if one is used.

## PalaestrAI Sensors of the Powergrid Simulator

If the with_arl is set either on the scenario levle or on the module level, sensor objects for the following outputs will be created. However, space definitions needed to be generalized and may not represent the actual space of the attribute.

- loading_percent (Trafo, Line) = Box(0, 1, (1,), np.float32)

- vm_pu (Bus) = Box(0.8, 1.2, (1,), np.float32)

- va_degree (Bus) = Box(-1, 1, (1,), np.float32)

- p_mw (Load, Sgen, Storage, Ext_grid) = Box(0, 1, (1,), np.float32)

- q_mvar (Load, Sgen, Storage, Ext_grid) = Box(-1, 1, (1,), np.float32)

- health (Grid) = Box(0, 1.2, (1,), np.float32)

- grid_json (Grid) = Box(0, 1, (1,), np.float32)

The last one (grid_json) is actually a string and not intented to be used as common sensor.

## PalaestrAI Actuators of the Powergrid Simulator

With the with_arl flag, the following actuators will be created. The spaces have the same limitations as with the sensors.

- tap_pos (Trafo): Box(-10, 10, (1,), np.int32)

- p_mw (Load, Sgen): Box(0, 0.5, (1,), np.float32)

- q_mvar (Load, Sgen): Box(0, 0.5, (1,), np.float32)

## Example Scenario Configuration

The following scenario (tbd) runs the same grid twice but one instance will use the (yet experimental) grid constraints.