diff --git a/.circleci/config.yml b/.circleci/config.yml index 90f75038..a82b4eb9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -29,7 +29,7 @@ executors: - image: cimg/python:3.13 jobs: - test: + test_generic: executor: grid2op-executor resource_class: medium+ parallelism: 4 @@ -70,6 +70,155 @@ jobs: # - store_artifacts: # path: "/Grid2Op/grid2op/tests/test_Action.py" # destination: coverage_artifacts/ + test_agent: + executor: grid2op-executor + resource_class: small + steps: + - checkout + - run: apt-get update -y + - run: apt-get install -y coinor-cbc + - run: python -m pip install virtualenv + - run: python -m virtualenv venv_test + - run: + command: | + source venv_test/bin/activate + pip install -U pip setuptools wheel + - run: + command: | + source venv_test/bin/activate + pip install -e .[test] + pip freeze + - run: + command: | + source venv_test/bin/activate + export _GRID2OP_FORCE_TEST=1 + cd grid2op/tests/ + python -m unittest -v test_Agent test_AgentsFast test_recopowerlineperarea + + test_converter: + executor: grid2op-executor + resource_class: small + steps: + - checkout + - run: apt-get update -y + - run: apt-get install -y coinor-cbc + - run: python -m pip install virtualenv + - run: python -m virtualenv venv_test + - run: + command: | + source venv_test/bin/activate + pip install -U pip setuptools wheel + - run: + command: | + source venv_test/bin/activate + pip install -e .[test] + pip freeze + - run: + command: | + source venv_test/bin/activate + export _GRID2OP_FORCE_TEST=1 + cd grid2op/tests/ + python -m unittest -v test_AgentConverter test_Converter test_BackendConverter + + test_runner_epdata_score: + executor: grid2op-executor + resource_class: small + steps: + - checkout + - run: apt-get update -y + - run: apt-get install -y coinor-cbc + - run: python -m pip install virtualenv + - run: python -m virtualenv venv_test + - run: + command: | + source venv_test/bin/activate + pip install -U pip setuptools wheel + - run: + command: | + source venv_test/bin/activate + pip install -e .[test] + pip freeze + - run: + command: | + source venv_test/bin/activate + export _GRID2OP_FORCE_TEST=1 + cd grid2op/tests/ + python -m unittest -v test_EpisodeData test_runner_kwargs_backend test_Runner test_RunnerFast test_score_idf_2023_assistant test_score_idf_2023_nres test_score_idf_2023 test_score_wcci_2022 test_AlarmScore test_RewardAlertCostScore test_RewardNewRenewableSourcesUsageScore test_utils test_CompactEpisodeData test_reset_options_runner + + test_env_general: + executor: grid2op-executor + resource_class: small + steps: + - checkout + - run: apt-get update -y + - run: apt-get install -y coinor-cbc + - run: python -m pip install virtualenv + - run: python -m virtualenv venv_test + - run: + command: | + source venv_test/bin/activate + pip install -U pip setuptools wheel + - run: + command: | + source venv_test/bin/activate + pip install -e .[test] + pip freeze + - run: + command: | + source venv_test/bin/activate + export _GRID2OP_FORCE_TEST=1 + cd grid2op/tests/ + python -m unittest -v test_attached_envs test_attached_envs_compat test_l2rpn_idf_2023 test_MultiMix test_timeOutEnvironment test_MaskedEnvironment test_MakeEnv test_multi_steps_env test_simenv_blackout + + test_alert_alarm: + executor: grid2op-executor + resource_class: small + steps: + - checkout + - run: apt-get update -y + - run: apt-get install -y coinor-cbc + - run: python -m pip install virtualenv + - run: python -m virtualenv venv_test + - run: + command: | + source venv_test/bin/activate + pip install -U pip setuptools wheel + - run: + command: | + source venv_test/bin/activate + pip install -e .[test] + pip freeze + - run: + command: | + source venv_test/bin/activate + export _GRID2OP_FORCE_TEST=1 + cd grid2op/tests/ + python -m unittest -v test_AlarmFeature test_alert_gym_compat test_alert_obs_act test_alert_trust_score test_AlertReward + + test_issue: + executor: grid2op-executor + resource_class: small + steps: + - checkout + - run: apt-get update -y + - run: apt-get install -y coinor-cbc + - run: python -m pip install virtualenv + - run: python -m virtualenv venv_test + - run: + command: | + source venv_test/bin/activate + pip install -U pip setuptools wheel + - run: + command: | + source venv_test/bin/activate + pip install -e .[test] + pip freeze + - run: + command: | + source venv_test/bin/activate + export _GRID2OP_FORCE_TEST=1 + cd grid2op/tests/ + python -m unittest -v test_issue_* gen_coverage: executor: grid2op-executor @@ -446,7 +595,13 @@ workflows: version: 2.1 test: jobs: - - test + - test_generic + - test_agent + - test_converter + - test_runner_epdata_score + - test_env_general + - test_alert_alarm + - test_issue - legacy_lightsim_old_pp - legacy_lightsim - test_chronix2grid diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 37ccb6cf..cb9f8a2f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -100,6 +100,22 @@ Native multi agents support: - add detachment - add change_bus / set_bus +[1.12.3] - 2026-02-04 +----------------------- +- [FIXED] the warnings when building the documentation. +- [FIXED] the deprecation warnings when importing grid2op + with recent python versions (due to presence of math equation + in some docstring) +- [FIXED] issues when loading a grid with disconnected elements: grid2op + did not know on which bus to reconnect them when only the "reconnect" bus was given. +- [FIXED] an issue leading to wrong setpoint values for shunt_p and shunt_q in the previous + stored state (EnvPreviousState) +- [FIXED] a wrong type hints in `_aux_check_finite_float` of Backend (in Backend.py) +- [ADDED] a test (in the AAA test) to assess that the backend._sh_vnkv is properly set if the shunts are + handled by the backend. +- [IMPROVED] code for AAA backend tests (avoid equality check for float) +- [IMPROVED] doc when loading grid with disconnected elements + [1.12.2] - 2025-11-18 ---------------------- - [FIXED] an issue preventing to change the way @@ -1169,8 +1185,8 @@ Native multi agents support: - [ADDED]: a new kind of opponent that is able to attack at "more random" times with "more random" duration. See the `GeometricOpponent`. - [IMPROVED]: on windows at least, grid2op does not work with gym < 0.17.2 Checks are performed in order to make sure - the installed open ai gym package meets this requirement (see issue - `Issue#185 `_ ) + the installed open ai gym package meets this requirement + (see issue `Issue#185 `_ ) - [IMPROVED] the seed of openAI gym for composed action space (see issue `https://github.com/openai/gym/issues/2166`): in waiting for an official fix, grid2op will use the solution proposed there https://github.com/openai/gym/issues/2166#issuecomment-803984619 diff --git a/docs/conf.py b/docs/conf.py index 2527c594..4936e0d3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,7 +22,7 @@ author = 'Benjamin Donnot' # The full version, including alpha/beta/rc tags -release = '1.12.2' +release = '1.12.3' version = '1.12' @@ -35,14 +35,15 @@ 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.coverage', - 'sphinx.ext.imgmath', + 'sphinx.ext.imgmath', # for math in documentation 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode', # 'builder', 'sphinx.ext.extlinks', 'sphinx.ext.napoleon', 'sphinxcontrib_trio', - "sphinx_rtd_theme", + "sphinx_rtd_theme", + # 'sphinx.ext.mathjax', # toc of modules 'autodocsumm', # 'sphinx.ext.autosectionlabel', diff --git a/docs/developer.rst b/docs/developer.rst deleted file mode 100644 index f32eb13d..00000000 --- a/docs/developer.rst +++ /dev/null @@ -1,8 +0,0 @@ -.. toctree:: - :maxdepth: 1 - - developer/env_content - developer/create_an_environment - developer/createbackend - -.. include:: final.rst diff --git a/docs/grid2op_dev.rst b/docs/grid2op_dev.rst index 6beedb0d..3d44046d 100644 --- a/docs/grid2op_dev.rst +++ b/docs/grid2op_dev.rst @@ -2,6 +2,5 @@ :maxdepth: 1 grid2op_dev/action - grid2op_dev/observation .. include:: final.rst diff --git a/docs/grid2op_extend.rst b/docs/grid2op_extend.rst new file mode 100644 index 00000000..1bce8296 --- /dev/null +++ b/docs/grid2op_extend.rst @@ -0,0 +1,9 @@ +.. toctree:: + :maxdepth: 1 + + grid2op_extend/env_content + grid2op_extend/create_an_environment + grid2op_extend/createbackend + grid2op_extend/observation + +.. include:: final.rst diff --git a/docs/developer/create_an_environment.rst b/docs/grid2op_extend/create_an_environment.rst similarity index 100% rename from docs/developer/create_an_environment.rst rename to docs/grid2op_extend/create_an_environment.rst diff --git a/docs/developer/createbackend.rst b/docs/grid2op_extend/createbackend.rst similarity index 99% rename from docs/developer/createbackend.rst rename to docs/grid2op_extend/createbackend.rst index c1ecc86e..124925f8 100644 --- a/docs/developer/createbackend.rst +++ b/docs/grid2op_extend/createbackend.rst @@ -63,12 +63,12 @@ Objectives You will also find in this file the complete description on how the "powergrid" is represented in grid2op. Backend is an abstraction that represents the physical system (the powergrid). In theory every powerflow can be - used as a backend. And example of a backend using `Pandapower `_ is available with - the :class:`grid2op.Backend.EducPandaPowerBackend.EducPandaPowerBackend` (only for demonstration purpose) + used as a backend. And example of a backend using `Pandapower `__ is available with + the :class:`grid2op.Backend.educPandaPowerBackend.EducPandaPowerBackend` (only for demonstration purpose) If you want working backend, please use the :class:`grid2op.Backend.PandaPowerBackend` that - uses `Pandapower `_ and - a port in c++ to a subset of pandapower called `LightSim2Grid `_ . + uses `Pandapower `__ and + a port in c++ to a subset of pandapower called `LightSim2Grid `__ . To implement completely a backend, you should implement all the abstract function defined here :ref:`backend-module`. diff --git a/docs/developer/env_content.rst b/docs/grid2op_extend/env_content.rst similarity index 100% rename from docs/developer/env_content.rst rename to docs/grid2op_extend/env_content.rst diff --git a/docs/developer/final.rst b/docs/grid2op_extend/final.rst similarity index 100% rename from docs/developer/final.rst rename to docs/grid2op_extend/final.rst diff --git a/docs/developer/observation.rst b/docs/grid2op_extend/observation.rst similarity index 100% rename from docs/developer/observation.rst rename to docs/grid2op_extend/observation.rst diff --git a/docs/index.rst b/docs/index.rst index d6fc74dd..6cf59ea3 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -202,7 +202,7 @@ but if you want to slightly modify one of its component. :maxdepth: 1 :caption: Technical documentation for grid2op "external" contributions - developer + grid2op_extend Technical documentation for grid2op developers diff --git a/docs/special.rst b/docs/special.rst index 5b210239..68ffebc5 100644 --- a/docs/special.rst +++ b/docs/special.rst @@ -1,6 +1,7 @@ .. Color profiles for Sphinx. .. Has to be used with hacks.css .. (https://bitbucket.org/lbesson/web-sphinx/src/master/.static/hacks.css) + .. role:: black .. role:: gray .. role:: grey @@ -38,4 +39,4 @@ .. role:: center .. role:: left .. role:: right -.. (c) Lilian Besson, 2011-2016, https://bitbucket.org/lbesson/web-sphinx/ \ No newline at end of file +.. (c) Lilian Besson, 2011-2016, https://bitbucket.org/lbesson/web-sphinx/ diff --git a/docs/user/action.rst b/docs/user/action.rst index aa23bd58..1f9f0bb2 100644 --- a/docs/user/action.rst +++ b/docs/user/action.rst @@ -453,6 +453,17 @@ action original status final status \* means that this bus is affected: if it was on bus 1 it moves on bus 2 and vice versa. +.. danger:: + In the general case, the "last state" (denoted `PREVIOUS_OR` or `PREVIOUS_EX`) is known. But it is not always the case. + + It can happen that the original grid file (the one loaded by grid2op backend to create the environment) has + disconnected elements. + + In this case, it is NOT possible to reconnect said elements without provided explicitely the buses at both sides. Any + attempt to do so will lead to a "illegal" action and will be replaced by "do nohting" in env.step (thus discarding all other + "parts" of the action). + + Note on random actions ------------------------ Sampling a "non ambiguous" legal action is a difficult task. diff --git a/docs/user/opponent.rst b/docs/user/opponent.rst index 9f47edc9..0998a3d3 100644 --- a/docs/user/opponent.rst +++ b/docs/user/opponent.rst @@ -41,11 +41,12 @@ First, a grid is said to be "in security" if no threshold are violate for any eq In the context of grid2op, this most often means that all powerlines have a flow under a certain threshold (refer to as "thermal limit" in grid2op). -``̀` -A grid is N-1 safe, if, for any "contingency" (*eg* the disconnection a powerline) from -a given list (in general this list is "all the lines / transformers on the grid"), the grid would -still be "in security" (define in the above paragraph) after this contingency occurred. -``̀` +.. important:: + + A grid is N-1 safe, if, for any "contingency" (*eg* the disconnection a powerline) from + a given list (in general this list is "all the lines / transformers on the grid"), the grid would + still be "in security" (define in the above paragraph) after this contingency occurred. + N-1 with corrective actions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -59,11 +60,11 @@ contingency to avoid the grid to go out of security. This would give the following definition of N-1 security: -``̀` -A grid is N-1 secure (with corrective action), if an only if, for a any contingency (among a given list), -it is possible to find (at least) a corrective action (understand: an action that can be quickly implemented after -the contingency, including the "I do nothing action") that would bring the grid back to security. -``̀` +.. important:: + A grid is N-1 secure (with corrective action), if an only if, for a any contingency (among a given list), + it is possible to find (at least) a corrective action (understand: an action that can be quickly implemented after + the contingency, including the "I do nothing action") that would bring the grid back to security. + .. note:: If a grid is N-1 secure (as described in the above paragraph), it will be "N-1 secure (with corrective action)". @@ -78,11 +79,11 @@ or a few days). The N-1 criterion can then be "extended" to include the time dependance. The natural definition would be: -``̀` -A grid is N-1 scure accross the time interval [beginning, end] if (and only if), for any contingency -(among a given list) occurring during this time interval, there exists a list of corrective actions that -can ensure the grid remains in security at any time until the end of this interval". -``̀` +.. important:: + A grid is N-1 scure accross the time interval [beginning, end] if (and only if), for any contingency + (among a given list) occurring during this time interval, there exists a list of corrective actions that + can ensure the grid remains in security at any time until the end of this interval". + .. note:: If the grid state is not modified by any action, assessing whether or not the grid is "N-1 secure on a given time interval" diff --git a/docs/user/special.rst b/docs/user/special.rst index a4b7a9d9..8f668078 100644 --- a/docs/user/special.rst +++ b/docs/user/special.rst @@ -1,4 +1,5 @@ .. for the color + .. include:: ../special.rst .. _n_gen: ./space.html#grid2op.Space.GridObjects.n_gen diff --git a/grid2op/Action/_backendAction.py b/grid2op/Action/_backendAction.py index 1aafe621..9ad67936 100644 --- a/grid2op/Action/_backendAction.py +++ b/grid2op/Action/_backendAction.py @@ -245,7 +245,7 @@ def __getitem__(self, item): def __iter__(self): return self - + def __next__(self): res = None while self.last_index < self.values.shape[0]: @@ -910,7 +910,7 @@ def __iadd__(self, other : BaseAction) -> Self: # V Force disconnected status # of disconnected powerlines extremities self._status_or[:], self._status_ex[:] = self.current_topo.get_line_status( - self.line_or_pos_topo_vect, self.line_ex_pos_topo_vect + cls.line_or_pos_topo_vect, cls.line_ex_pos_topo_vect ) # At least one disconnected extremity @@ -943,6 +943,13 @@ def _assign_0_to_disco_el(self) -> None: sto_changed = self.current_topo.changed[cls.storage_pos_topo_vect] sto_bus = self.current_topo.values[cls.storage_pos_topo_vect] self.storage_power.force_unchanged(sto_changed, sto_bus) + + def invalidate_cache(self): + """INTERNAL + + Used when environment is loaded from an observation (eg ForecastEnv) + """ + self._is_cached = False def __call__(self) -> Tuple[np.ndarray, Tuple[ValueStore, ValueStore, ValueStore, ValueStore, ValueStore], diff --git a/grid2op/Action/baseAction.py b/grid2op/Action/baseAction.py index 2de4d095..b2d2d4e4 100644 --- a/grid2op/Action/baseAction.py +++ b/grid2op/Action/baseAction.py @@ -216,13 +216,13 @@ class BaseAction(GridObjects): _subs_impacted: :class:`numpy.ndarray`, dtype:bool This attributes is either not initialized (set to ``None``) or it tells, for each substation, if it is impacted - by the action (in this case :attr:`BaseAction._subs_impacted`\[sub_id\] is ``True``) or not - (in this case :attr:`BaseAction._subs_impacted`\[sub_id\] is ``False``) + by the action (in this case :attr:`BaseAction._subs_impacted` [sub_id] is ``True``) or not + (in this case :attr:`BaseAction._subs_impacted` [sub_id] is ``False``) _lines_impacted: :class:`numpy.ndarray`, dtype:bool This attributes is either not initialized (set to ``None``) or it tells, for each powerline, if it is impacted - by the action (in this case :attr:`BaseAction._lines_impacted`\[line_id\] is ``True``) or not - (in this case :attr:`BaseAction._subs_impacted`\[line_id\] is ``False``) + by the action (in this case :attr:`BaseAction._lines_impacted` [line_id] is ``True``) or not + (in this case :attr:`BaseAction._subs_impacted` [line_id] is ``False``) attr_list_vect: ``list``, static The authorized key that are processed by :func:`BaseAction.__call__` to modify the injections @@ -630,6 +630,7 @@ def __init__(self, _names_chronics_to_backend: Optional[Dict[Literal["loads", "p #: .. versionadded:: 1.12.1 + #: #: allows the agent to perform an action #: that depends on the backend type used. #: See the doc for more information. @@ -652,7 +653,8 @@ def __init__(self, _names_chronics_to_backend: Optional[Dict[Literal["loads", "p self._modif_detach_storage = False #: .. versionadded:: 1.12.1 - #: cache not to recompute the `is_ambiguous` for the same action + #: + #: cache not to recompute the :attr:`BaseAction.is_ambiguous` for the same action self._cached_is_not_ambiguous = True # init the private argument when needed @@ -1618,10 +1620,15 @@ def _aux_eq_shunts(self, other: "BaseAction") -> bool: def _aux_vect_different(self, other, modif_flag_nm, vect_nm): """Implement something similar to : - ((self._modif_set_status != other._modif_set_status) or - not np.all(self._set_line_status == other._set_line_status) - ) + .. code-block:: python + + ((self._modif_set_status != other._modif_set_status) or + not np.all(self._set_line_status == other._set_line_status) + ) + But for different flag (*eg* `_modif_set_status`) and vector (*eg* `_private_set_line_status`) + to avoid duplicating the code. + """ if getattr(self, modif_flag_nm) != getattr(other, modif_flag_nm): # they are different @@ -1689,18 +1696,18 @@ def __eq__(self, other: "BaseAction") -> bool: Test the equality of two actions. 2 actions are said to be identical if they have the same impact on the powergrid. This is unrelated to their - respective class. For example, if an Action is of class :class:`Action` and doesn't act on the injection, it + respective class. For example, if an Action is of class :class:`BaseAction` and doesn't act on the injection, it can be equal to an Action of the derived class :class:`TopologyAction` (if the topological modifications are the same of course). - This implies that the attributes :attr:`Action.authorized_keys` is not checked in this method. + This implies that the attributes :attr:`BaseAction.authorized_keys` is not checked in this method. Note that if 2 actions don't act on the same powergrid, or on the same backend (eg number of loads, or generators are not the same in *self* and *other*, or they are not in the same order) then action will be declared as different. **Known issue** if two backends are different, but the description of the _grid are identical (ie all - n_gen, n_load, n_line, sub_info, dim_topo, all vectors \*_to_subid, and \*_pos_topo_vect are + n_gen, n_load, n_line, sub_info, dim_topo, all vectors \\*_to_subid, and \\*_pos_topo_vect are identical) then this method will not detect the backend are different, and the action could be declared as identical. For now, this is only a theoretical behavior: if everything is the same, then probably, up to the naming convention, then the power grids are identical too. @@ -1908,7 +1915,7 @@ def get_topological_impact(self, then the argument `powerline_status` might be ignored in future calls where `_read_from_cache` is ``True`` - .. newinversion:: 1.11.0 + .. versionadded:: 1.11.0 .. warning:: Use with extra care, it's private API. @@ -1925,7 +1932,7 @@ def get_topological_impact(self, By default it's ``True``, but by default no cache is not set up. This means that by default the argument `powerline_status` is in fact used. - .. newinversion:: 1.11.0 + .. versionadded:: 1.11.0 Returns ------- @@ -5587,9 +5594,9 @@ def set_bus(self) -> np.ndarray: Will: - * set to bus 1 the (unique) element for which \*_pos_topo_vect is 1 - * disconnect the (unique) element for which \*_pos_topo_vect is 2 - * set to bus 2 the (unique) element for which \*_pos_topo_vect is 3 + * set to bus 1 the (unique) element for which \\*_pos_topo_vect is 1 + * disconnect the (unique) element for which \\*_pos_topo_vect is 2 + * set to bus 2 the (unique) element for which \\*_pos_topo_vect is 3 You can use the documentation page :ref:`modeled-elements-module` for more information about which element correspond to what component of this vector. @@ -5909,9 +5916,9 @@ def change_bus(self) -> np.ndarray: Will: - * change the bus of the (unique) element for which \*_pos_topo_vect is 1 - * change the bus of (unique) element for which \*_pos_topo_vect is 2 - * change the bus of (unique) element for which \*_pos_topo_vect is 3 + * change the bus of the (unique) element for which \\*_pos_topo_vect is 1 + * change the bus of (unique) element for which \\*_pos_topo_vect is 2 + * change the bus of (unique) element for which \\*_pos_topo_vect is 3 You can use the documentation page :ref:`modeled-elements-module` for more information about which element correspond to what component of this "vector". @@ -7419,7 +7426,7 @@ def limit_curtail_storage(self, margin: float=10., do_copy: bool=False, _tol_equal : float=0.01) -> Tuple["BaseAction", np.ndarray, np.ndarray]: - """ + r""" This function tries to limit the possibility to end up with a "game over" because actions on curtailment or storage units (see the "Notes" section for more information). @@ -7442,25 +7449,26 @@ def limit_curtail_storage(self, At each time, the environment ensures that the following equations are met: - 1) for each controlable generators $p^{(c)}_{min} <= p^{(c)}_t <= p^{(c)}_{max}$ - 2) for each controlable generators $-ramp_{min}^{(c)} <= p^{(c)}_t - p^{(c)}_{t-1} <= ramp_{max}^{(c)}$ + 1) for each controlable generators :math:`p^{(c)}_{min} <= p^{(c)}_t <= p^{(c)}_{max}` + 2) for each controlable generators :math:`-ramp_{min}^{(c)} <= p^{(c)}_t - p^{(c)}_{t-1} <= ramp_{max}^{(c)}` 3) at each step the sum of MW curtailed and the total contribution of storage units is absorbed by the controlable generators so that the total amount of power injected at this step does not change: - $\sum_{\text{all generators } g} p^{(g, scenario)}_t = \sum_{\text{controlable generators } c} p^{(c)}_t + \sum_{\text{storage unit } s} p^{s}_t + \sum_{\text{renewable generator} r} p^{(r)}_t$ - where $p^{(g)}_t$ denotes the productions of generator $g$ in the input data "scenario" + :math:`\sum_{\text{all generators } g} p^{(g, scenario)}_t = \sum_{\text{controlable generators } c} p^{(c)}_t + \sum_{\text{storage unit } s} p^{s}_t + \sum_{\text{renewable generator} r} p^{(r)}_t` + where :math:`p^{(g)}_t` denotes the productions of generator $g$ in the input data "scenario" (*ie* "in the current episode", "before any modification", "decided by the market / central authority"). - In the above equations, `\sum_{\text{storage unit } s} p^{s}_t` are controled by the action (thanks to the storage units) - and `\sum_{\text{renewable generator} r} p^{(r)}_t` are controlled by the curtailment. + In the above equations: + ..:math:`\sum_{\text{storage unit } s} p^{s}_t` are controled by the action (thanks to the storage units) + and :math:`\sum_{\text{renewable generator} r} p^{(r)}_t` are controlled by the curtailment. - `\sum_{\text{all generators } g} p^{(g, scenario)}_t` are input data from the environment (that cannot be modify). + :math:`\sum_{\text{all generators } g} p^{(g, scenario)}_t` are input data from the environment (that cannot be modify). - The exact value of each `p^{(c)}_t` (for each controlable generator) is computed by an internal routine of the + The exact value of each :math:`p^{(c)}_t` (for each controlable generator) is computed by an internal routine of the environment. - The constraint comes from the fact that `\sum_{\text{controlable generators } c} p^{(c)}_t` is determined by the last equation - above but at the same time the values of each `p^{(c)}_t` (for each controllable generator) is heavily constrained + The constraint comes from the fact that :math:`\sum_{\text{controlable generators } c} p^{(c)}_t` is determined by the last equation + above but at the same time the values of each :math:`p^{(c)}_t` (for each controllable generator) is heavily constrained by equations 1) and 2). .. note:: @@ -7946,3 +7954,46 @@ def has_element_detached(self): `detach_load`, `detach_gen` or `detach_storage` """ return self._modif_detach_gen or self._modif_detach_load or self._modif_detach_storage + + def check_reconnection_valid(self, current_line_status, last_valid_topo_vect): + # check lines can be reconnected safely if no bus is provided + if not (self._modif_set_status or self._modif_change_status): + # action does not modifies line status, no problem + return None + + if (last_valid_topo_vect >= 1).all(): + # all previous buses known, + # no need to check + # TODO speed optimization: if i end up here for one step, then I end up here for all the following + return None + + cls = type(self) + + # line reconnected + reco = ((self._set_line_status == 1) | + (self._switch_line_status & (~current_line_status))) + + # check that the "previous bus" is known for these lines + vect_or = cls.line_or_pos_topo_vect[reco] + vect_ex = cls.line_ex_pos_topo_vect[reco] + if not self._modif_set_bus: + # reconnection without proper bus specified in the action + # previous bus should be registered at both ends + issue_or = last_valid_topo_vect[vect_or] < 1 + issue_ex = last_valid_topo_vect[vect_ex] < 1 + else: + # check that the user specified the bus on each side + issue_or = (last_valid_topo_vect[vect_or] < 1) & (self._set_topo_vect[vect_or] < 1) + issue_ex = (last_valid_topo_vect[vect_ex] < 1) & (self._set_topo_vect[vect_ex] < 1) + if issue_or.any(): + return IllegalAction(f"Attempt to reconnect line " + f"{cls.name_line[issue_or.nonzero()[0]]} " + f"with id(s) {issue_or.nonzero()[0]} " + f"(origin side) with no known previous nodes. In this case, you need to specify " + f"explicitly the node / bus to which you want to reconnect it.") + if issue_ex.any(): + return IllegalAction(f"Attempt to reconnect line " + f"{cls.name_line[issue_ex.nonzero()[0]]} " + f"with id(s) {issue_ex.nonzero()[0]} " + f"(extremity side) with no known previous nodes. In this case, you need to specify " + f"explicitly the node / bus to which you want to reconnect it.") diff --git a/grid2op/Backend/backend.py b/grid2op/Backend/backend.py index 6bb872cb..2badbeef 100644 --- a/grid2op/Backend/backend.py +++ b/grid2op/Backend/backend.py @@ -155,9 +155,10 @@ def __init__(self, # thermal limit setting, in ampere, at the same "side" of the powerline than self.get_line_overflow self.thermal_limit_a : Optional[np.ndarray] = None - # for the shunt (only if supported) - self._sh_vnkv : Optional[np.ndarray]= None # for each shunt gives the nominal value at the bus at which it is connected - # if this information is not present, then "get_action_to_set" might not behave correctly + #: for the shunt (only if supported) + #: for each shunt gives the nominal voltage value at the substation at which it is connected + #: if this information is not present, then "get_action_to_set" might not behave correctly + self._sh_vnkv : Optional[np.ndarray] = None self.comp_time : float = 0.0 self.can_output_theta : bool = False @@ -192,7 +193,7 @@ def __init__(self, self.detachment_is_allowed : bool = DEFAULT_ALLOW_DETACHMENT #: .. versionadded: 1.11.0 - self._load_bus_target : Optional[np.ndarray]= None + self._load_bus_target : Optional[np.ndarray] = None self._gen_bus_target : Optional[np.ndarray] = None self._storage_bus_target : Optional[np.ndarray] = None self._shunt_bus_target : Optional[np.ndarray] = None @@ -491,7 +492,6 @@ def apply_action_public(self, backend_action: Union["_BackendAction", None]) -> self._shunt_bus_target.flags.writeable = True self._shunt_bus_target[shunts_bus.changed] = shunts_bus.values[shunts_bus.changed] self._shunt_bus_target.flags.writeable = False - return self.apply_action(backend_action) def update_bus_target_after_pf(self, loads_bus, gens_bus, stos_bus, shunt_bus=None): @@ -2112,7 +2112,7 @@ def load_storage_data(self, f' for {sto_nm} and column "discharging_efficiency"', ) - def _aux_check_finite_float(self, nb_ : float, str_ : Optional[str]="") -> None: + def _aux_check_finite_float(self, nb_ : float, str_ : Optional[str]="") -> dt_float: """ INTERNAL @@ -2208,24 +2208,19 @@ def get_action_to_set(self) -> "CompleteAction": set_me = self._complete_action_class() # pylint: disable=not-callable dict_ = { "set_line_status": line_status, - "set_bus": 1 * topo_vect, + "set_bus": topo_vect.copy(), "injection": { - "prod_p": prod_p, - "prod_v": prod_v, - "load_p": load_p, - "load_q": load_q, + "prod_p": prod_p.copy(), + "prod_v": prod_v.copy(), + "load_p": load_p.copy(), + "load_q": load_q.copy(), }, } if type(self).shunts_data_available: - p_s, q_s, sh_v, bus_s = self.shunt_info() + p_s, q_s, bus_s = self.get_shunt_setpoint() dict_["shunt"] = {"shunt_bus": bus_s} if (bus_s >= 1).sum(): - sh_conn = bus_s > 0 - p_s[sh_conn] *= (self._sh_vnkv[sh_conn] / sh_v[sh_conn]) ** 2 - q_s[sh_conn] *= (self._sh_vnkv[sh_conn] / sh_v[sh_conn]) ** 2 - p_s[bus_s == -1] = np.nan - q_s[bus_s == -1] = np.nan dict_["shunt"]["shunt_p"] = p_s dict_["shunt"]["shunt_q"] = q_s @@ -2236,6 +2231,23 @@ def get_action_to_set(self) -> "CompleteAction": set_me.update(dict_) return set_me + def get_shunt_setpoint(self): + """INTERNAL + + Is called in "get_action_to_set" but also in "EnvPrevState.update_from_backend" + + This gives the proper input to provide to the shunt (in an action or a backend action) to have + the right outcome. + """ + p_s, q_s, sh_v, bus_s = self.shunt_info() + if (bus_s >= 1).any(): + sh_conn = bus_s > 0 + p_s[sh_conn] *= (self._sh_vnkv[sh_conn] / sh_v[sh_conn]) ** 2 + q_s[sh_conn] *= (self._sh_vnkv[sh_conn] / sh_v[sh_conn]) ** 2 + p_s[bus_s == -1] = np.nan + q_s[bus_s == -1] = np.nan + return p_s, q_s, bus_s + def update_from_obs(self, obs: "grid2op.Observation.CompleteObservation", force_update: Optional[bool]=False) -> "_BackendAction": diff --git a/grid2op/Backend/educPandaPowerBackend.py b/grid2op/Backend/educPandaPowerBackend.py index b8820272..1b370c17 100644 --- a/grid2op/Backend/educPandaPowerBackend.py +++ b/grid2op/Backend/educPandaPowerBackend.py @@ -40,7 +40,7 @@ class EducPandaPowerBackend(Backend): resulting backend harder to read. This module presents an example of an implementation of a `grid2op.Backend` when using the powerflow - implementation "pandapower" available at `PandaPower `_ for more details about + implementation "pandapower" available at `PandaPower `__ for more details about this backend. This file is provided as an example of a proper :class:`grid2op.Backend.Backend` implementation. This backend currently does not work with 3 winding transformers and other exotic object. diff --git a/grid2op/Backend/pandaPowerBackend.py b/grid2op/Backend/pandaPowerBackend.py index 9c956ea5..7ab795ec 100644 --- a/grid2op/Backend/pandaPowerBackend.py +++ b/grid2op/Backend/pandaPowerBackend.py @@ -52,7 +52,7 @@ class PandaPowerBackend(Backend): of PandaPower. This module presents an example of an implementation of a `grid2op.Backend` when using the powerflow - implementation "pandapower" available at `PandaPower `_ for more details about + implementation "pandapower" available at `PandaPower `__ for more details about this backend. This file is provided as an example of a proper :class:`grid2op.Backend.Backend` implementation. This backend currently does not work with 3 winding transformers and other exotic object. @@ -345,6 +345,7 @@ def reset(self, self._reset_all_nan() self._get_line_status() self._get_topo_vect() + self._fetch_data_pf_converged(is_dc=False) self.comp_time = 0.0 def load_grid(self, @@ -370,7 +371,7 @@ def load_grid(self, warnings.filterwarnings("ignore", category=FutureWarning) self._grid = pp.from_json(full_path) self._check_for_non_modeled_elements() - + # add the slack bus that is often not modeled as a generator, but i need it for this backend to work bus_gen_added = None i_ref = None @@ -452,13 +453,17 @@ def load_grid(self, self.__nb_powerline = self._grid.line.shape[0] self._init_bus_load = self.cst_1 * self._grid.load["bus"].values self._init_bus_gen = self.cst_1 * self._grid.gen["bus"].values - self._init_bus_lor = self.cst_1 * self._grid.line["from_bus"].values - self._init_bus_lex = self.cst_1 * self._grid.line["to_bus"].values - + + bus_lor = self.cst_1 * self._grid.line["from_bus"].values + # bus_lor[~self._grid.line["in_service"].values] = -1 + bus_lex = self.cst_1 * self._grid.line["to_bus"].values + # bus_lex[~self._grid.line["in_service"].values] = -1 t_for = self.cst_1 * self._grid.trafo["hv_bus"].values + # t_for[~self._grid.trafo["in_service"].values] = -1 t_fex = self.cst_1 * self._grid.trafo["lv_bus"].values - self._init_bus_lor = np.concatenate((self._init_bus_lor, t_for)).astype(dt_int) - self._init_bus_lex = np.concatenate((self._init_bus_lex, t_fex)).astype(dt_int) + # t_fex[~self._grid.trafo["in_service"].values] = -1 + self._init_bus_lor = np.concatenate((bus_lor, t_for)).astype(dt_int) + self._init_bus_lex = np.concatenate((bus_lex, t_fex)).astype(dt_int) self._grid["ext_grid"]["va_degree"] = 0.0 @@ -565,8 +570,8 @@ def load_grid(self, # bug in pandapower 3.0.0 in this case del tmp["geo"] pp.create_bus(self._grid, index=ind, **tmp) - self._init_private_attrs() self._aux_run_pf_init() # run yet another powerflow with the added buses + self._init_private_attrs() # do this at the end self._in_service_line_col_id = int((self._grid.line.columns == "in_service").nonzero()[0][0]) @@ -844,6 +849,7 @@ def _init_private_attrs(self) -> None: self.gen_theta = np.full(self.n_gen, fill_value=np.nan, dtype=dt_float) self.storage_theta = np.full(self.n_storage, fill_value=np.nan, dtype=dt_float) + self._get_line_status() self._get_topo_vect() self.tol = 1e-5 # this is NOT the pandapower tolerance !!!! this is used to check if a storage unit # produce / absorbs anything @@ -866,6 +872,7 @@ def storage_deact_for_backward_comaptibility(self) -> None: self._topo_vect.flags.writeable = True self._topo_vect.resize(cls.dim_topo, refcheck=False) self._topo_vect.flags.writeable = False + self._get_line_status() self._get_topo_vect() def _convert_id_topo(self, id_big_topo): @@ -962,16 +969,15 @@ def apply_action(self, backend_action: "grid2op.Action._backendAction._BackendAc chg_and_in_service = sh_service & shunt_bus.changed self._grid.shunt.loc[chg_and_in_service, "bus"] = cls.local_bus_to_global(shunt_bus.values[chg_and_in_service], cls.shunt_to_subid[chg_and_in_service]) - # i made at least a real change, so i implement it in the backend for id_el, new_bus in topo__: id_el_backend, id_topo, type_obj = self._big_topo_to_backend[id_el] - if type_obj is not None: # storage unit are handled elsewhere self._type_to_bus_set[type_obj](new_bus, id_el_backend, id_topo) - - self._topo_vect.flags.writeable = False + # self._topo_vect.flags.writeable = True + # self._topo_vect[topo__.changed] = topo__.values[topo__.changed] + # self._topo_vect.flags.writeable = False def _apply_load_bus(self, new_bus, id_el_backend, id_topo): new_bus_backend = type(self).local_bus_to_global_int( @@ -1117,7 +1123,105 @@ def _aux_runpf_pp(self, is_dc: bool): # sometimes pandapower does not detect divergence and put Nan. raise pp.powerflow.LoadflowNotConverged("Divergence due to Nan values in res_gen table (most likely due to " "a non connected grid).") - + + def _fetch_data_pf_converged(self, is_dc): + cls = type(self) + ( + self.prod_p[:], + self.prod_q[:], + self.prod_v[:], + self.gen_theta[:], + ) = self._gens_info() + ( + self.load_p[:], + self.load_q[:], + self.load_v[:], + self.load_theta[:], + ) = self._loads_info() + + if is_dc: + # fix voltages magnitude that are always "nan" for dc case + # self._grid.res_bus["vm_pu"] is always nan when computed in DC + self.load_v[:] = self.load_pu_to_kv # TODO + # need to assign the correct value when a generator is present at the same bus + # TODO optimize this ugly loop + # see https://github.com/e2nIEE/pandapower/issues/1996 for a fix + for l_id in range(cls.n_load): + if cls.load_to_subid[l_id] in cls.gen_to_subid: + ind_gens = ( + cls.gen_to_subid == cls.load_to_subid[l_id] + ).nonzero()[0] + for g_id in ind_gens: + if ( + self._topo_vect[cls.load_pos_topo_vect[l_id]] + == self._topo_vect[cls.gen_pos_topo_vect[g_id]] + ): + self.load_v[l_id] = self.prod_v[g_id] + break + self.load_v[~self._grid.load["in_service"]] = 0. + + # I retrieve the data once for the flows, so has to not re read multiple dataFrame + self.p_or[:] = self._aux_get_line_info("p_from_mw", "p_hv_mw") + self.q_or[:] = self._aux_get_line_info("q_from_mvar", "q_hv_mvar") + self.v_or[:] = self._aux_get_line_info("vm_from_pu", "vm_hv_pu") + self.a_or[:] = self._aux_get_line_info("i_from_ka", "i_hv_ka") * 1000. + self.theta_or[:] = self._aux_get_line_info( + "va_from_degree", "va_hv_degree" + ) + self.a_or[~np.isfinite(self.a_or)] = 0.0 + self.v_or[~np.isfinite(self.v_or)] = 0.0 + + self.p_ex[:] = self._aux_get_line_info("p_to_mw", "p_lv_mw") + self.q_ex[:] = self._aux_get_line_info("q_to_mvar", "q_lv_mvar") + self.v_ex[:] = self._aux_get_line_info("vm_to_pu", "vm_lv_pu") + self.a_ex[:] = self._aux_get_line_info("i_to_ka", "i_lv_ka") * 1000. + self.theta_ex[:] = self._aux_get_line_info( + "va_to_degree", "va_lv_degree" + ) + self.a_ex[~np.isfinite(self.a_ex)] = 0.0 + self.v_ex[~np.isfinite(self.v_ex)] = 0.0 + + # it seems that pandapower does not take into account disconencted powerline for their voltage + self.v_or[~self.line_status] = 0.0 + self.v_ex[~self.line_status] = 0.0 + self.v_or[:] *= self.lines_or_pu_to_kv + self.v_ex[:] *= self.lines_ex_pu_to_kv + + # see issue https://github.com/Grid2Op/grid2op/issues/389 + self.theta_or[~np.isfinite(self.theta_or)] = 0.0 + self.theta_ex[~np.isfinite(self.theta_ex)] = 0.0 + + self._nb_bus_before = None + if self._iref_slack is not None: + # a gen has been added to represent the slack, modeled as an "ext_grid" + self._grid._ppc["gen"][self._iref_slack, 1] = 0.0 + + # handle storage units + # note that we have to look ourselves for disconnected storage + ( + self.storage_p[:], + self.storage_q[:], + self.storage_v[:], + self.storage_theta[:], + ) = self._storages_info() + + deact_storage = ~np.isfinite(self.storage_v) + self.storage_p[deact_storage] = 0.0 + self.storage_q[deact_storage] = 0.0 + self.storage_v[deact_storage] = 0.0 + self._grid.storage["in_service"].values[deact_storage] = False + if not self._grid.converged: + raise pp.powerflow.LoadflowNotConverged("Divergence without specific reason (self._grid.converged is False)") + self.div_exception = None + + if is_dc: + # pandapower apparently does not set 0 for q in DC... + self.prod_q[:] = 0. + self.load_q[:] = 0. + self.storage_q[:] = 0. + self.q_or[:] = 0. + self.q_ex[:] = 0. + def runpf(self, is_dc : bool=False) -> Tuple[bool, Union[Exception, None]]: """ INTERNAL @@ -1137,109 +1241,15 @@ def runpf(self, is_dc : bool=False) -> Tuple[bool, Union[Exception, None]]: self._get_line_status() self._get_topo_vect() self._aux_runpf_pp(is_dc) - - cls = type(self) + # if a connected bus has a no voltage, it's a divergence (grid was not connected) if self._grid.res_bus.loc[self._grid.bus["in_service"]]["va_degree"].isnull().any(): buses_ko = self._grid.res_bus.loc[self._grid.bus["in_service"]]["va_degree"].isnull() buses_ko = buses_ko.values.nonzero()[0] raise pp.powerflow.LoadflowNotConverged(f"Isolated bus, check buses {buses_ko} with `env.backend._grid.res_bus.iloc[{buses_ko}, :]`") - - ( - self.prod_p[:], - self.prod_q[:], - self.prod_v[:], - self.gen_theta[:], - ) = self._gens_info() - ( - self.load_p[:], - self.load_q[:], - self.load_v[:], - self.load_theta[:], - ) = self._loads_info() - - if is_dc: - # fix voltages magnitude that are always "nan" for dc case - # self._grid.res_bus["vm_pu"] is always nan when computed in DC - self.load_v[:] = self.load_pu_to_kv # TODO - # need to assign the correct value when a generator is present at the same bus - # TODO optimize this ugly loop - # see https://github.com/e2nIEE/pandapower/issues/1996 for a fix - for l_id in range(cls.n_load): - if cls.load_to_subid[l_id] in cls.gen_to_subid: - ind_gens = ( - cls.gen_to_subid == cls.load_to_subid[l_id] - ).nonzero()[0] - for g_id in ind_gens: - if ( - self._topo_vect[cls.load_pos_topo_vect[l_id]] - == self._topo_vect[cls.gen_pos_topo_vect[g_id]] - ): - self.load_v[l_id] = self.prod_v[g_id] - break - self.load_v[~self._grid.load["in_service"]] = 0. - - # I retrieve the data once for the flows, so has to not re read multiple dataFrame - self.p_or[:] = self._aux_get_line_info("p_from_mw", "p_hv_mw") - self.q_or[:] = self._aux_get_line_info("q_from_mvar", "q_hv_mvar") - self.v_or[:] = self._aux_get_line_info("vm_from_pu", "vm_hv_pu") - self.a_or[:] = self._aux_get_line_info("i_from_ka", "i_hv_ka") * 1000. - self.theta_or[:] = self._aux_get_line_info( - "va_from_degree", "va_hv_degree" - ) - self.a_or[~np.isfinite(self.a_or)] = 0.0 - self.v_or[~np.isfinite(self.v_or)] = 0.0 - - self.p_ex[:] = self._aux_get_line_info("p_to_mw", "p_lv_mw") - self.q_ex[:] = self._aux_get_line_info("q_to_mvar", "q_lv_mvar") - self.v_ex[:] = self._aux_get_line_info("vm_to_pu", "vm_lv_pu") - self.a_ex[:] = self._aux_get_line_info("i_to_ka", "i_lv_ka") * 1000. - self.theta_ex[:] = self._aux_get_line_info( - "va_to_degree", "va_lv_degree" - ) - self.a_ex[~np.isfinite(self.a_ex)] = 0.0 - self.v_ex[~np.isfinite(self.v_ex)] = 0.0 - - # it seems that pandapower does not take into account disconencted powerline for their voltage - self.v_or[~self.line_status] = 0.0 - self.v_ex[~self.line_status] = 0.0 - self.v_or[:] *= self.lines_or_pu_to_kv - self.v_ex[:] *= self.lines_ex_pu_to_kv - - # see issue https://github.com/Grid2Op/grid2op/issues/389 - self.theta_or[~np.isfinite(self.theta_or)] = 0.0 - self.theta_ex[~np.isfinite(self.theta_ex)] = 0.0 - - self._nb_bus_before = None - if self._iref_slack is not None: - # a gen has been added to represent the slack, modeled as an "ext_grid" - self._grid._ppc["gen"][self._iref_slack, 1] = 0.0 - - # handle storage units - # note that we have to look ourselves for disconnected storage - ( - self.storage_p[:], - self.storage_q[:], - self.storage_v[:], - self.storage_theta[:], - ) = self._storages_info() - deact_storage = ~np.isfinite(self.storage_v) - self.storage_p[deact_storage] = 0.0 - self.storage_q[deact_storage] = 0.0 - self.storage_v[deact_storage] = 0.0 - self._grid.storage["in_service"].values[deact_storage] = False - if not self._grid.converged: - raise pp.powerflow.LoadflowNotConverged("Divergence without specific reason (self._grid.converged is False)") - self.div_exception = None + self._fetch_data_pf_converged(is_dc) - if is_dc: - # pandapower apparently does not set 0 for q in DC... - self.prod_q[:] = 0. - self.load_q[:] = 0. - self.storage_q[:] = 0. - self.q_or[:] = 0. - self.q_ex[:] = 0. return True, None except pp.powerflow.LoadflowNotConverged as exc_: diff --git a/grid2op/Converter/BackendConverter.py b/grid2op/Converter/BackendConverter.py index cb0ee891..bf6c968c 100644 --- a/grid2op/Converter/BackendConverter.py +++ b/grid2op/Converter/BackendConverter.py @@ -211,7 +211,7 @@ def load_grid(self, path=None, filename=None): ] if type(self.source_backend).shunts_data_available: - li_attrs += ["n_shunt", "name_shunt", "shunts_data_available"] + li_attrs += ["n_shunt", "name_shunt", "shunts_data_available", "_sh_vnkv"] for attr_nm in li_attrs: setattr(self, attr_nm, getattr(self.source_backend, attr_nm)) @@ -354,9 +354,12 @@ def _init_myself(self): sr2tg=self._shunt_sr2tg, nm="shunt", ) + self._sh_vnkv = self.source_backend._sh_vnkv[self._shunt_sr2tg] else: self.n_shunt = 0 self.name_shunt = np.empty(0, dtype=str) + self._sh_vnkv = None + self._thermal_limit_a = 1.0 * self.target_backend.thermal_limit_a self.set_thermal_limit(self.target_backend.thermal_limit_a[self._line_tg2sr]) diff --git a/grid2op/Environment/_env_prev_state.py b/grid2op/Environment/_env_prev_state.py index 34a5a521..820626cd 100644 --- a/grid2op/Environment/_env_prev_state.py +++ b/grid2op/Environment/_env_prev_state.py @@ -7,7 +7,8 @@ # This file is part of Grid2Op, Grid2Op a testbed platform to model sequential decision making in power systems. import copy -from typing import Optional, Type, Union +from typing import Dict, Literal, Optional, Tuple, Type, Union + import numpy as np from grid2op.Space import GridObjects import grid2op.Backend @@ -37,20 +38,61 @@ def __init__(self, self._grid_obj_cls : CLS_AS_DICT_TYPING = grid_obj_cls self._n_storage = len(self._grid_obj_cls["name_storage"]) # to avoid typing that over and over again - self._load_p : np.ndarray = 1. * init_load_p - self._load_q : np.ndarray = 1. * init_load_q - self._gen_p : np.ndarray = 1. * init_gen_p - self._gen_v : np.ndarray = 1. * init_gen_v - self._storage_p : np.ndarray = 1. * init_storage_p - self._topo_vect : np.ndarray = 1 * init_topo_vect - self._shunt_p : np.ndarray = 1. * init_shunt_p - self._shunt_q : np.ndarray = 1. * init_shunt_q - self._shunt_bus : np.ndarray = 1. * init_shunt_bus + self._load_p : np.ndarray = init_load_p.copy() + self._load_q : np.ndarray = init_load_q.copy() + self._gen_p : np.ndarray = init_gen_p.copy() + self._gen_v : np.ndarray = init_gen_v.copy() + self._storage_p : np.ndarray = init_storage_p.copy() + self._topo_vect : np.ndarray = init_topo_vect.copy() + self._shunt_p : np.ndarray = init_shunt_p.copy() + self._shunt_q : np.ndarray = init_shunt_q.copy() + self._shunt_bus : np.ndarray = init_shunt_bus.copy() if "detailed_topo_desc" in self._grid_obj_cls and self._grid_obj_cls["detailed_topo_desc"] is not None: - self._switch_state = 1 * init_switch_state + self._switch_state = init_switch_state.copy() else: self._switch_state = None - + + def __eq__(self, value: "_EnvPreviousState"): + return len(self.where_different(value)) == 0 + + def where_different(self, oth: "_EnvPreviousState") -> Dict[ + Literal["_load_p", "_load_q", "_gen_p", "_gen_v", "_storage_p", "_topo_vect", "_shunt_p", "_shunt_q", "_shunt_bus", "_switch_state"], + Tuple[Literal["size", "values", "missing_in_me", "missing_in_other", "me_none", "other_none"], + Optional[np.ndarray], Optional[np.ndarray]] + ]: + """Where this object is different from another one""" + + res = {} + for attr_nm in ["_load_p", "_load_q", "_gen_p", "_gen_v", "_storage_p", "_topo_vect", "_shunt_p", "_shunt_q", "_shunt_bus", "_switch_state"]: + if not hasattr(self, attr_nm) and not hasattr(oth, attr_nm): + # attribute is not present (eg _switch_state when no switch are present) + continue + if not hasattr(self, attr_nm) and hasattr(oth, attr_nm): + res[attr_nm] = ("missing_in_me", None, getattr(oth, attr_nm)) + continue + if hasattr(self, attr_nm) and not hasattr(oth, attr_nm): + res[attr_nm] = ("missing_in_other", getattr(self, attr_nm), None) + continue + arr_me : Optional[np.ndarray] = getattr(self, attr_nm) + arr_oth : Optional[np.ndarray] = getattr(oth, attr_nm) + if arr_me is None and arr_oth is None: + # eg _shunt_p when no shunts + continue + if arr_me is None and arr_oth is not None: + res[attr_nm] = ("me_none", None, arr_oth) + continue + if arr_me is not None and arr_oth is None: + res[attr_nm] = ("other_none", arr_me, None) + continue + if arr_me.shape != arr_oth.shape: + res[attr_nm] = ("size", arr_me.shape, arr_oth.shape) + continue + if np.allclose(arr_me, arr_oth): + # they match + continue + res[attr_nm] = ("values", arr_me.copy(), arr_oth.copy()) + return res + def copy(self): return _EnvPreviousState(grid_obj_cls=self._grid_obj_cls, init_load_p=self._load_p, @@ -127,9 +169,9 @@ def update_from_backend(self, else: storage_p = None if type(backend).shunts_data_available: - shunt_p, shunt_q, _, shunt_bus = backend.shunt_info() + shunt_p, shunt_q, shunt_bus = backend.get_shunt_setpoint() else: - shunt_p, shunt_q, _, shunt_bus = None, None, None, None + shunt_p, shunt_q, shunt_bus = None, None, None switches = None # if type(backend).detailed_topo_desc is not None: @@ -211,3 +253,35 @@ def _aux_update(self, arr1[el_co] = 1. * arr1_new[el_co] if arr2 is not None: arr2[el_co] = 1. * arr2_new[el_co] + + + def fix_topo_bus(self): + """ + INTERNAL + + .. warning:: /!\\\\ Internal, do not use unless you know what you are doing /!\\\\ + + + This function fixes the "previous connection sate" to make sure they are all valid buses for set_bus. + + It is called by "env.reset" + + There might be issues for example if the original grid contained disconnected elements, in that case they would + be assigned to 0 which is not possible. + + """ + if not ((self._topo_vect <= -2) | + (self._topo_vect == 0) | + (self._topo_vect > int(self._grid_obj_cls["n_busbar_per_sub"])) + ).any(): + # all bus are ok + # nothing to do + return + + # if detailed topo, not done ATM # TODO + if hasattr(self, "_switch_state") and self._switch_state is not None: + raise RuntimeError("Disconnected element in the grid in the presence of switches. This is not handled at the moment.") + + self._topo_vect[self._topo_vect <= -2] = -1 + self._topo_vect[self._topo_vect == 0] = -1 + self._topo_vect[self._topo_vect > int(self._grid_obj_cls["n_busbar_per_sub"])] = 1 diff --git a/grid2op/Environment/_obsEnv.py b/grid2op/Environment/_obsEnv.py index 618580d3..2e9cce54 100644 --- a/grid2op/Environment/_obsEnv.py +++ b/grid2op/Environment/_obsEnv.py @@ -569,3 +569,13 @@ def close(self): if hasattr(self, attr_nm): delattr(self, attr_nm) setattr(self, attr_nm, None) + + def synch_backend_action(self, real_env_backend_action: grid2op.Action._BackendAction) -> None: + """Synchronize the backend action of the (simulated) environment with the backend action of the real environment. + + This is called by the "simulated environment" (forecast env) and allow to remember "past state" of the grid + """ + self._backend_action.last_topo_registered.values[:] = real_env_backend_action.last_topo_registered.values + self._backend_action.current_topo.values[:] = real_env_backend_action.current_topo.values + self._backend_action.invalidate_cache() + self._backend_action.all_changed() diff --git a/grid2op/Environment/baseEnv.py b/grid2op/Environment/baseEnv.py index 23dba6e5..825959ce 100644 --- a/grid2op/Environment/baseEnv.py +++ b/grid2op/Environment/baseEnv.py @@ -171,10 +171,6 @@ def foo(manager): Attributes ---------- - - parameters: :class:`grid2op.Parameters.Parameters` - The parameters of the game (to expose more control on what is being simulated) - with_forecast: ``bool`` Whether the chronics allow to have some kind of "forecast". See :func:`BaseEnv.activate_forceast` for more information @@ -318,7 +314,9 @@ def foo(manager): kwargs_observation: ``dict`` TODO - # TODO add the units (eg MW, MWh, MW/time step,etc.) in the redispatching related attributes + warnings + -------- + TODO add the units (eg MW, MWh, MW/time step,etc.) in the redispatching related attributes """ ALARM_FILE_NAME = "alerts_info.json" @@ -1515,30 +1513,60 @@ def _has_been_initialized(self): np.zeros(n_shunt, dtype=dt_int), ) + self._compute_init_state() + + def _compute_init_state(self, do_powerflow=True): + """ + INTERNAL + + Usefull to initialize the grid representatino of the env (_backend_action and _previous_conn_state) + to the correct value in the grid. + + It is called when the environment is initialized (first time) but also when the env is reset. + """ if self._init_obs is None: # regular environment, initialized from scratch try: - self.backend.runpf(is_dc=self._parameters.ENV_DC) + if do_powerflow: + conv, exc = self.backend.runpf(is_dc=self._parameters.ENV_DC) + if not conv: + raise exc self._previous_conn_state.update_from_backend(self.backend) except Exception as exc_: # nothing to do in this case self.logger.warning(f"Impossible to retrieve the initial state of the grid before running the initial powerflow: {exc_}") self._previous_conn_state._topo_vect[:] = 1 # I force assign everything to busbar 1 by default... - self._cst_prev_state_at_init = copy.deepcopy(self._previous_conn_state) self._backend_action = self._backend_action_class() else: # environment initialized from an observation, eg forecast_env # update the backend self._backend_action = self.backend.update_from_obs(self._init_obs) - self._backend_action.last_topo_registered.values[:] = self._init_obs._prev_conn._topo_vect - self._cst_prev_state_at_init = copy.deepcopy(self._init_obs._prev_conn) self._previous_conn_state.update_from_other(self._init_obs._prev_conn) - + self._backend_action.current_topo.values[:] = self._init_obs.topo_vect + + # "fix" topology in case of disconnected element in grid file + self._previous_conn_state.fix_topo_bus() + self._cst_prev_state_at_init = self._previous_conn_state.copy() self._cst_prev_state_at_init.prevent_modification() + # update backend_action with the "last known" state self._backend_action.last_topo_registered.values[:] = self._previous_conn_state._topo_vect self._backend_action._needs_active_bus = self.backend._needs_active_bus + # assign correct topo in case of "no init obs" (not done in the first if self._init_obs is None) + # because I need the fix_topo_bus() + if self._init_obs is None: + self._backend_action.current_topo.values[:] = self._previous_conn_state._topo_vect + + def synch_backend_action(self, real_env_backend_action: _BackendAction) -> None: + """Synchronize the backend action of the (simulated) environment with the backend action of the real environment. + + This is called by the "simulated environment" (forecast env) and allow to remember "past state" of the grid + + This function should be overloaded in the simulated environment + """ + pass + def _update_parameters(self): """update value for the new parameters""" self._parameters = self.__new_param @@ -3225,7 +3253,6 @@ def _aux_apply_redisp(self, except_.append(except_tmp) else: res_action = action - # self._backend_action.set_redispatch(self._actual_dispatch) return res_action, failed_redisp, is_illegal_reco, is_done def _aux_update_backend_action(self, @@ -3414,13 +3441,13 @@ def _aux_register_env_converged(self, self._delta_gen_p[gen_detached_user] = 0. # when the backend disconnect it it should not be set to 0. self._prev_gen_p[:] = self._gen_activeprod_t + # update the previous state + self._previous_conn_state.update_from_backend(self.backend) + # finally, build the observation (it's a different one at each step, we cannot reuse the same one) # THIS SHOULD BE DONE AFTER EVERYTHING IS INITIALIZED ! self.current_obs = self.get_obs(_do_copy=False) - # update the previous state - self._previous_conn_state.update_from_backend(self.backend) - self._time_extract_obs += time.perf_counter() - beg_res return None @@ -3631,7 +3658,6 @@ def step(self, action: BaseAction) -> Tuple[BaseObservation, # I did something after calling "env.seed()" which is # somehow "env.step()" or "env.reset()" self._has_just_been_seeded = False - cls = type(self) has_error = True is_done = False @@ -3703,6 +3729,11 @@ def step(self, action: BaseAction) -> Tuple[BaseObservation, ) action, init_disp, action_storage_power = self._aux_step_reset_action() is_ambiguous = True + reco_valid = action.check_reconnection_valid(self._line_status, self._previous_conn_state._topo_vect) + if reco_valid is not None: + action, init_disp, action_storage_power = self._aux_step_reset_action() + is_illegal = True + except_.append(reco_valid) # speed optimization: during all the "env.step" the "topological impact" # of an action is called multiple times, I cache the results @@ -3743,7 +3774,7 @@ def step(self, action: BaseAction) -> Tuple[BaseObservation, False # because it absorbs all redispatching actions ) new_p = self._get_new_prod_setpoint(action) - new_p_th = 1.0 * new_p + new_p_th = new_p.copy() self._feed_data_for_detachment(new_p_th) # should be called before _axu_apply_detachment # storage unit @@ -3831,7 +3862,7 @@ def step(self, action: BaseAction) -> Tuple[BaseObservation, except StopIteration: # episode is over is_done = True - + self._backend_action.reset() end_step = time.perf_counter() self._time_step += end_step - beg_step diff --git a/grid2op/Environment/environment.py b/grid2op/Environment/environment.py index 0fbf3988..2e0a7c85 100644 --- a/grid2op/Environment/environment.py +++ b/grid2op/Environment/environment.py @@ -503,7 +503,7 @@ def _init_backend( self._observation_space.set_real_env_kwargs(self) # see issue https://github.com/Grid2Op/grid2op/issues/617 - # thermal limits are set AFTER this initial step + # thermal limits are set AFTER this initial "step" _no_overflow_disconnection = self._no_overflow_disconnection self._no_overflow_disconnection = True self._last_obs = None @@ -982,21 +982,17 @@ def reset_grid(self, self.backend.reset_public(self._init_grid_path) self._needs_active_bus = self.backend._needs_active_bus - # self.backend.assert_grid_correct() self._previous_conn_state.update_from_other(self._cst_prev_state_at_init) if self._thermal_limit_a is not None: self.backend.set_thermal_limit(self._thermal_limit_a.astype(dt_float)) self.nb_time_step = -1 # to have init obs at step 1 (and to prevent 'setting to proper state' "action" to be illegal) - - if self._init_obs is not None: - # update the backend - self._backend_action = self.backend.update_from_obs(self._init_obs) - self._backend_action.last_topo_registered.values[:] = self._init_obs._prev_conn._topo_vect - else: - self._backend_action = self._backend_action_class() - self._backend_action._needs_active_bus = self._needs_active_bus + + # synch the backend action with the init topology + # NB topolgy is supposed to be accessible when the backend is loaded in "reset_public" + # so no need to perform a powerflow in this case. + self._compute_init_state(do_powerflow=False) if self._init_obs is not None: # NB this is called twice (once at the end of reset), this is the first call @@ -1038,7 +1034,7 @@ def reset_grid(self, raise Grid2OpException(f"kwargs `method` used to set the initial state of the grid " f"is not understood (use one of `combine` or `ignore` and " f"not `{method}`)") - + *_, fail_to_start, info = self.step(init_action) if fail_to_start: raise Grid2OpException( diff --git a/grid2op/Environment/forecast_env.py b/grid2op/Environment/forecast_env.py index 9c019cd7..df0821d4 100644 --- a/grid2op/Environment/forecast_env.py +++ b/grid2op/Environment/forecast_env.py @@ -18,11 +18,12 @@ class ForecastEnv(Environment): - """Type of environment that increments the `highres_simulator` when it calls the env.step method. + """ + Type of environment that increments the `highres_simulator` when it calls the env.step method. It is the returned value of :func:`grid2op.Observation.BaseObservation.get_forecast_env`. """ - def __init__(self,**kwargs): + def __init__(self, **kwargs): if "_update_obs_after_reward" not in kwargs: kwargs["_update_obs_after_reward"] = False super().__init__(**kwargs) @@ -33,4 +34,5 @@ def step(self, action: BaseAction) -> Tuple["BaseObservation", bool, STEP_INFO_TYPING]: self._highres_sim_counter += 1 - return super().step(action) + tmp = super().step(action) + return tmp diff --git a/grid2op/Observation/baseObservation.py b/grid2op/Observation/baseObservation.py index 2764375c..342b21f9 100644 --- a/grid2op/Observation/baseObservation.py +++ b/grid2op/Observation/baseObservation.py @@ -264,6 +264,19 @@ class BaseObservation(GridObjects): non renewable generators) This is NOT the "curtailment" given in the action by the agent. + + This "effective curtailment" is expressed in MW rather than in ratio of pmax. + + Examples + -------- + .. code-block:: python + + import grid2op + env_name = "l2rpn_case14_sandbox" # or any other name + env = grid2op.make(env_name) + + obs = env.reset() + curtailment_mw = obs.curtailment_mw curtailment: :class:`numpy.ndarray`, dtype:float Give the power curtailed for each generator. It is expressed in @@ -4333,21 +4346,6 @@ def thermal_limit(self) -> np.ndarray: @property def curtailment_mw(self) -> np.ndarray: - """ - return the curtailment, expressed in MW rather than in ratio of pmax. - - Examples - -------- - .. code-block:: python - - import grid2op - env_name = "l2rpn_case14_sandbox" # or any other name - env = grid2op.make(env_name) - - obs = env.reset() - curtailment_mw = obs.curtailment_mw - - """ return self.curtailment * self.gen_pmax @property @@ -5062,13 +5060,14 @@ def _make_env_from_arays(self, backend._is_loaded = True nb_highres_called = self._obs_env.highres_sim_counter.nb_highres_called - res = ForecastEnv(**self._ptr_kwargs_env, - backend=backend, - chronics_handler=ch, - parameters=self._obs_env.parameters, - _init_obs=self, - highres_sim_counter=self._obs_env.highres_sim_counter - ) + res = ForecastEnv( + **self._ptr_kwargs_env, + backend=backend, + chronics_handler=ch, + parameters=self._obs_env.parameters, + _init_obs=self, + highres_sim_counter=self._obs_env.highres_sim_counter + ) # it does one simulation when it inits it (calling env.step) so I remove 1 here res.highres_sim_counter._HighResSimCounter__nb_highres_called = nb_highres_called return res diff --git a/grid2op/Observation/observationSpace.py b/grid2op/Observation/observationSpace.py index 976fc11c..a4213fb0 100644 --- a/grid2op/Observation/observationSpace.py +++ b/grid2op/Observation/observationSpace.py @@ -211,6 +211,7 @@ def _create_obs_env(self, env, observationClass): v.initialize(self.obs_env) self.obs_env.backend._disconnected_during_cf = np.full(type(self.obs_env).n_line, fill_value=-1, dtype=dt_int) + self.obs_env.synch_backend_action(env._backend_action) def _aux_create_backend(self, env, observation_bk_class, observation_bk_kwargs, path_grid_for, _local_dir_cls): if observation_bk_kwargs is None: diff --git a/grid2op/__init__.py b/grid2op/__init__.py index c84a9b06..c75ab596 100644 --- a/grid2op/__init__.py +++ b/grid2op/__init__.py @@ -11,7 +11,7 @@ Grid2Op a testbed platform to model sequential decision making in power systems. """ -__version__ = '1.12.2' +__version__ = '1.12.3' __all__ = [ "Action", diff --git a/grid2op/data_test/5bus_example_disco_el_in_grid/5bus_example.json b/grid2op/data_test/5bus_example_disco_el_in_grid/5bus_example.json new file mode 100644 index 00000000..4c1cbb76 --- /dev/null +++ b/grid2op/data_test/5bus_example_disco_el_in_grid/5bus_example.json @@ -0,0 +1,1339 @@ +{ + "_module": "pandapower.auxiliary", + "_class": "pandapowerNet", + "_object": { + "bus": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"vn_kv\",\"type\",\"zone\",\"in_service\"],\"index\":[0,1,2,3,4],\"data\":[[\"substation_1\",100.0,\"b\",null,true],[\"substation_2\",100.0,\"b\",null,true],[\"substation_3\",100.0,\"b\",null,true],[\"substation_4\",100.0,\"b\",null,true],[\"substation_5\",100.0,\"b\",null,true]]}", + "dtype": { + "name": "object", + "vn_kv": "float64", + "type": "object", + "zone": "object", + "in_service": "bool" + }, + "orient": "split" + }, + "load": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_mw\",\"q_mvar\",\"const_z_percent\",\"const_i_percent\",\"sn_mva\",\"scaling\",\"in_service\",\"type\"],\"index\":[0,1,2],\"data\":[[\"load_0_0\",0,10.0,7.0,0.0,0.0,null,1.0,true,null],[\"load_3_1\",3,10.0,7.0,0.0,0.0,null,1.0,true,null],[\"load_4_2\",4,10.0,7.0,0.0,0.0,null,1.0,true,null]]}", + "dtype": { + "name": "object", + "bus": "uint32", + "p_mw": "float64", + "q_mvar": "float64", + "const_z_percent": "float64", + "const_i_percent": "float64", + "sn_mva": "float64", + "scaling": "float64", + "in_service": "bool", + "type": "object" + }, + "orient": "split" + }, + "sgen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_mw\",\"q_mvar\",\"sn_mva\",\"scaling\",\"in_service\",\"type\",\"current_source\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "bus": "int64", + "p_mw": "float64", + "q_mvar": "float64", + "sn_mva": "float64", + "scaling": "float64", + "in_service": "bool", + "type": "object", + "current_source": "bool" + }, + "orient": "split" + }, + "storage": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_mw\",\"q_mvar\",\"sn_mva\",\"soc_percent\",\"min_e_mwh\",\"max_e_mwh\",\"scaling\",\"in_service\",\"type\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "bus": "int64", + "p_mw": "float64", + "q_mvar": "float64", + "sn_mva": "float64", + "soc_percent": "float64", + "min_e_mwh": "float64", + "max_e_mwh": "float64", + "scaling": "float64", + "in_service": "bool", + "type": "object" + }, + "orient": "split" + }, + "gen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_mw\",\"vm_pu\",\"sn_mva\",\"min_q_mvar\",\"max_q_mvar\",\"scaling\",\"slack\",\"in_service\",\"type\"],\"index\":[0,1],\"data\":[[\"gen_0_0\",0,10.0,1.02,null,null,null,1.0,false,true,null],[\"gen_1_1\",1,20.0,1.02,null,null,null,1.0,true,true,null]]}", + "dtype": { + "name": "object", + "bus": "uint32", + "p_mw": "float64", + "vm_pu": "float64", + "sn_mva": "float64", + "min_q_mvar": "float64", + "max_q_mvar": "float64", + "scaling": "float64", + "slack": "bool", + "in_service": "bool", + "type": "object" + }, + "orient": "split" + }, + "switch": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"bus\",\"element\",\"et\",\"type\",\"closed\",\"name\",\"z_ohm\"],\"index\":[],\"data\":[]}", + "dtype": { + "bus": "int64", + "element": "int64", + "et": "object", + "type": "object", + "closed": "bool", + "name": "object", + "z_ohm": "float64" + }, + "orient": "split" + }, + "shunt": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"bus\",\"name\",\"q_mvar\",\"p_mw\",\"vn_kv\",\"step\",\"max_step\",\"in_service\"],\"index\":[],\"data\":[]}", + "dtype": { + "bus": "uint32", + "name": "object", + "q_mvar": "float64", + "p_mw": "float64", + "vn_kv": "float64", + "step": "uint32", + "max_step": "uint32", + "in_service": "bool" + }, + "orient": "split" + }, + "ext_grid": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"vm_pu\",\"va_degree\",\"in_service\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "bus": "uint32", + "vm_pu": "float64", + "va_degree": "float64", + "in_service": "bool" + }, + "orient": "split" + }, + "line": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"std_type\",\"from_bus\",\"to_bus\",\"length_km\",\"r_ohm_per_km\",\"x_ohm_per_km\",\"c_nf_per_km\",\"g_us_per_km\",\"max_i_ka\",\"df\",\"parallel\",\"type\",\"in_service\"],\"index\":[0,1,2,3,4,5,6,7],\"data\":[[null,\"NAYY 4x50 SE\",0,1,4.0,0.642,0.083,210.0,0.0,0.6,1.0,1,\"cs\",true],[\"0_2_2\",\"NAYY 4x50 SE\",0,2,4.47,0.642,0.083,210.0,0.0,0.22,1.0,1,\"cs\",true],[\"0_3_3\",\"NAYY 4x50 SE\",0,3,5.65,0.642,0.083,210.0,0.0,0.16,1.0,1,\"cs\",false],[\"0_4_4\",\"NAYY 4x50 SE\",0,4,4.0,0.642,0.083,210.0,0.0,0.16,1.0,1,\"cs\",true],[\"1_2_5\",\"NAYY 4x50 SE\",1,2,2.0,0.642,0.083,210.0,0.0,0.6,1.0,1,\"cs\",true],[\"2_3_6\",\"NAYY 4x50 SE\",2,3,2.0,0.642,0.083,210.0,0.0,0.3,1.0,1,\"cs\",true],[\"2_3_7\",\"NAYY 4x50 SE\",2,3,2.0,0.642,0.083,210.0,0.0,0.3,1.0,1,\"cs\",true],[\"3_4_8\",\"NAYY 4x50 SE\",3,4,4.0,0.642,0.083,210.0,0.0,0.16,1.0,1,\"cs\",true]]}", + "dtype": { + "name": "object", + "std_type": "object", + "from_bus": "uint32", + "to_bus": "uint32", + "length_km": "float64", + "r_ohm_per_km": "float64", + "x_ohm_per_km": "float64", + "c_nf_per_km": "float64", + "g_us_per_km": "float64", + "max_i_ka": "float64", + "df": "float64", + "parallel": "uint32", + "type": "object", + "in_service": "bool" + }, + "orient": "split" + }, + "trafo": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"std_type\",\"hv_bus\",\"lv_bus\",\"sn_mva\",\"vn_hv_kv\",\"vn_lv_kv\",\"vk_percent\",\"vkr_percent\",\"pfe_kw\",\"i0_percent\",\"shift_degree\",\"tap_side\",\"tap_neutral\",\"tap_min\",\"tap_max\",\"tap_step_percent\",\"tap_step_degree\",\"tap_pos\",\"tap_phase_shifter\",\"parallel\",\"df\",\"in_service\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "std_type": "object", + "hv_bus": "uint32", + "lv_bus": "uint32", + "sn_mva": "float64", + "vn_hv_kv": "float64", + "vn_lv_kv": "float64", + "vk_percent": "float64", + "vkr_percent": "float64", + "pfe_kw": "float64", + "i0_percent": "float64", + "shift_degree": "float64", + "tap_side": "object", + "tap_neutral": "int32", + "tap_min": "int32", + "tap_max": "int32", + "tap_step_percent": "float64", + "tap_step_degree": "float64", + "tap_pos": "int32", + "tap_phase_shifter": "bool", + "parallel": "uint32", + "df": "float64", + "in_service": "bool" + }, + "orient": "split" + }, + "trafo3w": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"std_type\",\"hv_bus\",\"mv_bus\",\"lv_bus\",\"sn_hv_mva\",\"sn_mv_mva\",\"sn_lv_mva\",\"vn_hv_kv\",\"vn_mv_kv\",\"vn_lv_kv\",\"vk_hv_percent\",\"vk_mv_percent\",\"vk_lv_percent\",\"vkr_hv_percent\",\"vkr_mv_percent\",\"vkr_lv_percent\",\"pfe_kw\",\"i0_percent\",\"shift_mv_degree\",\"shift_lv_degree\",\"tap_side\",\"tap_neutral\",\"tap_min\",\"tap_max\",\"tap_step_percent\",\"tap_step_degree\",\"tap_pos\",\"tap_at_star_point\",\"in_service\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "std_type": "object", + "hv_bus": "uint32", + "mv_bus": "uint32", + "lv_bus": "uint32", + "sn_hv_mva": "float64", + "sn_mv_mva": "float64", + "sn_lv_mva": "float64", + "vn_hv_kv": "float64", + "vn_mv_kv": "float64", + "vn_lv_kv": "float64", + "vk_hv_percent": "float64", + "vk_mv_percent": "float64", + "vk_lv_percent": "float64", + "vkr_hv_percent": "float64", + "vkr_mv_percent": "float64", + "vkr_lv_percent": "float64", + "pfe_kw": "float64", + "i0_percent": "float64", + "shift_mv_degree": "float64", + "shift_lv_degree": "float64", + "tap_side": "object", + "tap_neutral": "int32", + "tap_min": "int32", + "tap_max": "int32", + "tap_step_percent": "float64", + "tap_step_degree": "float64", + "tap_pos": "int32", + "tap_at_star_point": "bool", + "in_service": "bool" + }, + "orient": "split" + }, + "impedance": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"from_bus\",\"to_bus\",\"rft_pu\",\"xft_pu\",\"rtf_pu\",\"xtf_pu\",\"sn_mva\",\"in_service\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "from_bus": "uint32", + "to_bus": "uint32", + "rft_pu": "float64", + "xft_pu": "float64", + "rtf_pu": "float64", + "xtf_pu": "float64", + "sn_mva": "float64", + "in_service": "bool" + }, + "orient": "split" + }, + "dcline": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"from_bus\",\"to_bus\",\"p_mw\",\"loss_percent\",\"loss_mw\",\"vm_from_pu\",\"vm_to_pu\",\"max_p_mw\",\"min_q_from_mvar\",\"min_q_to_mvar\",\"max_q_from_mvar\",\"max_q_to_mvar\",\"in_service\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "from_bus": "uint32", + "to_bus": "uint32", + "p_mw": "float64", + "loss_percent": "float64", + "loss_mw": "float64", + "vm_from_pu": "float64", + "vm_to_pu": "float64", + "max_p_mw": "float64", + "min_q_from_mvar": "float64", + "min_q_to_mvar": "float64", + "max_q_from_mvar": "float64", + "max_q_to_mvar": "float64", + "in_service": "bool" + }, + "orient": "split" + }, + "ward": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"ps_mw\",\"qs_mvar\",\"qz_mvar\",\"pz_mw\",\"in_service\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "bus": "uint32", + "ps_mw": "float64", + "qs_mvar": "float64", + "qz_mvar": "float64", + "pz_mw": "float64", + "in_service": "bool" + }, + "orient": "split" + }, + "xward": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"ps_mw\",\"qs_mvar\",\"qz_mvar\",\"pz_mw\",\"r_ohm\",\"x_ohm\",\"vm_pu\",\"in_service\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "bus": "uint32", + "ps_mw": "float64", + "qs_mvar": "float64", + "qz_mvar": "float64", + "pz_mw": "float64", + "r_ohm": "float64", + "x_ohm": "float64", + "vm_pu": "float64", + "in_service": "bool" + }, + "orient": "split" + }, + "measurement": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"measurement_type\",\"element_type\",\"element\",\"value\",\"std_dev\",\"side\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "measurement_type": "object", + "element_type": "object", + "element": "uint32", + "value": "float64", + "std_dev": "float64", + "side": "object" + }, + "orient": "split" + }, + "pwl_cost": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"power_type\",\"element\",\"et\",\"points\"],\"index\":[],\"data\":[]}", + "dtype": { + "power_type": "object", + "element": "object", + "et": "object", + "points": "object" + }, + "orient": "split" + }, + "poly_cost": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"element\",\"et\",\"cp0_eur\",\"cp1_eur_per_mw\",\"cp2_eur_per_mw2\",\"cq0_eur\",\"cq1_eur_per_mvar\",\"cq2_eur_per_mvar2\"],\"index\":[],\"data\":[]}", + "dtype": { + "element": "object", + "et": "object", + "cp0_eur": "float64", + "cp1_eur_per_mw": "float64", + "cp2_eur_per_mw2": "float64", + "cq0_eur": "float64", + "cq1_eur_per_mvar": "float64", + "cq2_eur_per_mvar2": "float64" + }, + "orient": "split" + }, + "line_geodata": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"coords\"],\"index\":[0,1,2,3,4,5,6,7],\"data\":[[[[0,0],[0,4]]],[[[0,0],[2,4]]],[[[0,0],[4,4]]],[[[0,0],[4,0]]],[[[0,4],[2,4]]],[[[2,4],[3,4.2],[4,4]]],[[[2,4],[3,3.8],[4,4]]],[[[4,4],[4,0]]]]}", + "dtype": { + "coords": "object" + }, + "orient": "split" + }, + "bus_geodata": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"x\",\"y\",\"coords\"],\"index\":[0,1,2,3,4],\"data\":[[0.0,0.0,null],[0.0,4.0,null],[2.0,4.0,null],[4.0,4.0,null],[4.0,0.0,null]]}", + "dtype": { + "x": "float64", + "y": "float64", + "coords": "object" + }, + "orient": "split" + }, + "version": "2.1.0", + "converged": true, + "name": "5bus", + "f_hz": 50.0, + "sn_mva": 1, + "std_types": { + "line": { + "NAYY 4x50 SE": { + "c_nf_per_km": 210, + "r_ohm_per_km": 0.642, + "x_ohm_per_km": 0.083, + "max_i_ka": 0.142, + "type": "cs", + "q_mm2": 50, + "alpha": 0.00403 + }, + "NAYY 4x120 SE": { + "c_nf_per_km": 264, + "r_ohm_per_km": 0.225, + "x_ohm_per_km": 0.08, + "max_i_ka": 0.242, + "type": "cs", + "q_mm2": 120, + "alpha": 0.00403 + }, + "NAYY 4x150 SE": { + "c_nf_per_km": 261, + "r_ohm_per_km": 0.208, + "x_ohm_per_km": 0.08, + "max_i_ka": 0.27, + "type": "cs", + "q_mm2": 150, + "alpha": 0.00403 + }, + "NA2XS2Y 1x95 RM/25 12/20 kV": { + "c_nf_per_km": 216, + "r_ohm_per_km": 0.313, + "x_ohm_per_km": 0.132, + "max_i_ka": 0.252, + "type": "cs", + "q_mm2": 95, + "alpha": 0.00403 + }, + "NA2XS2Y 1x185 RM/25 12/20 kV": { + "c_nf_per_km": 273, + "r_ohm_per_km": 0.161, + "x_ohm_per_km": 0.117, + "max_i_ka": 0.362, + "type": "cs", + "q_mm2": 185, + "alpha": 0.00403 + }, + "NA2XS2Y 1x240 RM/25 12/20 kV": { + "c_nf_per_km": 304, + "r_ohm_per_km": 0.122, + "x_ohm_per_km": 0.112, + "max_i_ka": 0.421, + "type": "cs", + "q_mm2": 240, + "alpha": 0.00403 + }, + "NA2XS2Y 1x95 RM/25 6/10 kV": { + "c_nf_per_km": 315, + "r_ohm_per_km": 0.313, + "x_ohm_per_km": 0.123, + "max_i_ka": 0.249, + "type": "cs", + "q_mm2": 95, + "alpha": 0.00403 + }, + "NA2XS2Y 1x185 RM/25 6/10 kV": { + "c_nf_per_km": 406, + "r_ohm_per_km": 0.161, + "x_ohm_per_km": 0.11, + "max_i_ka": 0.358, + "type": "cs", + "q_mm2": 185, + "alpha": 0.00403 + }, + "NA2XS2Y 1x240 RM/25 6/10 kV": { + "c_nf_per_km": 456, + "r_ohm_per_km": 0.122, + "x_ohm_per_km": 0.105, + "max_i_ka": 0.416, + "type": "cs", + "q_mm2": 240, + "alpha": 0.00403 + }, + "NA2XS2Y 1x150 RM/25 12/20 kV": { + "c_nf_per_km": 250, + "r_ohm_per_km": 0.206, + "x_ohm_per_km": 0.116, + "max_i_ka": 0.319, + "type": "cs", + "q_mm2": 150, + "alpha": 0.00403 + }, + "NA2XS2Y 1x120 RM/25 12/20 kV": { + "c_nf_per_km": 230, + "r_ohm_per_km": 0.253, + "x_ohm_per_km": 0.119, + "max_i_ka": 0.283, + "type": "cs", + "q_mm2": 120, + "alpha": 0.00403 + }, + "NA2XS2Y 1x70 RM/25 12/20 kV": { + "c_nf_per_km": 190, + "r_ohm_per_km": 0.443, + "x_ohm_per_km": 0.132, + "max_i_ka": 0.22, + "type": "cs", + "q_mm2": 70, + "alpha": 0.00403 + }, + "NA2XS2Y 1x150 RM/25 6/10 kV": { + "c_nf_per_km": 360, + "r_ohm_per_km": 0.206, + "x_ohm_per_km": 0.11, + "max_i_ka": 0.315, + "type": "cs", + "q_mm2": 150, + "alpha": 0.00403 + }, + "NA2XS2Y 1x120 RM/25 6/10 kV": { + "c_nf_per_km": 340, + "r_ohm_per_km": 0.253, + "x_ohm_per_km": 0.113, + "max_i_ka": 0.28, + "type": "cs", + "q_mm2": 120, + "alpha": 0.00403 + }, + "NA2XS2Y 1x70 RM/25 6/10 kV": { + "c_nf_per_km": 280, + "r_ohm_per_km": 0.443, + "x_ohm_per_km": 0.123, + "max_i_ka": 0.217, + "type": "cs", + "q_mm2": 70, + "alpha": 0.00403 + }, + "N2XS(FL)2Y 1x120 RM/35 64/110 kV": { + "c_nf_per_km": 112, + "r_ohm_per_km": 0.153, + "x_ohm_per_km": 0.166, + "max_i_ka": 0.366, + "type": "cs", + "q_mm2": 120, + "alpha": 0.00393 + }, + "N2XS(FL)2Y 1x185 RM/35 64/110 kV": { + "c_nf_per_km": 125, + "r_ohm_per_km": 0.099, + "x_ohm_per_km": 0.156, + "max_i_ka": 0.457, + "type": "cs", + "q_mm2": 185, + "alpha": 0.00393 + }, + "N2XS(FL)2Y 1x240 RM/35 64/110 kV": { + "c_nf_per_km": 135, + "r_ohm_per_km": 0.075, + "x_ohm_per_km": 0.149, + "max_i_ka": 0.526, + "type": "cs", + "q_mm2": 240, + "alpha": 0.00393 + }, + "N2XS(FL)2Y 1x300 RM/35 64/110 kV": { + "c_nf_per_km": 144, + "r_ohm_per_km": 0.06, + "x_ohm_per_km": 0.144, + "max_i_ka": 0.588, + "type": "cs", + "q_mm2": 300, + "alpha": 0.00393 + }, + "15-AL1/3-ST1A 0.4": { + "c_nf_per_km": 11, + "r_ohm_per_km": 1.8769, + "x_ohm_per_km": 0.35, + "max_i_ka": 0.105, + "type": "ol", + "q_mm2": 16, + "alpha": 0.00403 + }, + "24-AL1/4-ST1A 0.4": { + "c_nf_per_km": 11.25, + "r_ohm_per_km": 1.2012, + "x_ohm_per_km": 0.335, + "max_i_ka": 0.14, + "type": "ol", + "q_mm2": 24, + "alpha": 0.00403 + }, + "48-AL1/8-ST1A 0.4": { + "c_nf_per_km": 12.2, + "r_ohm_per_km": 0.5939, + "x_ohm_per_km": 0.3, + "max_i_ka": 0.21, + "type": "ol", + "q_mm2": 48, + "alpha": 0.00403 + }, + "94-AL1/15-ST1A 0.4": { + "c_nf_per_km": 13.2, + "r_ohm_per_km": 0.306, + "x_ohm_per_km": 0.29, + "max_i_ka": 0.35, + "type": "ol", + "q_mm2": 94, + "alpha": 0.00403 + }, + "34-AL1/6-ST1A 10.0": { + "c_nf_per_km": 9.7, + "r_ohm_per_km": 0.8342, + "x_ohm_per_km": 0.36, + "max_i_ka": 0.17, + "type": "ol", + "q_mm2": 34, + "alpha": 0.00403 + }, + "48-AL1/8-ST1A 10.0": { + "c_nf_per_km": 10.1, + "r_ohm_per_km": 0.5939, + "x_ohm_per_km": 0.35, + "max_i_ka": 0.21, + "type": "ol", + "q_mm2": 48, + "alpha": 0.00403 + }, + "70-AL1/11-ST1A 10.0": { + "c_nf_per_km": 10.4, + "r_ohm_per_km": 0.4132, + "x_ohm_per_km": 0.339, + "max_i_ka": 0.29, + "type": "ol", + "q_mm2": 70, + "alpha": 0.00403 + }, + "94-AL1/15-ST1A 10.0": { + "c_nf_per_km": 10.75, + "r_ohm_per_km": 0.306, + "x_ohm_per_km": 0.33, + "max_i_ka": 0.35, + "type": "ol", + "q_mm2": 94, + "alpha": 0.00403 + }, + "122-AL1/20-ST1A 10.0": { + "c_nf_per_km": 11.1, + "r_ohm_per_km": 0.2376, + "x_ohm_per_km": 0.323, + "max_i_ka": 0.41, + "type": "ol", + "q_mm2": 122, + "alpha": 0.00403 + }, + "149-AL1/24-ST1A 10.0": { + "c_nf_per_km": 11.25, + "r_ohm_per_km": 0.194, + "x_ohm_per_km": 0.315, + "max_i_ka": 0.47, + "type": "ol", + "q_mm2": 149, + "alpha": 0.00403 + }, + "34-AL1/6-ST1A 20.0": { + "c_nf_per_km": 9.15, + "r_ohm_per_km": 0.8342, + "x_ohm_per_km": 0.382, + "max_i_ka": 0.17, + "type": "ol", + "q_mm2": 34, + "alpha": 0.00403 + }, + "48-AL1/8-ST1A 20.0": { + "c_nf_per_km": 9.5, + "r_ohm_per_km": 0.5939, + "x_ohm_per_km": 0.372, + "max_i_ka": 0.21, + "type": "ol", + "q_mm2": 48, + "alpha": 0.00403 + }, + "70-AL1/11-ST1A 20.0": { + "c_nf_per_km": 9.7, + "r_ohm_per_km": 0.4132, + "x_ohm_per_km": 0.36, + "max_i_ka": 0.29, + "type": "ol", + "q_mm2": 70, + "alpha": 0.00403 + }, + "94-AL1/15-ST1A 20.0": { + "c_nf_per_km": 10, + "r_ohm_per_km": 0.306, + "x_ohm_per_km": 0.35, + "max_i_ka": 0.35, + "type": "ol", + "q_mm2": 94, + "alpha": 0.00403 + }, + "122-AL1/20-ST1A 20.0": { + "c_nf_per_km": 10.3, + "r_ohm_per_km": 0.2376, + "x_ohm_per_km": 0.344, + "max_i_ka": 0.41, + "type": "ol", + "q_mm2": 122, + "alpha": 0.00403 + }, + "149-AL1/24-ST1A 20.0": { + "c_nf_per_km": 10.5, + "r_ohm_per_km": 0.194, + "x_ohm_per_km": 0.337, + "max_i_ka": 0.47, + "type": "ol", + "q_mm2": 149, + "alpha": 0.00403 + }, + "184-AL1/30-ST1A 20.0": { + "c_nf_per_km": 10.75, + "r_ohm_per_km": 0.1571, + "x_ohm_per_km": 0.33, + "max_i_ka": 0.535, + "type": "ol", + "q_mm2": 184, + "alpha": 0.00403 + }, + "243-AL1/39-ST1A 20.0": { + "c_nf_per_km": 11, + "r_ohm_per_km": 0.1188, + "x_ohm_per_km": 0.32, + "max_i_ka": 0.645, + "type": "ol", + "q_mm2": 243, + "alpha": 0.00403 + }, + "48-AL1/8-ST1A 110.0": { + "c_nf_per_km": 8, + "r_ohm_per_km": 0.5939, + "x_ohm_per_km": 0.46, + "max_i_ka": 0.21, + "type": "ol", + "q_mm2": 48, + "alpha": 0.00403 + }, + "70-AL1/11-ST1A 110.0": { + "c_nf_per_km": 8.4, + "r_ohm_per_km": 0.4132, + "x_ohm_per_km": 0.45, + "max_i_ka": 0.29, + "type": "ol", + "q_mm2": 70, + "alpha": 0.00403 + }, + "94-AL1/15-ST1A 110.0": { + "c_nf_per_km": 8.65, + "r_ohm_per_km": 0.306, + "x_ohm_per_km": 0.44, + "max_i_ka": 0.35, + "type": "ol", + "q_mm2": 94, + "alpha": 0.00403 + }, + "122-AL1/20-ST1A 110.0": { + "c_nf_per_km": 8.5, + "r_ohm_per_km": 0.2376, + "x_ohm_per_km": 0.43, + "max_i_ka": 0.41, + "type": "ol", + "q_mm2": 122, + "alpha": 0.00403 + }, + "149-AL1/24-ST1A 110.0": { + "c_nf_per_km": 8.75, + "r_ohm_per_km": 0.194, + "x_ohm_per_km": 0.41, + "max_i_ka": 0.47, + "type": "ol", + "q_mm2": 149, + "alpha": 0.00403 + }, + "184-AL1/30-ST1A 110.0": { + "c_nf_per_km": 8.8, + "r_ohm_per_km": 0.1571, + "x_ohm_per_km": 0.4, + "max_i_ka": 0.535, + "type": "ol", + "q_mm2": 184, + "alpha": 0.00403 + }, + "243-AL1/39-ST1A 110.0": { + "c_nf_per_km": 9, + "r_ohm_per_km": 0.1188, + "x_ohm_per_km": 0.39, + "max_i_ka": 0.645, + "type": "ol", + "q_mm2": 243, + "alpha": 0.00403 + }, + "305-AL1/39-ST1A 110.0": { + "c_nf_per_km": 9.2, + "r_ohm_per_km": 0.0949, + "x_ohm_per_km": 0.38, + "max_i_ka": 0.74, + "type": "ol", + "q_mm2": 305, + "alpha": 0.00403 + }, + "490-AL1/64-ST1A 110.0": { + "c_nf_per_km": 9.75, + "r_ohm_per_km": 0.059, + "x_ohm_per_km": 0.37, + "max_i_ka": 0.96, + "type": "ol", + "q_mm2": 490, + "alpha": 0.00403 + }, + "679-AL1/86-ST1A 110.0": { + "c_nf_per_km": 9.95, + "r_ohm_per_km": 0.042, + "x_ohm_per_km": 0.36, + "max_i_ka": 0.115, + "type": "ol", + "q_mm2": 679, + "alpha": 0.00403 + }, + "490-AL1/64-ST1A 220.0": { + "c_nf_per_km": 10, + "r_ohm_per_km": 0.059, + "x_ohm_per_km": 0.285, + "max_i_ka": 0.96, + "type": "ol", + "q_mm2": 490, + "alpha": 0.00403 + }, + "679-AL1/86-ST1A 220.0": { + "c_nf_per_km": 11.7, + "r_ohm_per_km": 0.042, + "x_ohm_per_km": 0.275, + "max_i_ka": 0.115, + "type": "ol", + "q_mm2": 679, + "alpha": 0.00403 + }, + "490-AL1/64-ST1A 380.0": { + "c_nf_per_km": 11, + "r_ohm_per_km": 0.059, + "x_ohm_per_km": 0.253, + "max_i_ka": 0.96, + "type": "ol", + "q_mm2": 490, + "alpha": 0.00403 + }, + "679-AL1/86-ST1A 380.0": { + "c_nf_per_km": 14.6, + "r_ohm_per_km": 0.042, + "x_ohm_per_km": 0.25, + "max_i_ka": 0.115, + "type": "ol", + "q_mm2": 679, + "alpha": 0.00403 + } + }, + "trafo": { + "160 MVA 380/110 kV": { + "i0_percent": 0.06, + "pfe_kw": 60, + "vkr_percent": 0.25, + "sn_mva": 160, + "vn_lv_kv": 110.0, + "vn_hv_kv": 380.0, + "vk_percent": 12.2, + "shift_degree": 0, + "vector_group": "Yy0", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "100 MVA 220/110 kV": { + "i0_percent": 0.06, + "pfe_kw": 55, + "vkr_percent": 0.26, + "sn_mva": 100, + "vn_lv_kv": 110.0, + "vn_hv_kv": 220.0, + "vk_percent": 12.0, + "shift_degree": 0, + "vector_group": "Yy0", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "63 MVA 110/20 kV": { + "i0_percent": 0.04, + "pfe_kw": 22, + "vkr_percent": 0.32, + "sn_mva": 63, + "vn_lv_kv": 20.0, + "vn_hv_kv": 110.0, + "vk_percent": 18, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "40 MVA 110/20 kV": { + "i0_percent": 0.05, + "pfe_kw": 18, + "vkr_percent": 0.34, + "sn_mva": 40, + "vn_lv_kv": 20.0, + "vn_hv_kv": 110.0, + "vk_percent": 16.2, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "25 MVA 110/20 kV": { + "i0_percent": 0.07, + "pfe_kw": 14, + "vkr_percent": 0.41, + "sn_mva": 25, + "vn_lv_kv": 20.0, + "vn_hv_kv": 110.0, + "vk_percent": 12, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "63 MVA 110/10 kV": { + "sn_mva": 63, + "vn_hv_kv": 110, + "vn_lv_kv": 10, + "vk_percent": 18, + "vkr_percent": 0.32, + "pfe_kw": 22, + "i0_percent": 0.04, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "40 MVA 110/10 kV": { + "sn_mva": 40, + "vn_hv_kv": 110, + "vn_lv_kv": 10, + "vk_percent": 16.2, + "vkr_percent": 0.34, + "pfe_kw": 18, + "i0_percent": 0.05, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "25 MVA 110/10 kV": { + "sn_mva": 25, + "vn_hv_kv": 110, + "vn_lv_kv": 10, + "vk_percent": 12, + "vkr_percent": 0.41, + "pfe_kw": 14, + "i0_percent": 0.07, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "0.25 MVA 20/0.4 kV": { + "sn_mva": 0.25, + "vn_hv_kv": 20, + "vn_lv_kv": 0.4, + "vk_percent": 6, + "vkr_percent": 1.44, + "pfe_kw": 0.8, + "i0_percent": 0.32, + "shift_degree": 150, + "vector_group": "Yzn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.4 MVA 20/0.4 kV": { + "sn_mva": 0.4, + "vn_hv_kv": 20, + "vn_lv_kv": 0.4, + "vk_percent": 6, + "vkr_percent": 1.425, + "pfe_kw": 1.35, + "i0_percent": 0.3375, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.63 MVA 20/0.4 kV": { + "sn_mva": 0.63, + "vn_hv_kv": 20, + "vn_lv_kv": 0.4, + "vk_percent": 6, + "vkr_percent": 1.206, + "pfe_kw": 1.65, + "i0_percent": 0.2619, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.25 MVA 10/0.4 kV": { + "sn_mva": 0.25, + "vn_hv_kv": 10, + "vn_lv_kv": 0.4, + "vk_percent": 4, + "vkr_percent": 1.2, + "pfe_kw": 0.6, + "i0_percent": 0.24, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.4 MVA 10/0.4 kV": { + "sn_mva": 0.4, + "vn_hv_kv": 10, + "vn_lv_kv": 0.4, + "vk_percent": 4, + "vkr_percent": 1.325, + "pfe_kw": 0.95, + "i0_percent": 0.2375, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.63 MVA 10/0.4 kV": { + "sn_mva": 0.63, + "vn_hv_kv": 10, + "vn_lv_kv": 0.4, + "vk_percent": 4, + "vkr_percent": 1.0794, + "pfe_kw": 1.18, + "i0_percent": 0.1873, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + } + }, + "trafo3w": { + "63/25/38 MVA 110/20/10 kV": { + "sn_hv_mva": 63, + "sn_mv_mva": 25, + "sn_lv_mva": 38, + "vn_hv_kv": 110, + "vn_mv_kv": 20, + "vn_lv_kv": 10, + "vk_hv_percent": 10.4, + "vk_mv_percent": 10.4, + "vk_lv_percent": 10.4, + "vkr_hv_percent": 0.28, + "vkr_mv_percent": 0.32, + "vkr_lv_percent": 0.35, + "pfe_kw": 35, + "i0_percent": 0.89, + "shift_mv_degree": 0, + "shift_lv_degree": 0, + "vector_group": "YN0yn0yn0", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -10, + "tap_max": 10, + "tap_step_percent": 1.2 + }, + "63/25/38 MVA 110/10/10 kV": { + "sn_hv_mva": 63, + "sn_mv_mva": 25, + "sn_lv_mva": 38, + "vn_hv_kv": 110, + "vn_mv_kv": 10, + "vn_lv_kv": 10, + "vk_hv_percent": 10.4, + "vk_mv_percent": 10.4, + "vk_lv_percent": 10.4, + "vkr_hv_percent": 0.28, + "vkr_mv_percent": 0.32, + "vkr_lv_percent": 0.35, + "pfe_kw": 35, + "i0_percent": 0.89, + "shift_mv_degree": 0, + "shift_lv_degree": 0, + "vector_group": "YN0yn0yn0", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -10, + "tap_max": 10, + "tap_step_percent": 1.2 + } + } + }, + "res_bus": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"vm_pu\",\"va_degree\",\"p_mw\",\"q_mvar\"],\"index\":[0,1,2,3,4],\"data\":[[1.02,-0.845445168673926,0.0,-111.791243672370911],[1.02,0.0,-21.729831330858325,116.839935541152954],[1.019214100496144,-0.409103297622625,0.0,0.0],[1.018637116919488,-0.503470352662766,10.0,7.0],[1.017983079721402,-0.653497665026562,10.0,7.0]]}", + "dtype": { + "vm_pu": "float64", + "va_degree": "float64", + "p_mw": "float64", + "q_mvar": "float64" + }, + "orient": "split" + }, + "res_line": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_from_mw\",\"q_from_mvar\",\"p_to_mw\",\"q_to_mvar\",\"pl_mw\",\"ql_mvar\",\"i_from_ka\",\"i_to_ka\",\"i_ka\",\"vm_from_pu\",\"va_from_degree\",\"vm_to_pu\",\"va_to_degree\",\"loading_percent\"],\"index\":[0,1,2,3,4,5,6,7],\"data\":[[-7.167647147657727,57.480079867900443,8.03525639977348,-60.113463233922118,0.867609252115754,-2.633383366021676,0.327874112511858,0.343286326507116,0.343286326507116,1.02,-0.845445168673926,1.02,0.0,57.214387751185988],[-0.657313913963437,25.969126903729045,0.866078469150186,-29.007927174007612,0.208764555186749,-3.038800270278568,0.147040043868819,0.164393305610081,0.164393305610081,1.02,-0.845445168673926,1.019214100496144,-0.409103297622625,74.724229822763931],[1.64566972119938,15.370129751576128,-1.540268914180618,-19.229415550834709,0.105400807018762,-3.859285799258581,0.087496748884432,0.109338903896103,0.109338903896103,1.02,-0.845445168673926,1.018637116919488,-0.503470352662766,68.336814935064211],[6.179291340421495,12.971907266349552,-6.119076735247816,-15.70424981919658,0.060214605173678,-2.732342552847028,0.081330018729726,0.095589209712924,0.095589209712924,1.02,-0.845445168673926,1.017983079721402,-0.653497665026562,59.743256070577175],[13.694574931085771,-56.726472302863066,-13.283848894885464,55.407854241119566,0.410726036200307,-1.3186180617435,0.330312825878128,0.322760996590474,0.330312825878128,1.02,0.0,1.019214100496144,-0.409103297622625,55.052137646354595],[6.208885212872048,-13.199963533555254,-6.184761786109662,11.833197159642042,0.024123426762386,-1.366766373913212,0.082632108556076,0.075677384410291,0.082632108556076,1.019214100496144,-0.409103297622625,1.018637116919488,-0.503470352662766,27.544036185358689],[6.208885212872048,-13.199963533555254,-6.184761786109662,11.833197159642042,0.024123426762386,-1.366766373913212,0.082632108556076,0.075677384410291,0.082632108556076,1.019214100496144,-0.409103297622625,1.018637116919488,-0.503470352662766,27.544036185358689],[3.909792486391969,-11.436978768449999,-3.88092326475316,8.704249819196738,0.028869221638809,-2.732728949253261,0.068506463438984,0.054050881891821,0.068506463438984,1.018637116919488,-0.503470352662766,1.017983079721402,-0.653497665026562,42.816539649365005]]}", + "dtype": { + "p_from_mw": "float64", + "q_from_mvar": "float64", + "p_to_mw": "float64", + "q_to_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_from_ka": "float64", + "i_to_ka": "float64", + "i_ka": "float64", + "vm_from_pu": "float64", + "va_from_degree": "float64", + "vm_to_pu": "float64", + "va_to_degree": "float64", + "loading_percent": "float64" + }, + "orient": "split" + }, + "res_trafo": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_hv_mw\",\"q_hv_mvar\",\"p_lv_mw\",\"q_lv_mvar\",\"pl_mw\",\"ql_mvar\",\"i_hv_ka\",\"i_lv_ka\",\"vm_hv_pu\",\"va_hv_degree\",\"vm_lv_pu\",\"va_lv_degree\",\"loading_percent\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_hv_mw": "float64", + "q_hv_mvar": "float64", + "p_lv_mw": "float64", + "q_lv_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_hv_ka": "float64", + "i_lv_ka": "float64", + "vm_hv_pu": "float64", + "va_hv_degree": "float64", + "vm_lv_pu": "float64", + "va_lv_degree": "float64", + "loading_percent": "float64" + }, + "orient": "split" + }, + "res_trafo3w": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_hv_mw\",\"q_hv_mvar\",\"p_mv_mw\",\"q_mv_mvar\",\"p_lv_mw\",\"q_lv_mvar\",\"pl_mw\",\"ql_mvar\",\"i_hv_ka\",\"i_mv_ka\",\"i_lv_ka\",\"vm_hv_pu\",\"va_hv_degree\",\"vm_mv_pu\",\"va_mv_degree\",\"vm_lv_pu\",\"va_lv_degree\",\"va_internal_degree\",\"vm_internal_pu\",\"loading_percent\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_hv_mw": "float64", + "q_hv_mvar": "float64", + "p_mv_mw": "float64", + "q_mv_mvar": "float64", + "p_lv_mw": "float64", + "q_lv_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_hv_ka": "float64", + "i_mv_ka": "float64", + "i_lv_ka": "float64", + "vm_hv_pu": "float64", + "va_hv_degree": "float64", + "vm_mv_pu": "float64", + "va_mv_degree": "float64", + "vm_lv_pu": "float64", + "va_lv_degree": "float64", + "va_internal_degree": "float64", + "vm_internal_pu": "float64", + "loading_percent": "float64" + }, + "orient": "split" + }, + "res_impedance": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_from_mw\",\"q_from_mvar\",\"p_to_mw\",\"q_to_mvar\",\"pl_mw\",\"ql_mvar\",\"i_from_ka\",\"i_to_ka\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_from_mw": "float64", + "q_from_mvar": "float64", + "p_to_mw": "float64", + "q_to_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_from_ka": "float64", + "i_to_ka": "float64" + }, + "orient": "split" + }, + "res_ext_grid": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + }, + "orient": "split" + }, + "res_load": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[0,1,2],\"data\":[[10.0,7.0],[10.0,7.0],[10.0,7.0]]}", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + }, + "orient": "split" + }, + "res_sgen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + }, + "orient": "split" + }, + "res_storage": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + }, + "orient": "split" + }, + "res_shunt": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\",\"vm_pu\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64", + "vm_pu": "float64" + }, + "orient": "split" + }, + "res_gen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\",\"va_degree\",\"vm_pu\"],\"index\":[0,1],\"data\":[[10.0,118.791243672370911,-0.845445168673926,1.02],[21.729831330858325,-116.839935541152954,0.0,1.02]]}", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64", + "va_degree": "float64", + "vm_pu": "float64" + }, + "orient": "split" + }, + "res_ward": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\",\"vm_pu\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64", + "vm_pu": "float64" + }, + "orient": "split" + }, + "res_xward": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\",\"vm_pu\",\"va_internal_degree\",\"vm_internal_pu\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64", + "vm_pu": "float64", + "va_internal_degree": "float64", + "vm_internal_pu": "float64" + }, + "orient": "split" + }, + "res_dcline": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_from_mw\",\"q_from_mvar\",\"p_to_mw\",\"q_to_mvar\",\"pl_mw\",\"vm_from_pu\",\"va_from_degree\",\"vm_to_pu\",\"va_to_degree\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_from_mw": "float64", + "q_from_mvar": "float64", + "p_to_mw": "float64", + "q_to_mvar": "float64", + "pl_mw": "float64", + "vm_from_pu": "float64", + "va_from_degree": "float64", + "vm_to_pu": "float64", + "va_to_degree": "float64" + }, + "orient": "split" + }, + "user_pf_options": {}, + "OPF_converged": false + } +} diff --git a/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/hazards.csv.bz2 b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/hazards.csv.bz2 new file mode 100644 index 00000000..5257b64d Binary files /dev/null and b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/hazards.csv.bz2 differ diff --git a/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/load_p.csv.bz2 b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/load_p.csv.bz2 new file mode 100644 index 00000000..df894b76 Binary files /dev/null and b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/load_p.csv.bz2 differ diff --git a/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/load_p_forecasted.csv.bz2 b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/load_p_forecasted.csv.bz2 new file mode 100644 index 00000000..d9123622 Binary files /dev/null and b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/load_p_forecasted.csv.bz2 differ diff --git a/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/load_q.csv.bz2 b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/load_q.csv.bz2 new file mode 100644 index 00000000..d401840a Binary files /dev/null and b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/load_q.csv.bz2 differ diff --git a/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/load_q_forecasted.csv.bz2 b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/load_q_forecasted.csv.bz2 new file mode 100644 index 00000000..494dcd68 Binary files /dev/null and b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/load_q_forecasted.csv.bz2 differ diff --git a/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/maintenance.csv.bz2 b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/maintenance.csv.bz2 new file mode 100644 index 00000000..5257b64d Binary files /dev/null and b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/maintenance.csv.bz2 differ diff --git a/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/maintenance_forecasted.csv.bz2 b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/maintenance_forecasted.csv.bz2 new file mode 100644 index 00000000..5257b64d Binary files /dev/null and b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/maintenance_forecasted.csv.bz2 differ diff --git a/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/maintenance_meta.json b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/maintenance_meta.json new file mode 100644 index 00000000..e6faa8ec --- /dev/null +++ b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/maintenance_meta.json @@ -0,0 +1,7 @@ +{ + "maintenance_starting_hour": 9 , + "maintenance_ending_hour": 17, + "line_to_maintenance": ["0_1_0", "2_3_5"], + "daily_proba_per_month_maintenance": [0.0, 0.0, 0.0, 0.02, 0.02, 0.03, 0.05, 0.06, 0.03, 0.02, 0.0, 0.0], + "max_daily_number_per_month_maintenance": [0, 0, 0, 1, 1, 2, 2, 2, 1, 1, 0, 0] +} diff --git a/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/prod_p.csv.bz2 b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/prod_p.csv.bz2 new file mode 100644 index 00000000..45ae98a8 Binary files /dev/null and b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/prod_p.csv.bz2 differ diff --git a/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/prod_p_forecasted.csv.bz2 b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/prod_p_forecasted.csv.bz2 new file mode 100644 index 00000000..555c0fdd Binary files /dev/null and b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/prod_p_forecasted.csv.bz2 differ diff --git a/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/prod_v.csv.bz2 b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/prod_v.csv.bz2 new file mode 100644 index 00000000..9fde13d8 Binary files /dev/null and b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/prod_v.csv.bz2 differ diff --git a/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/prod_v_forecasted.csv.bz2 b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/prod_v_forecasted.csv.bz2 new file mode 100644 index 00000000..c685c39c Binary files /dev/null and b/grid2op/data_test/5bus_example_disco_el_in_grid/chronics/0/prod_v_forecasted.csv.bz2 differ diff --git a/grid2op/data_test/5bus_example_disco_el_in_grid/config.py b/grid2op/data_test/5bus_example_disco_el_in_grid/config.py new file mode 100644 index 00000000..1ec901a0 --- /dev/null +++ b/grid2op/data_test/5bus_example_disco_el_in_grid/config.py @@ -0,0 +1,19 @@ +from grid2op.Action import TopologyAction +from grid2op.Reward import L2RPNReward +from grid2op.Rules import DefaultRules +from grid2op.Chronics import Multifolder +from grid2op.Chronics import GridStateFromFileWithForecasts +from grid2op.Backend import PandaPowerBackend + +config = { + "backend": PandaPowerBackend, + "action_class": TopologyAction, + "observation_class": None, + "reward_class": L2RPNReward, + "gamerules_class": DefaultRules, + "chronics_class": Multifolder, + "grid_value_class": GridStateFromFileWithForecasts, + "volagecontroler_class": None, + "thermal_limits": None, + "names_chronics_to_grid": None, +} diff --git a/grid2op/data_test/5bus_example_disco_el_in_grid/grid.json b/grid2op/data_test/5bus_example_disco_el_in_grid/grid.json new file mode 100644 index 00000000..b8360012 --- /dev/null +++ b/grid2op/data_test/5bus_example_disco_el_in_grid/grid.json @@ -0,0 +1,1772 @@ +{ + "_module": "pandapower.auxiliary", + "_class": "pandapowerNet", + "_object": { + "bus": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"vn_kv\",\"type\",\"zone\",\"in_service\"],\"index\":[0,1,2,3,4],\"data\":[[\"substation_1\",100.0,\"b\",null,true],[\"substation_2\",100.0,\"b\",null,true],[\"substation_3\",100.0,\"b\",null,true],[\"substation_4\",100.0,\"b\",null,true],[\"substation_5\",100.0,\"b\",null,true]]}", + "orient": "split", + "dtype": { + "name": "object", + "vn_kv": "float64", + "type": "object", + "zone": "object", + "in_service": "bool" + } + }, + "load": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_mw\",\"q_mvar\",\"const_z_percent\",\"const_i_percent\",\"sn_mva\",\"scaling\",\"in_service\",\"type\"],\"index\":[0,1,2],\"data\":[[\"load_0_0\",0,10.0,7.0,0.0,0.0,null,1.0,true,null],[\"load_3_1\",3,10.0,7.0,0.0,0.0,null,1.0,true,null],[\"load_4_2\",4,10.0,7.0,0.0,0.0,null,1.0,true,null]]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "uint32", + "p_mw": "float64", + "q_mvar": "float64", + "const_z_percent": "float64", + "const_i_percent": "float64", + "sn_mva": "float64", + "scaling": "float64", + "in_service": "bool", + "type": "object" + } + }, + "sgen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_mw\",\"q_mvar\",\"sn_mva\",\"scaling\",\"in_service\",\"type\",\"current_source\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "int64", + "p_mw": "float64", + "q_mvar": "float64", + "sn_mva": "float64", + "scaling": "float64", + "in_service": "bool", + "type": "object", + "current_source": "bool" + } + }, + "motor": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"pn_mech_mw\",\"loading_percent\",\"cos_phi\",\"cos_phi_n\",\"efficiency_percent\",\"efficiency_n_percent\",\"lrc_pu\",\"vn_kv\",\"scaling\",\"in_service\",\"rx\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "int64", + "pn_mech_mw": "float64", + "loading_percent": "float64", + "cos_phi": "float64", + "cos_phi_n": "float64", + "efficiency_percent": "float64", + "efficiency_n_percent": "float64", + "lrc_pu": "float64", + "vn_kv": "float64", + "scaling": "float64", + "in_service": "bool", + "rx": "float64" + } + }, + "asymmetric_load": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_a_mw\",\"q_a_mvar\",\"p_b_mw\",\"q_b_mvar\",\"p_c_mw\",\"q_c_mvar\",\"sn_mva\",\"scaling\",\"in_service\",\"type\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "uint32", + "p_a_mw": "float64", + "q_a_mvar": "float64", + "p_b_mw": "float64", + "q_b_mvar": "float64", + "p_c_mw": "float64", + "q_c_mvar": "float64", + "sn_mva": "float64", + "scaling": "float64", + "in_service": "bool", + "type": "object" + } + }, + "asymmetric_sgen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_a_mw\",\"q_a_mvar\",\"p_b_mw\",\"q_b_mvar\",\"p_c_mw\",\"q_c_mvar\",\"sn_mva\",\"scaling\",\"in_service\",\"type\",\"current_source\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "int64", + "p_a_mw": "float64", + "q_a_mvar": "float64", + "p_b_mw": "float64", + "q_b_mvar": "float64", + "p_c_mw": "float64", + "q_c_mvar": "float64", + "sn_mva": "float64", + "scaling": "float64", + "in_service": "bool", + "type": "object", + "current_source": "bool" + } + }, + "storage": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_mw\",\"q_mvar\",\"sn_mva\",\"soc_percent\",\"min_e_mwh\",\"max_e_mwh\",\"scaling\",\"in_service\",\"type\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "int64", + "p_mw": "float64", + "q_mvar": "float64", + "sn_mva": "float64", + "soc_percent": "float64", + "min_e_mwh": "float64", + "max_e_mwh": "float64", + "scaling": "float64", + "in_service": "bool", + "type": "object" + } + }, + "gen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_mw\",\"vm_pu\",\"sn_mva\",\"min_q_mvar\",\"max_q_mvar\",\"scaling\",\"slack\",\"in_service\",\"type\",\"slack_weight\"],\"index\":[0,1],\"data\":[[\"gen_0_0\",0,10.0,1.02,null,null,null,1.0,false,true,null,0.0],[\"gen_1_1\",1,20.0,1.02,null,null,null,1.0,true,true,null,1.0]]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "uint32", + "p_mw": "float64", + "vm_pu": "float64", + "sn_mva": "float64", + "min_q_mvar": "float64", + "max_q_mvar": "float64", + "scaling": "float64", + "slack": "bool", + "in_service": "bool", + "type": "object", + "slack_weight": "float64" + } + }, + "switch": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"bus\",\"element\",\"et\",\"type\",\"closed\",\"name\",\"z_ohm\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "bus": "int64", + "element": "int64", + "et": "object", + "type": "object", + "closed": "bool", + "name": "object", + "z_ohm": "float64" + } + }, + "shunt": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"bus\",\"name\",\"q_mvar\",\"p_mw\",\"vn_kv\",\"step\",\"max_step\",\"in_service\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "bus": "uint32", + "name": "object", + "q_mvar": "float64", + "p_mw": "float64", + "vn_kv": "float64", + "step": "uint32", + "max_step": "uint32", + "in_service": "bool" + } + }, + "ext_grid": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"vm_pu\",\"va_degree\",\"in_service\",\"slack_weight\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "uint32", + "vm_pu": "float64", + "va_degree": "float64", + "in_service": "bool", + "slack_weight": "float64" + } + }, + "line": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"std_type\",\"from_bus\",\"to_bus\",\"length_km\",\"r_ohm_per_km\",\"x_ohm_per_km\",\"c_nf_per_km\",\"g_us_per_km\",\"max_i_ka\",\"df\",\"parallel\",\"type\",\"in_service\"],\"index\":[0,1,2,3,4,5,6,7],\"data\":[[null,\"NAYY 4x50 SE\",0,1,4.0,0.642,0.083,210.0,0.0,0.6,1.0,1,\"cs\",true],[\"0_2_2\",\"NAYY 4x50 SE\",0,2,4.47,0.642,0.083,210.0,0.0,0.22,1.0,1,\"cs\",true],[\"0_3_3\",\"NAYY 4x50 SE\",0,3,5.65,0.642,0.083,210.0,0.0,0.16,1.0,1,\"cs\",false],[\"0_4_4\",\"NAYY 4x50 SE\",0,4,4.0,0.642,0.083,210.0,0.0,0.16,1.0,1,\"cs\",true],[\"1_2_5\",\"NAYY 4x50 SE\",1,2,2.0,0.642,0.083,210.0,0.0,0.6,1.0,1,\"cs\",true],[\"2_3_6\",\"NAYY 4x50 SE\",2,3,2.0,0.642,0.083,210.0,0.0,0.3,1.0,1,\"cs\",true],[\"2_3_7\",\"NAYY 4x50 SE\",2,3,2.0,0.642,0.083,210.0,0.0,0.3,1.0,1,\"cs\",true],[\"3_4_8\",\"NAYY 4x50 SE\",3,4,4.0,0.642,0.083,210.0,0.0,0.16,1.0,1,\"cs\",true]]}", + "orient": "split", + "dtype": { + "name": "object", + "std_type": "object", + "from_bus": "uint32", + "to_bus": "uint32", + "length_km": "float64", + "r_ohm_per_km": "float64", + "x_ohm_per_km": "float64", + "c_nf_per_km": "float64", + "g_us_per_km": "float64", + "max_i_ka": "float64", + "df": "float64", + "parallel": "uint32", + "type": "object", + "in_service": "bool" + } + }, + "trafo": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"std_type\",\"hv_bus\",\"lv_bus\",\"sn_mva\",\"vn_hv_kv\",\"vn_lv_kv\",\"vk_percent\",\"vkr_percent\",\"pfe_kw\",\"i0_percent\",\"shift_degree\",\"tap_side\",\"tap_neutral\",\"tap_min\",\"tap_max\",\"tap_step_percent\",\"tap_step_degree\",\"tap_pos\",\"tap_phase_shifter\",\"parallel\",\"df\",\"in_service\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "std_type": "object", + "hv_bus": "uint32", + "lv_bus": "uint32", + "sn_mva": "float64", + "vn_hv_kv": "float64", + "vn_lv_kv": "float64", + "vk_percent": "float64", + "vkr_percent": "float64", + "pfe_kw": "float64", + "i0_percent": "float64", + "shift_degree": "float64", + "tap_side": "object", + "tap_neutral": "int32", + "tap_min": "int32", + "tap_max": "int32", + "tap_step_percent": "float64", + "tap_step_degree": "float64", + "tap_pos": "int32", + "tap_phase_shifter": "bool", + "parallel": "uint32", + "df": "float64", + "in_service": "bool" + } + }, + "trafo3w": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"std_type\",\"hv_bus\",\"mv_bus\",\"lv_bus\",\"sn_hv_mva\",\"sn_mv_mva\",\"sn_lv_mva\",\"vn_hv_kv\",\"vn_mv_kv\",\"vn_lv_kv\",\"vk_hv_percent\",\"vk_mv_percent\",\"vk_lv_percent\",\"vkr_hv_percent\",\"vkr_mv_percent\",\"vkr_lv_percent\",\"pfe_kw\",\"i0_percent\",\"shift_mv_degree\",\"shift_lv_degree\",\"tap_side\",\"tap_neutral\",\"tap_min\",\"tap_max\",\"tap_step_percent\",\"tap_step_degree\",\"tap_pos\",\"tap_at_star_point\",\"in_service\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "std_type": "object", + "hv_bus": "uint32", + "mv_bus": "uint32", + "lv_bus": "uint32", + "sn_hv_mva": "float64", + "sn_mv_mva": "float64", + "sn_lv_mva": "float64", + "vn_hv_kv": "float64", + "vn_mv_kv": "float64", + "vn_lv_kv": "float64", + "vk_hv_percent": "float64", + "vk_mv_percent": "float64", + "vk_lv_percent": "float64", + "vkr_hv_percent": "float64", + "vkr_mv_percent": "float64", + "vkr_lv_percent": "float64", + "pfe_kw": "float64", + "i0_percent": "float64", + "shift_mv_degree": "float64", + "shift_lv_degree": "float64", + "tap_side": "object", + "tap_neutral": "int32", + "tap_min": "int32", + "tap_max": "int32", + "tap_step_percent": "float64", + "tap_step_degree": "float64", + "tap_pos": "int32", + "tap_at_star_point": "bool", + "in_service": "bool" + } + }, + "impedance": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"from_bus\",\"to_bus\",\"rft_pu\",\"xft_pu\",\"rtf_pu\",\"xtf_pu\",\"sn_mva\",\"in_service\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "from_bus": "uint32", + "to_bus": "uint32", + "rft_pu": "float64", + "xft_pu": "float64", + "rtf_pu": "float64", + "xtf_pu": "float64", + "sn_mva": "float64", + "in_service": "bool" + } + }, + "dcline": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"from_bus\",\"to_bus\",\"p_mw\",\"loss_percent\",\"loss_mw\",\"vm_from_pu\",\"vm_to_pu\",\"max_p_mw\",\"min_q_from_mvar\",\"min_q_to_mvar\",\"max_q_from_mvar\",\"max_q_to_mvar\",\"in_service\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "from_bus": "uint32", + "to_bus": "uint32", + "p_mw": "float64", + "loss_percent": "float64", + "loss_mw": "float64", + "vm_from_pu": "float64", + "vm_to_pu": "float64", + "max_p_mw": "float64", + "min_q_from_mvar": "float64", + "min_q_to_mvar": "float64", + "max_q_from_mvar": "float64", + "max_q_to_mvar": "float64", + "in_service": "bool" + } + }, + "ward": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"ps_mw\",\"qs_mvar\",\"qz_mvar\",\"pz_mw\",\"in_service\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "uint32", + "ps_mw": "float64", + "qs_mvar": "float64", + "qz_mvar": "float64", + "pz_mw": "float64", + "in_service": "bool" + } + }, + "xward": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"ps_mw\",\"qs_mvar\",\"qz_mvar\",\"pz_mw\",\"r_ohm\",\"x_ohm\",\"vm_pu\",\"in_service\",\"slack_weight\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "uint32", + "ps_mw": "float64", + "qs_mvar": "float64", + "qz_mvar": "float64", + "pz_mw": "float64", + "r_ohm": "float64", + "x_ohm": "float64", + "vm_pu": "float64", + "in_service": "bool", + "slack_weight": "float64" + } + }, + "measurement": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"measurement_type\",\"element_type\",\"element\",\"value\",\"std_dev\",\"side\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "measurement_type": "object", + "element_type": "object", + "element": "uint32", + "value": "float64", + "std_dev": "float64", + "side": "object" + } + }, + "pwl_cost": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"power_type\",\"element\",\"et\",\"points\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "power_type": "object", + "element": "uint32", + "et": "object", + "points": "object" + } + }, + "poly_cost": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"element\",\"et\",\"cp0_eur\",\"cp1_eur_per_mw\",\"cp2_eur_per_mw2\",\"cq0_eur\",\"cq1_eur_per_mvar\",\"cq2_eur_per_mvar2\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "element": "uint32", + "et": "object", + "cp0_eur": "float64", + "cp1_eur_per_mw": "float64", + "cp2_eur_per_mw2": "float64", + "cq0_eur": "float64", + "cq1_eur_per_mvar": "float64", + "cq2_eur_per_mvar2": "float64" + } + }, + "characteristic": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"object\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "object": "object" + } + }, + "controller": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"object\",\"in_service\",\"order\",\"level\",\"initial_run\",\"recycle\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "object": "object", + "in_service": "bool", + "order": "float64", + "level": "object", + "initial_run": "bool", + "recycle": "object" + } + }, + "line_geodata": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"coords\"],\"index\":[0,1,2,3,4,5,6,7],\"data\":[[[[0,0],[0,4]]],[[[0,0],[2,4]]],[[[0,0],[4,4]]],[[[0,0],[4,0]]],[[[0,4],[2,4]]],[[[2,4],[3,4.2],[4,4]]],[[[2,4],[3,3.8],[4,4]]],[[[4,4],[4,0]]]]}", + "orient": "split", + "dtype": { + "coords": "object" + } + }, + "bus_geodata": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"x\",\"y\",\"coords\"],\"index\":[0,1,2,3,4],\"data\":[[0.0,0.0,null],[0.0,4.0,null],[2.0,4.0,null],[4.0,4.0,null],[4.0,0.0,null]]}", + "orient": "split", + "dtype": { + "x": "float64", + "y": "float64", + "coords": "object" + } + }, + "version": "2.8.0", + "converged": true, + "name": "5bus", + "f_hz": 50.0, + "sn_mva": 1, + "std_types": { + "line": { + "NAYY 4x50 SE": { + "c_nf_per_km": 210, + "r_ohm_per_km": 0.642, + "x_ohm_per_km": 0.083, + "max_i_ka": 0.142, + "type": "cs", + "q_mm2": 50, + "alpha": 0.00403 + }, + "NAYY 4x120 SE": { + "c_nf_per_km": 264, + "r_ohm_per_km": 0.225, + "x_ohm_per_km": 0.08, + "max_i_ka": 0.242, + "type": "cs", + "q_mm2": 120, + "alpha": 0.00403 + }, + "NAYY 4x150 SE": { + "c_nf_per_km": 261, + "r_ohm_per_km": 0.208, + "x_ohm_per_km": 0.08, + "max_i_ka": 0.27, + "type": "cs", + "q_mm2": 150, + "alpha": 0.00403 + }, + "NA2XS2Y 1x95 RM/25 12/20 kV": { + "c_nf_per_km": 216, + "r_ohm_per_km": 0.313, + "x_ohm_per_km": 0.132, + "max_i_ka": 0.252, + "type": "cs", + "q_mm2": 95, + "alpha": 0.00403 + }, + "NA2XS2Y 1x185 RM/25 12/20 kV": { + "c_nf_per_km": 273, + "r_ohm_per_km": 0.161, + "x_ohm_per_km": 0.117, + "max_i_ka": 0.362, + "type": "cs", + "q_mm2": 185, + "alpha": 0.00403 + }, + "NA2XS2Y 1x240 RM/25 12/20 kV": { + "c_nf_per_km": 304, + "r_ohm_per_km": 0.122, + "x_ohm_per_km": 0.112, + "max_i_ka": 0.421, + "type": "cs", + "q_mm2": 240, + "alpha": 0.00403 + }, + "NA2XS2Y 1x95 RM/25 6/10 kV": { + "c_nf_per_km": 315, + "r_ohm_per_km": 0.313, + "x_ohm_per_km": 0.123, + "max_i_ka": 0.249, + "type": "cs", + "q_mm2": 95, + "alpha": 0.00403 + }, + "NA2XS2Y 1x185 RM/25 6/10 kV": { + "c_nf_per_km": 406, + "r_ohm_per_km": 0.161, + "x_ohm_per_km": 0.11, + "max_i_ka": 0.358, + "type": "cs", + "q_mm2": 185, + "alpha": 0.00403 + }, + "NA2XS2Y 1x240 RM/25 6/10 kV": { + "c_nf_per_km": 456, + "r_ohm_per_km": 0.122, + "x_ohm_per_km": 0.105, + "max_i_ka": 0.416, + "type": "cs", + "q_mm2": 240, + "alpha": 0.00403 + }, + "NA2XS2Y 1x150 RM/25 12/20 kV": { + "c_nf_per_km": 250, + "r_ohm_per_km": 0.206, + "x_ohm_per_km": 0.116, + "max_i_ka": 0.319, + "type": "cs", + "q_mm2": 150, + "alpha": 0.00403 + }, + "NA2XS2Y 1x120 RM/25 12/20 kV": { + "c_nf_per_km": 230, + "r_ohm_per_km": 0.253, + "x_ohm_per_km": 0.119, + "max_i_ka": 0.283, + "type": "cs", + "q_mm2": 120, + "alpha": 0.00403 + }, + "NA2XS2Y 1x70 RM/25 12/20 kV": { + "c_nf_per_km": 190, + "r_ohm_per_km": 0.443, + "x_ohm_per_km": 0.132, + "max_i_ka": 0.22, + "type": "cs", + "q_mm2": 70, + "alpha": 0.00403 + }, + "NA2XS2Y 1x150 RM/25 6/10 kV": { + "c_nf_per_km": 360, + "r_ohm_per_km": 0.206, + "x_ohm_per_km": 0.11, + "max_i_ka": 0.315, + "type": "cs", + "q_mm2": 150, + "alpha": 0.00403 + }, + "NA2XS2Y 1x120 RM/25 6/10 kV": { + "c_nf_per_km": 340, + "r_ohm_per_km": 0.253, + "x_ohm_per_km": 0.113, + "max_i_ka": 0.28, + "type": "cs", + "q_mm2": 120, + "alpha": 0.00403 + }, + "NA2XS2Y 1x70 RM/25 6/10 kV": { + "c_nf_per_km": 280, + "r_ohm_per_km": 0.443, + "x_ohm_per_km": 0.123, + "max_i_ka": 0.217, + "type": "cs", + "q_mm2": 70, + "alpha": 0.00403 + }, + "N2XS(FL)2Y 1x120 RM/35 64/110 kV": { + "c_nf_per_km": 112, + "r_ohm_per_km": 0.153, + "x_ohm_per_km": 0.166, + "max_i_ka": 0.366, + "type": "cs", + "q_mm2": 120, + "alpha": 0.00393 + }, + "N2XS(FL)2Y 1x185 RM/35 64/110 kV": { + "c_nf_per_km": 125, + "r_ohm_per_km": 0.099, + "x_ohm_per_km": 0.156, + "max_i_ka": 0.457, + "type": "cs", + "q_mm2": 185, + "alpha": 0.00393 + }, + "N2XS(FL)2Y 1x240 RM/35 64/110 kV": { + "c_nf_per_km": 135, + "r_ohm_per_km": 0.075, + "x_ohm_per_km": 0.149, + "max_i_ka": 0.526, + "type": "cs", + "q_mm2": 240, + "alpha": 0.00393 + }, + "N2XS(FL)2Y 1x300 RM/35 64/110 kV": { + "c_nf_per_km": 144, + "r_ohm_per_km": 0.06, + "x_ohm_per_km": 0.144, + "max_i_ka": 0.588, + "type": "cs", + "q_mm2": 300, + "alpha": 0.00393 + }, + "15-AL1/3-ST1A 0.4": { + "c_nf_per_km": 11, + "r_ohm_per_km": 1.8769, + "x_ohm_per_km": 0.35, + "max_i_ka": 0.105, + "type": "ol", + "q_mm2": 16, + "alpha": 0.00403 + }, + "24-AL1/4-ST1A 0.4": { + "c_nf_per_km": 11.25, + "r_ohm_per_km": 1.2012, + "x_ohm_per_km": 0.335, + "max_i_ka": 0.14, + "type": "ol", + "q_mm2": 24, + "alpha": 0.00403 + }, + "48-AL1/8-ST1A 0.4": { + "c_nf_per_km": 12.2, + "r_ohm_per_km": 0.5939, + "x_ohm_per_km": 0.3, + "max_i_ka": 0.21, + "type": "ol", + "q_mm2": 48, + "alpha": 0.00403 + }, + "94-AL1/15-ST1A 0.4": { + "c_nf_per_km": 13.2, + "r_ohm_per_km": 0.306, + "x_ohm_per_km": 0.29, + "max_i_ka": 0.35, + "type": "ol", + "q_mm2": 94, + "alpha": 0.00403 + }, + "34-AL1/6-ST1A 10.0": { + "c_nf_per_km": 9.7, + "r_ohm_per_km": 0.8342, + "x_ohm_per_km": 0.36, + "max_i_ka": 0.17, + "type": "ol", + "q_mm2": 34, + "alpha": 0.00403 + }, + "48-AL1/8-ST1A 10.0": { + "c_nf_per_km": 10.1, + "r_ohm_per_km": 0.5939, + "x_ohm_per_km": 0.35, + "max_i_ka": 0.21, + "type": "ol", + "q_mm2": 48, + "alpha": 0.00403 + }, + "70-AL1/11-ST1A 10.0": { + "c_nf_per_km": 10.4, + "r_ohm_per_km": 0.4132, + "x_ohm_per_km": 0.339, + "max_i_ka": 0.29, + "type": "ol", + "q_mm2": 70, + "alpha": 0.00403 + }, + "94-AL1/15-ST1A 10.0": { + "c_nf_per_km": 10.75, + "r_ohm_per_km": 0.306, + "x_ohm_per_km": 0.33, + "max_i_ka": 0.35, + "type": "ol", + "q_mm2": 94, + "alpha": 0.00403 + }, + "122-AL1/20-ST1A 10.0": { + "c_nf_per_km": 11.1, + "r_ohm_per_km": 0.2376, + "x_ohm_per_km": 0.323, + "max_i_ka": 0.41, + "type": "ol", + "q_mm2": 122, + "alpha": 0.00403 + }, + "149-AL1/24-ST1A 10.0": { + "c_nf_per_km": 11.25, + "r_ohm_per_km": 0.194, + "x_ohm_per_km": 0.315, + "max_i_ka": 0.47, + "type": "ol", + "q_mm2": 149, + "alpha": 0.00403 + }, + "34-AL1/6-ST1A 20.0": { + "c_nf_per_km": 9.15, + "r_ohm_per_km": 0.8342, + "x_ohm_per_km": 0.382, + "max_i_ka": 0.17, + "type": "ol", + "q_mm2": 34, + "alpha": 0.00403 + }, + "48-AL1/8-ST1A 20.0": { + "c_nf_per_km": 9.5, + "r_ohm_per_km": 0.5939, + "x_ohm_per_km": 0.372, + "max_i_ka": 0.21, + "type": "ol", + "q_mm2": 48, + "alpha": 0.00403 + }, + "70-AL1/11-ST1A 20.0": { + "c_nf_per_km": 9.7, + "r_ohm_per_km": 0.4132, + "x_ohm_per_km": 0.36, + "max_i_ka": 0.29, + "type": "ol", + "q_mm2": 70, + "alpha": 0.00403 + }, + "94-AL1/15-ST1A 20.0": { + "c_nf_per_km": 10, + "r_ohm_per_km": 0.306, + "x_ohm_per_km": 0.35, + "max_i_ka": 0.35, + "type": "ol", + "q_mm2": 94, + "alpha": 0.00403 + }, + "122-AL1/20-ST1A 20.0": { + "c_nf_per_km": 10.3, + "r_ohm_per_km": 0.2376, + "x_ohm_per_km": 0.344, + "max_i_ka": 0.41, + "type": "ol", + "q_mm2": 122, + "alpha": 0.00403 + }, + "149-AL1/24-ST1A 20.0": { + "c_nf_per_km": 10.5, + "r_ohm_per_km": 0.194, + "x_ohm_per_km": 0.337, + "max_i_ka": 0.47, + "type": "ol", + "q_mm2": 149, + "alpha": 0.00403 + }, + "184-AL1/30-ST1A 20.0": { + "c_nf_per_km": 10.75, + "r_ohm_per_km": 0.1571, + "x_ohm_per_km": 0.33, + "max_i_ka": 0.535, + "type": "ol", + "q_mm2": 184, + "alpha": 0.00403 + }, + "243-AL1/39-ST1A 20.0": { + "c_nf_per_km": 11, + "r_ohm_per_km": 0.1188, + "x_ohm_per_km": 0.32, + "max_i_ka": 0.645, + "type": "ol", + "q_mm2": 243, + "alpha": 0.00403 + }, + "48-AL1/8-ST1A 110.0": { + "c_nf_per_km": 8, + "r_ohm_per_km": 0.5939, + "x_ohm_per_km": 0.46, + "max_i_ka": 0.21, + "type": "ol", + "q_mm2": 48, + "alpha": 0.00403 + }, + "70-AL1/11-ST1A 110.0": { + "c_nf_per_km": 8.4, + "r_ohm_per_km": 0.4132, + "x_ohm_per_km": 0.45, + "max_i_ka": 0.29, + "type": "ol", + "q_mm2": 70, + "alpha": 0.00403 + }, + "94-AL1/15-ST1A 110.0": { + "c_nf_per_km": 8.65, + "r_ohm_per_km": 0.306, + "x_ohm_per_km": 0.44, + "max_i_ka": 0.35, + "type": "ol", + "q_mm2": 94, + "alpha": 0.00403 + }, + "122-AL1/20-ST1A 110.0": { + "c_nf_per_km": 8.5, + "r_ohm_per_km": 0.2376, + "x_ohm_per_km": 0.43, + "max_i_ka": 0.41, + "type": "ol", + "q_mm2": 122, + "alpha": 0.00403 + }, + "149-AL1/24-ST1A 110.0": { + "c_nf_per_km": 8.75, + "r_ohm_per_km": 0.194, + "x_ohm_per_km": 0.41, + "max_i_ka": 0.47, + "type": "ol", + "q_mm2": 149, + "alpha": 0.00403 + }, + "184-AL1/30-ST1A 110.0": { + "c_nf_per_km": 8.8, + "r_ohm_per_km": 0.1571, + "x_ohm_per_km": 0.4, + "max_i_ka": 0.535, + "type": "ol", + "q_mm2": 184, + "alpha": 0.00403 + }, + "243-AL1/39-ST1A 110.0": { + "c_nf_per_km": 9, + "r_ohm_per_km": 0.1188, + "x_ohm_per_km": 0.39, + "max_i_ka": 0.645, + "type": "ol", + "q_mm2": 243, + "alpha": 0.00403 + }, + "305-AL1/39-ST1A 110.0": { + "c_nf_per_km": 9.2, + "r_ohm_per_km": 0.0949, + "x_ohm_per_km": 0.38, + "max_i_ka": 0.74, + "type": "ol", + "q_mm2": 305, + "alpha": 0.00403 + }, + "490-AL1/64-ST1A 110.0": { + "c_nf_per_km": 9.75, + "r_ohm_per_km": 0.059, + "x_ohm_per_km": 0.37, + "max_i_ka": 0.96, + "type": "ol", + "q_mm2": 490, + "alpha": 0.00403 + }, + "679-AL1/86-ST1A 110.0": { + "c_nf_per_km": 9.95, + "r_ohm_per_km": 0.042, + "x_ohm_per_km": 0.36, + "max_i_ka": 0.115, + "type": "ol", + "q_mm2": 679, + "alpha": 0.00403 + }, + "490-AL1/64-ST1A 220.0": { + "c_nf_per_km": 10, + "r_ohm_per_km": 0.059, + "x_ohm_per_km": 0.285, + "max_i_ka": 0.96, + "type": "ol", + "q_mm2": 490, + "alpha": 0.00403 + }, + "679-AL1/86-ST1A 220.0": { + "c_nf_per_km": 11.7, + "r_ohm_per_km": 0.042, + "x_ohm_per_km": 0.275, + "max_i_ka": 0.115, + "type": "ol", + "q_mm2": 679, + "alpha": 0.00403 + }, + "490-AL1/64-ST1A 380.0": { + "c_nf_per_km": 11, + "r_ohm_per_km": 0.059, + "x_ohm_per_km": 0.253, + "max_i_ka": 0.96, + "type": "ol", + "q_mm2": 490, + "alpha": 0.00403 + }, + "679-AL1/86-ST1A 380.0": { + "c_nf_per_km": 14.6, + "r_ohm_per_km": 0.042, + "x_ohm_per_km": 0.25, + "max_i_ka": 0.115, + "type": "ol", + "q_mm2": 679, + "alpha": 0.00403 + } + }, + "trafo": { + "160 MVA 380/110 kV": { + "i0_percent": 0.06, + "pfe_kw": 60, + "vkr_percent": 0.25, + "sn_mva": 160, + "vn_lv_kv": 110.0, + "vn_hv_kv": 380.0, + "vk_percent": 12.2, + "shift_degree": 0, + "vector_group": "Yy0", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "100 MVA 220/110 kV": { + "i0_percent": 0.06, + "pfe_kw": 55, + "vkr_percent": 0.26, + "sn_mva": 100, + "vn_lv_kv": 110.0, + "vn_hv_kv": 220.0, + "vk_percent": 12.0, + "shift_degree": 0, + "vector_group": "Yy0", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "63 MVA 110/20 kV": { + "i0_percent": 0.04, + "pfe_kw": 22, + "vkr_percent": 0.32, + "sn_mva": 63, + "vn_lv_kv": 20.0, + "vn_hv_kv": 110.0, + "vk_percent": 18, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "40 MVA 110/20 kV": { + "i0_percent": 0.05, + "pfe_kw": 18, + "vkr_percent": 0.34, + "sn_mva": 40, + "vn_lv_kv": 20.0, + "vn_hv_kv": 110.0, + "vk_percent": 16.2, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "25 MVA 110/20 kV": { + "i0_percent": 0.07, + "pfe_kw": 14, + "vkr_percent": 0.41, + "sn_mva": 25, + "vn_lv_kv": 20.0, + "vn_hv_kv": 110.0, + "vk_percent": 12, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "63 MVA 110/10 kV": { + "sn_mva": 63, + "vn_hv_kv": 110, + "vn_lv_kv": 10, + "vk_percent": 18, + "vkr_percent": 0.32, + "pfe_kw": 22, + "i0_percent": 0.04, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "40 MVA 110/10 kV": { + "sn_mva": 40, + "vn_hv_kv": 110, + "vn_lv_kv": 10, + "vk_percent": 16.2, + "vkr_percent": 0.34, + "pfe_kw": 18, + "i0_percent": 0.05, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "25 MVA 110/10 kV": { + "sn_mva": 25, + "vn_hv_kv": 110, + "vn_lv_kv": 10, + "vk_percent": 12, + "vkr_percent": 0.41, + "pfe_kw": 14, + "i0_percent": 0.07, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "0.25 MVA 20/0.4 kV": { + "sn_mva": 0.25, + "vn_hv_kv": 20, + "vn_lv_kv": 0.4, + "vk_percent": 6, + "vkr_percent": 1.44, + "pfe_kw": 0.8, + "i0_percent": 0.32, + "shift_degree": 150, + "vector_group": "Yzn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.4 MVA 20/0.4 kV": { + "sn_mva": 0.4, + "vn_hv_kv": 20, + "vn_lv_kv": 0.4, + "vk_percent": 6, + "vkr_percent": 1.425, + "pfe_kw": 1.35, + "i0_percent": 0.3375, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.63 MVA 20/0.4 kV": { + "sn_mva": 0.63, + "vn_hv_kv": 20, + "vn_lv_kv": 0.4, + "vk_percent": 6, + "vkr_percent": 1.206, + "pfe_kw": 1.65, + "i0_percent": 0.2619, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.25 MVA 10/0.4 kV": { + "sn_mva": 0.25, + "vn_hv_kv": 10, + "vn_lv_kv": 0.4, + "vk_percent": 4, + "vkr_percent": 1.2, + "pfe_kw": 0.6, + "i0_percent": 0.24, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.4 MVA 10/0.4 kV": { + "sn_mva": 0.4, + "vn_hv_kv": 10, + "vn_lv_kv": 0.4, + "vk_percent": 4, + "vkr_percent": 1.325, + "pfe_kw": 0.95, + "i0_percent": 0.2375, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.63 MVA 10/0.4 kV": { + "sn_mva": 0.63, + "vn_hv_kv": 10, + "vn_lv_kv": 0.4, + "vk_percent": 4, + "vkr_percent": 1.0794, + "pfe_kw": 1.18, + "i0_percent": 0.1873, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + } + }, + "trafo3w": { + "63/25/38 MVA 110/20/10 kV": { + "sn_hv_mva": 63, + "sn_mv_mva": 25, + "sn_lv_mva": 38, + "vn_hv_kv": 110, + "vn_mv_kv": 20, + "vn_lv_kv": 10, + "vk_hv_percent": 10.4, + "vk_mv_percent": 10.4, + "vk_lv_percent": 10.4, + "vkr_hv_percent": 0.28, + "vkr_mv_percent": 0.32, + "vkr_lv_percent": 0.35, + "pfe_kw": 35, + "i0_percent": 0.89, + "shift_mv_degree": 0, + "shift_lv_degree": 0, + "vector_group": "YN0yn0yn0", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -10, + "tap_max": 10, + "tap_step_percent": 1.2 + }, + "63/25/38 MVA 110/10/10 kV": { + "sn_hv_mva": 63, + "sn_mv_mva": 25, + "sn_lv_mva": 38, + "vn_hv_kv": 110, + "vn_mv_kv": 10, + "vn_lv_kv": 10, + "vk_hv_percent": 10.4, + "vk_mv_percent": 10.4, + "vk_lv_percent": 10.4, + "vkr_hv_percent": 0.28, + "vkr_mv_percent": 0.32, + "vkr_lv_percent": 0.35, + "pfe_kw": 35, + "i0_percent": 0.89, + "shift_mv_degree": 0, + "shift_lv_degree": 0, + "vector_group": "YN0yn0yn0", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -10, + "tap_max": 10, + "tap_step_percent": 1.2 + } + } + }, + "res_bus": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"vm_pu\",\"va_degree\",\"p_mw\",\"q_mvar\"],\"index\":[0,1,2,3,4],\"data\":[[1.02,-0.845445168673926,0.0,-111.791243672370911],[1.02,0.0,-21.729831330858325,116.839935541152954],[1.019214100496144,-0.409103297622625,0.0,0.0],[1.018637116919488,-0.503470352662766,10.0,7.0],[1.017983079721402,-0.653497665026562,10.0,7.0]]}", + "orient": "split", + "dtype": { + "vm_pu": "float64", + "va_degree": "float64", + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_line": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_from_mw\",\"q_from_mvar\",\"p_to_mw\",\"q_to_mvar\",\"pl_mw\",\"ql_mvar\",\"i_from_ka\",\"i_to_ka\",\"i_ka\",\"vm_from_pu\",\"va_from_degree\",\"vm_to_pu\",\"va_to_degree\",\"loading_percent\"],\"index\":[0,1,2,3,4,5,6,7],\"data\":[[-7.167647147657727,57.480079867900443,8.03525639977348,-60.113463233922118,0.867609252115754,-2.633383366021676,0.327874112511858,0.343286326507116,0.343286326507116,1.02,-0.845445168673926,1.02,0.0,57.214387751185988],[-0.657313913963437,25.969126903729045,0.866078469150186,-29.007927174007612,0.208764555186749,-3.038800270278568,0.147040043868819,0.164393305610081,0.164393305610081,1.02,-0.845445168673926,1.019214100496144,-0.409103297622625,74.724229822763931],[1.64566972119938,15.370129751576128,-1.540268914180618,-19.229415550834709,0.105400807018762,-3.859285799258581,0.087496748884432,0.109338903896103,0.109338903896103,1.02,-0.845445168673926,1.018637116919488,-0.503470352662766,68.336814935064211],[6.179291340421495,12.971907266349552,-6.119076735247816,-15.70424981919658,0.060214605173678,-2.732342552847028,0.081330018729726,0.095589209712924,0.095589209712924,1.02,-0.845445168673926,1.017983079721402,-0.653497665026562,59.743256070577175],[13.694574931085771,-56.726472302863066,-13.283848894885464,55.407854241119566,0.410726036200307,-1.3186180617435,0.330312825878128,0.322760996590474,0.330312825878128,1.02,0.0,1.019214100496144,-0.409103297622625,55.052137646354595],[6.208885212872048,-13.199963533555254,-6.184761786109662,11.833197159642042,0.024123426762386,-1.366766373913212,0.082632108556076,0.075677384410291,0.082632108556076,1.019214100496144,-0.409103297622625,1.018637116919488,-0.503470352662766,27.544036185358689],[6.208885212872048,-13.199963533555254,-6.184761786109662,11.833197159642042,0.024123426762386,-1.366766373913212,0.082632108556076,0.075677384410291,0.082632108556076,1.019214100496144,-0.409103297622625,1.018637116919488,-0.503470352662766,27.544036185358689],[3.909792486391969,-11.436978768449999,-3.88092326475316,8.704249819196738,0.028869221638809,-2.732728949253261,0.068506463438984,0.054050881891821,0.068506463438984,1.018637116919488,-0.503470352662766,1.017983079721402,-0.653497665026562,42.816539649365005]]}", + "orient": "split", + "dtype": { + "p_from_mw": "float64", + "q_from_mvar": "float64", + "p_to_mw": "float64", + "q_to_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_from_ka": "float64", + "i_to_ka": "float64", + "i_ka": "float64", + "vm_from_pu": "float64", + "va_from_degree": "float64", + "vm_to_pu": "float64", + "va_to_degree": "float64", + "loading_percent": "float64" + } + }, + "res_trafo": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_hv_mw\",\"q_hv_mvar\",\"p_lv_mw\",\"q_lv_mvar\",\"pl_mw\",\"ql_mvar\",\"i_hv_ka\",\"i_lv_ka\",\"vm_hv_pu\",\"va_hv_degree\",\"vm_lv_pu\",\"va_lv_degree\",\"loading_percent\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_hv_mw": "float64", + "q_hv_mvar": "float64", + "p_lv_mw": "float64", + "q_lv_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_hv_ka": "float64", + "i_lv_ka": "float64", + "vm_hv_pu": "float64", + "va_hv_degree": "float64", + "vm_lv_pu": "float64", + "va_lv_degree": "float64", + "loading_percent": "float64" + } + }, + "res_trafo3w": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_hv_mw\",\"q_hv_mvar\",\"p_mv_mw\",\"q_mv_mvar\",\"p_lv_mw\",\"q_lv_mvar\",\"pl_mw\",\"ql_mvar\",\"i_hv_ka\",\"i_mv_ka\",\"i_lv_ka\",\"vm_hv_pu\",\"va_hv_degree\",\"vm_mv_pu\",\"va_mv_degree\",\"vm_lv_pu\",\"va_lv_degree\",\"va_internal_degree\",\"vm_internal_pu\",\"loading_percent\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_hv_mw": "float64", + "q_hv_mvar": "float64", + "p_mv_mw": "float64", + "q_mv_mvar": "float64", + "p_lv_mw": "float64", + "q_lv_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_hv_ka": "float64", + "i_mv_ka": "float64", + "i_lv_ka": "float64", + "vm_hv_pu": "float64", + "va_hv_degree": "float64", + "vm_mv_pu": "float64", + "va_mv_degree": "float64", + "vm_lv_pu": "float64", + "va_lv_degree": "float64", + "va_internal_degree": "float64", + "vm_internal_pu": "float64", + "loading_percent": "float64" + } + }, + "res_impedance": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_from_mw\",\"q_from_mvar\",\"p_to_mw\",\"q_to_mvar\",\"pl_mw\",\"ql_mvar\",\"i_from_ka\",\"i_to_ka\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_from_mw": "float64", + "q_from_mvar": "float64", + "p_to_mw": "float64", + "q_to_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_from_ka": "float64", + "i_to_ka": "float64" + } + }, + "res_ext_grid": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_load": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[0,1,2],\"data\":[[10.0,7.0],[10.0,7.0],[10.0,7.0]]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_motor": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_sgen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_storage": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_shunt": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\",\"vm_pu\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64", + "vm_pu": "float64" + } + }, + "res_gen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\",\"va_degree\",\"vm_pu\"],\"index\":[0,1],\"data\":[[10.0,118.791243672370911,-0.845445168673926,1.02],[21.729831330858325,-116.839935541152954,0.0,1.02]]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64", + "va_degree": "float64", + "vm_pu": "float64" + } + }, + "res_ward": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\",\"vm_pu\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64", + "vm_pu": "float64" + } + }, + "res_xward": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\",\"vm_pu\",\"va_internal_degree\",\"vm_internal_pu\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64", + "vm_pu": "float64", + "va_internal_degree": "float64", + "vm_internal_pu": "float64" + } + }, + "res_dcline": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_from_mw\",\"q_from_mvar\",\"p_to_mw\",\"q_to_mvar\",\"pl_mw\",\"vm_from_pu\",\"va_from_degree\",\"vm_to_pu\",\"va_to_degree\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_from_mw": "float64", + "q_from_mvar": "float64", + "p_to_mw": "float64", + "q_to_mvar": "float64", + "pl_mw": "float64", + "vm_from_pu": "float64", + "va_from_degree": "float64", + "vm_to_pu": "float64", + "va_to_degree": "float64" + } + }, + "res_asymmetric_load": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_asymmetric_sgen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_bus_est": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"vm_pu\",\"va_degree\",\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "vm_pu": "float64", + "va_degree": "float64", + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_line_est": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_from_mw\",\"q_from_mvar\",\"p_to_mw\",\"q_to_mvar\",\"pl_mw\",\"ql_mvar\",\"i_from_ka\",\"i_to_ka\",\"i_ka\",\"vm_from_pu\",\"va_from_degree\",\"vm_to_pu\",\"va_to_degree\",\"loading_percent\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_from_mw": "float64", + "q_from_mvar": "float64", + "p_to_mw": "float64", + "q_to_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_from_ka": "float64", + "i_to_ka": "float64", + "i_ka": "float64", + "vm_from_pu": "float64", + "va_from_degree": "float64", + "vm_to_pu": "float64", + "va_to_degree": "float64", + "loading_percent": "float64" + } + }, + "res_trafo_est": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_hv_mw\",\"q_hv_mvar\",\"p_lv_mw\",\"q_lv_mvar\",\"pl_mw\",\"ql_mvar\",\"i_hv_ka\",\"i_lv_ka\",\"vm_hv_pu\",\"va_hv_degree\",\"vm_lv_pu\",\"va_lv_degree\",\"loading_percent\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_hv_mw": "float64", + "q_hv_mvar": "float64", + "p_lv_mw": "float64", + "q_lv_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_hv_ka": "float64", + "i_lv_ka": "float64", + "vm_hv_pu": "float64", + "va_hv_degree": "float64", + "vm_lv_pu": "float64", + "va_lv_degree": "float64", + "loading_percent": "float64" + } + }, + "res_trafo3w_est": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_hv_mw\",\"q_hv_mvar\",\"p_mv_mw\",\"q_mv_mvar\",\"p_lv_mw\",\"q_lv_mvar\",\"pl_mw\",\"ql_mvar\",\"i_hv_ka\",\"i_mv_ka\",\"i_lv_ka\",\"vm_hv_pu\",\"va_hv_degree\",\"vm_mv_pu\",\"va_mv_degree\",\"vm_lv_pu\",\"va_lv_degree\",\"va_internal_degree\",\"vm_internal_pu\",\"loading_percent\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_hv_mw": "float64", + "q_hv_mvar": "float64", + "p_mv_mw": "float64", + "q_mv_mvar": "float64", + "p_lv_mw": "float64", + "q_lv_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_hv_ka": "float64", + "i_mv_ka": "float64", + "i_lv_ka": "float64", + "vm_hv_pu": "float64", + "va_hv_degree": "float64", + "vm_mv_pu": "float64", + "va_mv_degree": "float64", + "vm_lv_pu": "float64", + "va_lv_degree": "float64", + "va_internal_degree": "float64", + "vm_internal_pu": "float64", + "loading_percent": "float64" + } + }, + "res_impedance_est": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_from_mw\",\"q_from_mvar\",\"p_to_mw\",\"q_to_mvar\",\"pl_mw\",\"ql_mvar\",\"i_from_ka\",\"i_to_ka\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_from_mw": "float64", + "q_from_mvar": "float64", + "p_to_mw": "float64", + "q_to_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_from_ka": "float64", + "i_to_ka": "float64" + } + }, + "res_bus_sc": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[],\"index\":[],\"data\":[]}", + "orient": "split" + }, + "res_line_sc": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[],\"index\":[],\"data\":[]}", + "orient": "split" + }, + "res_trafo_sc": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[],\"index\":[],\"data\":[]}", + "orient": "split" + }, + "res_trafo3w_sc": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[],\"index\":[],\"data\":[]}", + "orient": "split" + }, + "res_ext_grid_sc": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[],\"index\":[],\"data\":[]}", + "orient": "split" + }, + "res_gen_sc": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[],\"index\":[],\"data\":[]}", + "orient": "split" + }, + "res_sgen_sc": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[],\"index\":[],\"data\":[]}", + "orient": "split" + }, + "res_bus_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"vm_a_pu\",\"va_a_degree\",\"vm_b_pu\",\"va_b_degree\",\"vm_c_pu\",\"va_c_degree\",\"p_a_mw\",\"q_a_mvar\",\"p_b_mw\",\"q_b_mvar\",\"p_c_mw\",\"q_c_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "vm_a_pu": "float64", + "va_a_degree": "float64", + "vm_b_pu": "float64", + "va_b_degree": "float64", + "vm_c_pu": "float64", + "va_c_degree": "float64", + "p_a_mw": "float64", + "q_a_mvar": "float64", + "p_b_mw": "float64", + "q_b_mvar": "float64", + "p_c_mw": "float64", + "q_c_mvar": "float64" + } + }, + "res_line_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_a_from_mw\",\"q_a_from_mvar\",\"p_b_from_mw\",\"q_b_from_mvar\",\"q_c_from_mvar\",\"p_a_to_mw\",\"q_a_to_mvar\",\"p_b_to_mw\",\"q_b_to_mvar\",\"p_c_to_mw\",\"q_c_to_mvar\",\"p_a_l_mw\",\"q_a_l_mvar\",\"p_b_l_mw\",\"q_b_l_mvar\",\"p_c_l_mw\",\"q_c_l_mvar\",\"i_a_from_ka\",\"i_a_to_ka\",\"i_b_from_ka\",\"i_b_to_ka\",\"i_c_from_ka\",\"i_c_to_ka\",\"i_a_ka\",\"i_b_ka\",\"i_c_ka\",\"i_n_from_ka\",\"i_n_to_ka\",\"i_n_ka\",\"loading_a_percent\",\"loading_b_percent\",\"loading_c_percent\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_a_from_mw": "float64", + "q_a_from_mvar": "float64", + "p_b_from_mw": "float64", + "q_b_from_mvar": "float64", + "q_c_from_mvar": "float64", + "p_a_to_mw": "float64", + "q_a_to_mvar": "float64", + "p_b_to_mw": "float64", + "q_b_to_mvar": "float64", + "p_c_to_mw": "float64", + "q_c_to_mvar": "float64", + "p_a_l_mw": "float64", + "q_a_l_mvar": "float64", + "p_b_l_mw": "float64", + "q_b_l_mvar": "float64", + "p_c_l_mw": "float64", + "q_c_l_mvar": "float64", + "i_a_from_ka": "float64", + "i_a_to_ka": "float64", + "i_b_from_ka": "float64", + "i_b_to_ka": "float64", + "i_c_from_ka": "float64", + "i_c_to_ka": "float64", + "i_a_ka": "float64", + "i_b_ka": "float64", + "i_c_ka": "float64", + "i_n_from_ka": "float64", + "i_n_to_ka": "float64", + "i_n_ka": "float64", + "loading_a_percent": "float64", + "loading_b_percent": "float64", + "loading_c_percent": "float64" + } + }, + "res_trafo_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_a_hv_mw\",\"q_a_hv_mvar\",\"p_b_hv_mw\",\"q_b_hv_mvar\",\"p_c_hv_mw\",\"q_c_hv_mvar\",\"p_a_lv_mw\",\"q_a_lv_mvar\",\"p_b_lv_mw\",\"q_b_lv_mvar\",\"p_c_lv_mw\",\"q_c_lv_mvar\",\"p_a_l_mw\",\"q_a_l_mvar\",\"p_b_l_mw\",\"q_b_l_mvar\",\"p_c_l_mw\",\"q_c_l_mvar\",\"i_a_hv_ka\",\"i_a_lv_ka\",\"i_b_hv_ka\",\"i_b_lv_ka\",\"i_c_hv_ka\",\"i_c_lv_ka\",\"loading_a_percent\",\"loading_b_percent\",\"loading_c_percent\",\"loading_percent\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_a_hv_mw": "float64", + "q_a_hv_mvar": "float64", + "p_b_hv_mw": "float64", + "q_b_hv_mvar": "float64", + "p_c_hv_mw": "float64", + "q_c_hv_mvar": "float64", + "p_a_lv_mw": "float64", + "q_a_lv_mvar": "float64", + "p_b_lv_mw": "float64", + "q_b_lv_mvar": "float64", + "p_c_lv_mw": "float64", + "q_c_lv_mvar": "float64", + "p_a_l_mw": "float64", + "q_a_l_mvar": "float64", + "p_b_l_mw": "float64", + "q_b_l_mvar": "float64", + "p_c_l_mw": "float64", + "q_c_l_mvar": "float64", + "i_a_hv_ka": "float64", + "i_a_lv_ka": "float64", + "i_b_hv_ka": "float64", + "i_b_lv_ka": "float64", + "i_c_hv_ka": "float64", + "i_c_lv_ka": "float64", + "loading_a_percent": "float64", + "loading_b_percent": "float64", + "loading_c_percent": "float64", + "loading_percent": "float64" + } + }, + "res_ext_grid_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_a_mw\",\"q_a_mvar\",\"p_b_mw\",\"q_b_mvar\",\"p_c_mw\",\"q_c_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_a_mw": "float64", + "q_a_mvar": "float64", + "p_b_mw": "float64", + "q_b_mvar": "float64", + "p_c_mw": "float64", + "q_c_mvar": "float64" + } + }, + "res_shunt_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[],\"index\":[],\"data\":[]}", + "orient": "split" + }, + "res_load_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_sgen_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_storage_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_asymmetric_load_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_a_mw\",\"q_a_mvar\",\"p_b_mw\",\"q_b_mvar\",\"p_c_mw\",\"q_c_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_a_mw": "float64", + "q_a_mvar": "float64", + "p_b_mw": "float64", + "q_b_mvar": "float64", + "p_c_mw": "float64", + "q_c_mvar": "float64" + } + }, + "res_asymmetric_sgen_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_a_mw\",\"q_a_mvar\",\"p_b_mw\",\"q_b_mvar\",\"p_c_mw\",\"q_c_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_a_mw": "float64", + "q_a_mvar": "float64", + "p_b_mw": "float64", + "q_b_mvar": "float64", + "p_c_mw": "float64", + "q_c_mvar": "float64" + } + }, + "user_pf_options": {}, + "OPF_converged": false + } +} diff --git a/grid2op/data_test/5bus_example_disco_el_in_grid/prods_charac.csv b/grid2op/data_test/5bus_example_disco_el_in_grid/prods_charac.csv new file mode 100644 index 00000000..f47a9059 --- /dev/null +++ b/grid2op/data_test/5bus_example_disco_el_in_grid/prods_charac.csv @@ -0,0 +1,3 @@ +Pmax,Pmin,name,type,bus,max_ramp_up,max_ramp_down,min_up_time,min_down_time,marginal_cost,shut_down_cost,start_cost,x,y,V +15,0.0,gen_0_0,wind,5,0,0,0,0,0,0,0,0,0,102. +35,0.0,gen_1_1,thermal,0,15,15,4,4,70,1,2,0,400,102. \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/00/_parameters.json b/grid2op/data_test/runner_data/res_agent_1.12.3/00/_parameters.json new file mode 100644 index 00000000..733e6e8a --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.12.3/00/_parameters.json @@ -0,0 +1,26 @@ +{ + "ACTIVATE_STORAGE_LOSS": true, + "ALARM_BEST_TIME": 12, + "ALARM_WINDOW_SIZE": 12, + "ALERT_TIME_WINDOW": 12, + "ALLOW_DISPATCH_GEN_SWITCH_OFF": true, + "ENV_DC": false, + "ENV_DOES_REDISPATCHING": true, + "FORECAST_DC": false, + "HARD_OVERFLOW_THRESHOLD": 2.0, + "IGNORE_INITIAL_STATE_TIME_SERIE": 0, + "IGNORE_MIN_UP_DOWN_TIME": true, + "INIT_STORAGE_CAPACITY": 0.5, + "LIMIT_INFEASIBLE_CURTAILMENT_STORAGE_ACTION": false, + "MAX_LINE_STATUS_CHANGED": 1, + "MAX_SIMULATE_PER_EPISODE": -1, + "MAX_SIMULATE_PER_STEP": -1, + "MAX_SUB_CHANGED": 1, + "NB_TIMESTEP_COOLDOWN_LINE": 0, + "NB_TIMESTEP_COOLDOWN_SUB": 0, + "NB_TIMESTEP_OVERFLOW_ALLOWED": 2, + "NB_TIMESTEP_RECONNECTION": 10, + "NO_OVERFLOW_DISCONNECTION": false, + "SOFT_OVERFLOW_THRESHOLD": 1.0, + "STOP_EP_IF_GEN_BREAK_CONSTRAINTS": false +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/00/actions.npz b/grid2op/data_test/runner_data/res_agent_1.12.3/00/actions.npz new file mode 100644 index 00000000..f9916863 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.12.3/00/actions.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/00/agent_exec_times.npz b/grid2op/data_test/runner_data/res_agent_1.12.3/00/agent_exec_times.npz new file mode 100644 index 00000000..b67bb246 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.12.3/00/agent_exec_times.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/00/disc_lines_cascading_failure.npz b/grid2op/data_test/runner_data/res_agent_1.12.3/00/disc_lines_cascading_failure.npz new file mode 100644 index 00000000..1e155fc3 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.12.3/00/disc_lines_cascading_failure.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/00/env_modifications.npz b/grid2op/data_test/runner_data/res_agent_1.12.3/00/env_modifications.npz new file mode 100644 index 00000000..0ffcf852 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.12.3/00/env_modifications.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/00/episode_meta.json b/grid2op/data_test/runner_data/res_agent_1.12.3/00/episode_meta.json new file mode 100644 index 00000000..c5f02c09 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.12.3/00/episode_meta.json @@ -0,0 +1,11 @@ +{ + "agent_seed": null, + "backend_type": "PandaPowerBackend_rte_case5_examplePandaPowerBackend", + "chronics_max_timestep": "100", + "chronics_path": "/home/donnotben/Documents/grid2op/grid2op/data/rte_case5_example/chronics/00", + "cumulative_reward": 14.923386573791504, + "env_seed": null, + "env_type": "Environment_rte_case5_examplePandaPowerBackend", + "grid_path": "/home/donnotben/Documents/grid2op/grid2op/data/rte_case5_example/grid.json", + "nb_timestep_played": 4 +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/00/episode_times.json b/grid2op/data_test/runner_data/res_agent_1.12.3/00/episode_times.json new file mode 100644 index 00000000..d3d46862 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.12.3/00/episode_times.json @@ -0,0 +1,12 @@ +{ + "Agent": { + "total": 5.173299723537639e-05 + }, + "Env": { + "apply_act": 0.005063856951892376, + "observation_computation": 0.0016567599959671497, + "powerflow_computation": 0.06105741858482361, + "total": 0.06777803599834442 + }, + "total": 0.06871504700029618 +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/00/grid2op.info b/grid2op/data_test/runner_data/res_agent_1.12.3/00/grid2op.info new file mode 100644 index 00000000..47d0a3b4 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.12.3/00/grid2op.info @@ -0,0 +1,3 @@ +{ + "version": "1.12.3" +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/00/observations.npz b/grid2op/data_test/runner_data/res_agent_1.12.3/00/observations.npz new file mode 100644 index 00000000..9ad5e6ee Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.12.3/00/observations.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/00/opponent_attack.npz b/grid2op/data_test/runner_data/res_agent_1.12.3/00/opponent_attack.npz new file mode 100644 index 00000000..43189fed Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.12.3/00/opponent_attack.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/00/other_rewards.json b/grid2op/data_test/runner_data/res_agent_1.12.3/00/other_rewards.json new file mode 100644 index 00000000..99bb44b9 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.12.3/00/other_rewards.json @@ -0,0 +1,6 @@ +[ + {}, + {}, + {}, + {} +] \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/00/rewards.npz b/grid2op/data_test/runner_data/res_agent_1.12.3/00/rewards.npz new file mode 100644 index 00000000..9460c482 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.12.3/00/rewards.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/01/_parameters.json b/grid2op/data_test/runner_data/res_agent_1.12.3/01/_parameters.json new file mode 100644 index 00000000..733e6e8a --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.12.3/01/_parameters.json @@ -0,0 +1,26 @@ +{ + "ACTIVATE_STORAGE_LOSS": true, + "ALARM_BEST_TIME": 12, + "ALARM_WINDOW_SIZE": 12, + "ALERT_TIME_WINDOW": 12, + "ALLOW_DISPATCH_GEN_SWITCH_OFF": true, + "ENV_DC": false, + "ENV_DOES_REDISPATCHING": true, + "FORECAST_DC": false, + "HARD_OVERFLOW_THRESHOLD": 2.0, + "IGNORE_INITIAL_STATE_TIME_SERIE": 0, + "IGNORE_MIN_UP_DOWN_TIME": true, + "INIT_STORAGE_CAPACITY": 0.5, + "LIMIT_INFEASIBLE_CURTAILMENT_STORAGE_ACTION": false, + "MAX_LINE_STATUS_CHANGED": 1, + "MAX_SIMULATE_PER_EPISODE": -1, + "MAX_SIMULATE_PER_STEP": -1, + "MAX_SUB_CHANGED": 1, + "NB_TIMESTEP_COOLDOWN_LINE": 0, + "NB_TIMESTEP_COOLDOWN_SUB": 0, + "NB_TIMESTEP_OVERFLOW_ALLOWED": 2, + "NB_TIMESTEP_RECONNECTION": 10, + "NO_OVERFLOW_DISCONNECTION": false, + "SOFT_OVERFLOW_THRESHOLD": 1.0, + "STOP_EP_IF_GEN_BREAK_CONSTRAINTS": false +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/01/actions.npz b/grid2op/data_test/runner_data/res_agent_1.12.3/01/actions.npz new file mode 100644 index 00000000..f34a4819 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.12.3/01/actions.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/01/agent_exec_times.npz b/grid2op/data_test/runner_data/res_agent_1.12.3/01/agent_exec_times.npz new file mode 100644 index 00000000..cff127e0 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.12.3/01/agent_exec_times.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/01/disc_lines_cascading_failure.npz b/grid2op/data_test/runner_data/res_agent_1.12.3/01/disc_lines_cascading_failure.npz new file mode 100644 index 00000000..8829b9b7 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.12.3/01/disc_lines_cascading_failure.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/01/env_modifications.npz b/grid2op/data_test/runner_data/res_agent_1.12.3/01/env_modifications.npz new file mode 100644 index 00000000..df172ebf Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.12.3/01/env_modifications.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/01/episode_meta.json b/grid2op/data_test/runner_data/res_agent_1.12.3/01/episode_meta.json new file mode 100644 index 00000000..f90b9aef --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.12.3/01/episode_meta.json @@ -0,0 +1,11 @@ +{ + "agent_seed": null, + "backend_type": "PandaPowerBackend_rte_case5_examplePandaPowerBackend", + "chronics_max_timestep": "100", + "chronics_path": "/home/donnotben/Documents/grid2op/grid2op/data/rte_case5_example/chronics/01", + "cumulative_reward": 3.392332077026367, + "env_seed": null, + "env_type": "Environment_rte_case5_examplePandaPowerBackend", + "grid_path": "/home/donnotben/Documents/grid2op/grid2op/data/rte_case5_example/grid.json", + "nb_timestep_played": 2 +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/01/episode_times.json b/grid2op/data_test/runner_data/res_agent_1.12.3/01/episode_times.json new file mode 100644 index 00000000..3d3956c6 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.12.3/01/episode_times.json @@ -0,0 +1,12 @@ +{ + "Agent": { + "total": 2.542800211813301e-05 + }, + "Env": { + "apply_act": 0.002260413020849228, + "observation_computation": 0.0005414449842646718, + "powerflow_computation": 0.033623043447732925, + "total": 0.0364249013364315 + }, + "total": 0.03700649699749192 +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/01/grid2op.info b/grid2op/data_test/runner_data/res_agent_1.12.3/01/grid2op.info new file mode 100644 index 00000000..47d0a3b4 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.12.3/01/grid2op.info @@ -0,0 +1,3 @@ +{ + "version": "1.12.3" +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/01/observations.npz b/grid2op/data_test/runner_data/res_agent_1.12.3/01/observations.npz new file mode 100644 index 00000000..54183620 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.12.3/01/observations.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/01/opponent_attack.npz b/grid2op/data_test/runner_data/res_agent_1.12.3/01/opponent_attack.npz new file mode 100644 index 00000000..43189fed Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.12.3/01/opponent_attack.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/01/other_rewards.json b/grid2op/data_test/runner_data/res_agent_1.12.3/01/other_rewards.json new file mode 100644 index 00000000..a12aa787 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.12.3/01/other_rewards.json @@ -0,0 +1,4 @@ +[ + {}, + {} +] \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/01/rewards.npz b/grid2op/data_test/runner_data/res_agent_1.12.3/01/rewards.npz new file mode 100644 index 00000000..5c25514a Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.12.3/01/rewards.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/dict_action_space.json b/grid2op/data_test/runner_data/res_agent_1.12.3/dict_action_space.json new file mode 100644 index 00000000..a337920d --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.12.3/dict_action_space.json @@ -0,0 +1,221 @@ +{ + "_PATH_GRID_CLASSES": null, + "_init_subtype": "grid2op.Action.topologyAction.TopologyAction", + "alarms_area_lines": [], + "alarms_area_names": [], + "alarms_lines_area": {}, + "alertable_line_ids": [], + "alertable_line_names": [], + "assistant_warning_type": null, + "detachment_is_allowed": "False", + "dim_alarms": 0, + "dim_alerts": 0, + "env_name": "rte_case5_examplePandaPowerBackend", + "gen_cost_per_MW": [ + 0.0, + 70.0 + ], + "gen_max_ramp_down": [ + 0.0, + 10.0 + ], + "gen_max_ramp_up": [ + 0.0, + 10.0 + ], + "gen_min_downtime": [ + 0, + 4 + ], + "gen_min_uptime": [ + 0, + 4 + ], + "gen_pmax": [ + 10.0, + 30.0 + ], + "gen_pmin": [ + 0.0, + 0.0 + ], + "gen_pos_topo_vect": [ + 4, + 8 + ], + "gen_redispatchable": [ + false, + true + ], + "gen_renewable": [ + true, + false + ], + "gen_shutdown_cost": [ + 0.0, + 1.0 + ], + "gen_startup_cost": [ + 0.0, + 2.0 + ], + "gen_to_sub_pos": [ + 4, + 2 + ], + "gen_to_subid": [ + 0, + 1 + ], + "gen_type": [ + "wind", + "thermal" + ], + "glop_version": "1.12.0", + "grid_layout": { + "sub_0": [ + 0.0, + 0.0 + ], + "sub_1": [ + 0.0, + 400.0 + ], + "sub_2": [ + 200.0, + 400.0 + ], + "sub_3": [ + 400.0, + 400.0 + ], + "sub_4": [ + 400.0, + 0.0 + ] + }, + "line_ex_pos_topo_vect": [ + 6, + 9, + 13, + 18, + 10, + 14, + 15, + 19 + ], + "line_ex_to_sub_pos": [ + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1 + ], + "line_ex_to_subid": [ + 1, + 2, + 3, + 4, + 2, + 3, + 3, + 4 + ], + "line_or_pos_topo_vect": [ + 0, + 1, + 2, + 3, + 7, + 11, + 12, + 16 + ], + "line_or_to_sub_pos": [ + 0, + 1, + 2, + 3, + 1, + 2, + 3, + 3 + ], + "line_or_to_subid": [ + 0, + 0, + 0, + 0, + 1, + 2, + 2, + 3 + ], + "load_pos_topo_vect": [ + 5, + 17, + 20 + ], + "load_to_sub_pos": [ + 5, + 4, + 2 + ], + "load_to_subid": [ + 0, + 3, + 4 + ], + "n_busbar_per_sub": "2", + "name_gen": [ + "gen_0_0", + "gen_1_1" + ], + "name_line": [ + "0_1_0", + "0_2_1", + "0_3_2", + "0_4_3", + "1_2_4", + "2_3_5", + "2_3_6", + "3_4_7" + ], + "name_load": [ + "load_0_0", + "load_3_1", + "load_4_2" + ], + "name_shunt": [], + "name_storage": [], + "name_sub": [ + "sub_0", + "sub_1", + "sub_2", + "sub_3", + "sub_4" + ], + "shunt_to_subid": [], + "storage_Emax": [], + "storage_Emin": [], + "storage_charging_efficiency": [], + "storage_discharging_efficiency": [], + "storage_loss": [], + "storage_marginal_cost": [], + "storage_max_p_absorb": [], + "storage_max_p_prod": [], + "storage_pos_topo_vect": [], + "storage_to_sub_pos": [], + "storage_to_subid": [], + "storage_type": [], + "sub_info": [ + 6, + 3, + 4, + 5, + 3 + ] +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/dict_attack_space.json b/grid2op/data_test/runner_data/res_agent_1.12.3/dict_attack_space.json new file mode 100644 index 00000000..3bd04320 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.12.3/dict_attack_space.json @@ -0,0 +1,221 @@ +{ + "_PATH_GRID_CLASSES": null, + "_init_subtype": "grid2op.Action.dontAct.DontAct", + "alarms_area_lines": [], + "alarms_area_names": [], + "alarms_lines_area": {}, + "alertable_line_ids": [], + "alertable_line_names": [], + "assistant_warning_type": null, + "detachment_is_allowed": "False", + "dim_alarms": 0, + "dim_alerts": 0, + "env_name": "rte_case5_examplePandaPowerBackend", + "gen_cost_per_MW": [ + 0.0, + 70.0 + ], + "gen_max_ramp_down": [ + 0.0, + 10.0 + ], + "gen_max_ramp_up": [ + 0.0, + 10.0 + ], + "gen_min_downtime": [ + 0, + 4 + ], + "gen_min_uptime": [ + 0, + 4 + ], + "gen_pmax": [ + 10.0, + 30.0 + ], + "gen_pmin": [ + 0.0, + 0.0 + ], + "gen_pos_topo_vect": [ + 4, + 8 + ], + "gen_redispatchable": [ + false, + true + ], + "gen_renewable": [ + true, + false + ], + "gen_shutdown_cost": [ + 0.0, + 1.0 + ], + "gen_startup_cost": [ + 0.0, + 2.0 + ], + "gen_to_sub_pos": [ + 4, + 2 + ], + "gen_to_subid": [ + 0, + 1 + ], + "gen_type": [ + "wind", + "thermal" + ], + "glop_version": "1.12.0", + "grid_layout": { + "sub_0": [ + 0.0, + 0.0 + ], + "sub_1": [ + 0.0, + 400.0 + ], + "sub_2": [ + 200.0, + 400.0 + ], + "sub_3": [ + 400.0, + 400.0 + ], + "sub_4": [ + 400.0, + 0.0 + ] + }, + "line_ex_pos_topo_vect": [ + 6, + 9, + 13, + 18, + 10, + 14, + 15, + 19 + ], + "line_ex_to_sub_pos": [ + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1 + ], + "line_ex_to_subid": [ + 1, + 2, + 3, + 4, + 2, + 3, + 3, + 4 + ], + "line_or_pos_topo_vect": [ + 0, + 1, + 2, + 3, + 7, + 11, + 12, + 16 + ], + "line_or_to_sub_pos": [ + 0, + 1, + 2, + 3, + 1, + 2, + 3, + 3 + ], + "line_or_to_subid": [ + 0, + 0, + 0, + 0, + 1, + 2, + 2, + 3 + ], + "load_pos_topo_vect": [ + 5, + 17, + 20 + ], + "load_to_sub_pos": [ + 5, + 4, + 2 + ], + "load_to_subid": [ + 0, + 3, + 4 + ], + "n_busbar_per_sub": "2", + "name_gen": [ + "gen_0_0", + "gen_1_1" + ], + "name_line": [ + "0_1_0", + "0_2_1", + "0_3_2", + "0_4_3", + "1_2_4", + "2_3_5", + "2_3_6", + "3_4_7" + ], + "name_load": [ + "load_0_0", + "load_3_1", + "load_4_2" + ], + "name_shunt": [], + "name_storage": [], + "name_sub": [ + "sub_0", + "sub_1", + "sub_2", + "sub_3", + "sub_4" + ], + "shunt_to_subid": [], + "storage_Emax": [], + "storage_Emin": [], + "storage_charging_efficiency": [], + "storage_discharging_efficiency": [], + "storage_loss": [], + "storage_marginal_cost": [], + "storage_max_p_absorb": [], + "storage_max_p_prod": [], + "storage_pos_topo_vect": [], + "storage_to_sub_pos": [], + "storage_to_subid": [], + "storage_type": [], + "sub_info": [ + 6, + 3, + 4, + 5, + 3 + ] +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/dict_env_modification_space.json b/grid2op/data_test/runner_data/res_agent_1.12.3/dict_env_modification_space.json new file mode 100644 index 00000000..128c2a86 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.12.3/dict_env_modification_space.json @@ -0,0 +1,221 @@ +{ + "_PATH_GRID_CLASSES": null, + "_init_subtype": "grid2op.Action.completeAction.CompleteAction", + "alarms_area_lines": [], + "alarms_area_names": [], + "alarms_lines_area": {}, + "alertable_line_ids": [], + "alertable_line_names": [], + "assistant_warning_type": null, + "detachment_is_allowed": "False", + "dim_alarms": 0, + "dim_alerts": 0, + "env_name": "rte_case5_examplePandaPowerBackend", + "gen_cost_per_MW": [ + 0.0, + 70.0 + ], + "gen_max_ramp_down": [ + 0.0, + 10.0 + ], + "gen_max_ramp_up": [ + 0.0, + 10.0 + ], + "gen_min_downtime": [ + 0, + 4 + ], + "gen_min_uptime": [ + 0, + 4 + ], + "gen_pmax": [ + 10.0, + 30.0 + ], + "gen_pmin": [ + 0.0, + 0.0 + ], + "gen_pos_topo_vect": [ + 4, + 8 + ], + "gen_redispatchable": [ + false, + true + ], + "gen_renewable": [ + true, + false + ], + "gen_shutdown_cost": [ + 0.0, + 1.0 + ], + "gen_startup_cost": [ + 0.0, + 2.0 + ], + "gen_to_sub_pos": [ + 4, + 2 + ], + "gen_to_subid": [ + 0, + 1 + ], + "gen_type": [ + "wind", + "thermal" + ], + "glop_version": "1.12.0", + "grid_layout": { + "sub_0": [ + 0.0, + 0.0 + ], + "sub_1": [ + 0.0, + 400.0 + ], + "sub_2": [ + 200.0, + 400.0 + ], + "sub_3": [ + 400.0, + 400.0 + ], + "sub_4": [ + 400.0, + 0.0 + ] + }, + "line_ex_pos_topo_vect": [ + 6, + 9, + 13, + 18, + 10, + 14, + 15, + 19 + ], + "line_ex_to_sub_pos": [ + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1 + ], + "line_ex_to_subid": [ + 1, + 2, + 3, + 4, + 2, + 3, + 3, + 4 + ], + "line_or_pos_topo_vect": [ + 0, + 1, + 2, + 3, + 7, + 11, + 12, + 16 + ], + "line_or_to_sub_pos": [ + 0, + 1, + 2, + 3, + 1, + 2, + 3, + 3 + ], + "line_or_to_subid": [ + 0, + 0, + 0, + 0, + 1, + 2, + 2, + 3 + ], + "load_pos_topo_vect": [ + 5, + 17, + 20 + ], + "load_to_sub_pos": [ + 5, + 4, + 2 + ], + "load_to_subid": [ + 0, + 3, + 4 + ], + "n_busbar_per_sub": "2", + "name_gen": [ + "gen_0_0", + "gen_1_1" + ], + "name_line": [ + "0_1_0", + "0_2_1", + "0_3_2", + "0_4_3", + "1_2_4", + "2_3_5", + "2_3_6", + "3_4_7" + ], + "name_load": [ + "load_0_0", + "load_3_1", + "load_4_2" + ], + "name_shunt": [], + "name_storage": [], + "name_sub": [ + "sub_0", + "sub_1", + "sub_2", + "sub_3", + "sub_4" + ], + "shunt_to_subid": [], + "storage_Emax": [], + "storage_Emin": [], + "storage_charging_efficiency": [], + "storage_discharging_efficiency": [], + "storage_loss": [], + "storage_marginal_cost": [], + "storage_max_p_absorb": [], + "storage_max_p_prod": [], + "storage_pos_topo_vect": [], + "storage_to_sub_pos": [], + "storage_to_subid": [], + "storage_type": [], + "sub_info": [ + 6, + 3, + 4, + 5, + 3 + ] +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.12.3/dict_observation_space.json b/grid2op/data_test/runner_data/res_agent_1.12.3/dict_observation_space.json new file mode 100644 index 00000000..3fe1883a --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.12.3/dict_observation_space.json @@ -0,0 +1,221 @@ +{ + "_PATH_GRID_CLASSES": null, + "_init_subtype": "grid2op.Observation.completeObservation.CompleteObservation", + "alarms_area_lines": [], + "alarms_area_names": [], + "alarms_lines_area": {}, + "alertable_line_ids": [], + "alertable_line_names": [], + "assistant_warning_type": null, + "detachment_is_allowed": "False", + "dim_alarms": 0, + "dim_alerts": 0, + "env_name": "rte_case5_examplePandaPowerBackend", + "gen_cost_per_MW": [ + 0.0, + 70.0 + ], + "gen_max_ramp_down": [ + 0.0, + 10.0 + ], + "gen_max_ramp_up": [ + 0.0, + 10.0 + ], + "gen_min_downtime": [ + 0, + 4 + ], + "gen_min_uptime": [ + 0, + 4 + ], + "gen_pmax": [ + 10.0, + 30.0 + ], + "gen_pmin": [ + 0.0, + 0.0 + ], + "gen_pos_topo_vect": [ + 4, + 8 + ], + "gen_redispatchable": [ + false, + true + ], + "gen_renewable": [ + true, + false + ], + "gen_shutdown_cost": [ + 0.0, + 1.0 + ], + "gen_startup_cost": [ + 0.0, + 2.0 + ], + "gen_to_sub_pos": [ + 4, + 2 + ], + "gen_to_subid": [ + 0, + 1 + ], + "gen_type": [ + "wind", + "thermal" + ], + "glop_version": "1.12.0", + "grid_layout": { + "sub_0": [ + 0.0, + 0.0 + ], + "sub_1": [ + 0.0, + 400.0 + ], + "sub_2": [ + 200.0, + 400.0 + ], + "sub_3": [ + 400.0, + 400.0 + ], + "sub_4": [ + 400.0, + 0.0 + ] + }, + "line_ex_pos_topo_vect": [ + 6, + 9, + 13, + 18, + 10, + 14, + 15, + 19 + ], + "line_ex_to_sub_pos": [ + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1 + ], + "line_ex_to_subid": [ + 1, + 2, + 3, + 4, + 2, + 3, + 3, + 4 + ], + "line_or_pos_topo_vect": [ + 0, + 1, + 2, + 3, + 7, + 11, + 12, + 16 + ], + "line_or_to_sub_pos": [ + 0, + 1, + 2, + 3, + 1, + 2, + 3, + 3 + ], + "line_or_to_subid": [ + 0, + 0, + 0, + 0, + 1, + 2, + 2, + 3 + ], + "load_pos_topo_vect": [ + 5, + 17, + 20 + ], + "load_to_sub_pos": [ + 5, + 4, + 2 + ], + "load_to_subid": [ + 0, + 3, + 4 + ], + "n_busbar_per_sub": "2", + "name_gen": [ + "gen_0_0", + "gen_1_1" + ], + "name_line": [ + "0_1_0", + "0_2_1", + "0_3_2", + "0_4_3", + "1_2_4", + "2_3_5", + "2_3_6", + "3_4_7" + ], + "name_load": [ + "load_0_0", + "load_3_1", + "load_4_2" + ], + "name_shunt": [], + "name_storage": [], + "name_sub": [ + "sub_0", + "sub_1", + "sub_2", + "sub_3", + "sub_4" + ], + "shunt_to_subid": [], + "storage_Emax": [], + "storage_Emin": [], + "storage_charging_efficiency": [], + "storage_discharging_efficiency": [], + "storage_loss": [], + "storage_marginal_cost": [], + "storage_max_p_absorb": [], + "storage_max_p_prod": [], + "storage_pos_topo_vect": [], + "storage_to_sub_pos": [], + "storage_to_subid": [], + "storage_type": [], + "sub_info": [ + 6, + 3, + 4, + 5, + 3 + ] +} \ No newline at end of file diff --git a/grid2op/tests/BaseBackendTest.py b/grid2op/tests/BaseBackendTest.py index 071d7e21..f2915f93 100644 --- a/grid2op/tests/BaseBackendTest.py +++ b/grid2op/tests/BaseBackendTest.py @@ -2237,9 +2237,9 @@ def test_shunt_effect(self): env_change_q.action_space({"shunt": {"set_bus": [(0, 2)]}}) ) assert obs_co_bus2_sh_alone._shunt_bus == -1 - assert obs_co_bus2_sh_alone._shunt_v == 0. - assert obs_co_bus2_sh_alone._shunt_p == 0 - assert obs_co_bus2_sh_alone._shunt_q == 0 + assert np.abs(obs_co_bus2_sh_alone._shunt_v - 0.) <= 1e-6 + assert np.abs(obs_co_bus2_sh_alone._shunt_p - 0.) <= 1e-6 + assert np.abs(obs_co_bus2_sh_alone._shunt_q - 0.) <= 1e-6 # note that above the backend can diverge (shunt is alone on its bus !) # on pp it does not ... but it probably should @@ -2256,8 +2256,8 @@ def test_shunt_effect(self): assert np.allclose(obs_co_bus2_sh_notalone.v_or[10], 23.15359878540039) assert obs_co_bus2_sh_notalone._shunt_bus == 2 assert np.allclose(obs_co_bus2_sh_notalone._shunt_v, 23.15359878540039) - assert obs_co_bus2_sh_notalone._shunt_p == 0 - assert obs_co_bus2_sh_notalone._shunt_q == -25.464233 + assert np.abs(obs_co_bus2_sh_notalone._shunt_p) <= 1e-6, f"{obs_co_bus2_sh_notalone._shunt_p} vs 0." + assert np.abs(obs_co_bus2_sh_notalone._shunt_q - -25.464233) <= 1e-6 class BaseTestResetEqualsLoadGrid(MakeBackend): diff --git a/grid2op/tests/aaa_test_backend_interface.py b/grid2op/tests/aaa_test_backend_interface.py index c11f86f3..30b21671 100644 --- a/grid2op/tests/aaa_test_backend_interface.py +++ b/grid2op/tests/aaa_test_backend_interface.py @@ -724,10 +724,10 @@ def test_14change_topology(self): assert np.allclose(diff_v_bus, 0., atol=3 * self.tol_one), "there are some discrepency in the backend after a powerflow: some nodes have two different voltages. Check the accessor for voltage in all the `***_info()` (*eg* `loads_info()`)" p_after_or, q_after_or, v_after_or, a_after_or = backend.lines_or_info() - assert np.allclose(p_after_or, p_or), f"The p_or flow changed while the topology action is supposed to have no impact, check the `apply_action` for topology" - assert np.allclose(q_after_or, q_or), f"The q_or flow changed while the topology action is supposed to do nothing, check the `apply_action` for topology" - assert np.allclose(v_after_or, v_or), f"The v_or changed while the topology action is supposed to do nothing, check the `apply_action` for topology" - assert np.allclose(a_after_or, a_or), f"The a_or flow changed while the topology action is supposed to do nothing, check the `apply_action` for topology" + assert np.allclose(p_after_or, p_or), "The p_or flow changed while the topology action is supposed to have no impact, check the `apply_action` for topology" + assert np.allclose(q_after_or, q_or), "The q_or flow changed while the topology action is supposed to do nothing, check the `apply_action` for topology" + assert np.allclose(v_after_or, v_or), "The v_or changed while the topology action is supposed to do nothing, check the `apply_action` for topology" + assert np.allclose(a_after_or, a_or), "The a_or flow changed while the topology action is supposed to do nothing, check the `apply_action` for topology" sub_id = 1 # mix of bus 1 and 2 on substation 1 @@ -750,10 +750,10 @@ def test_14change_topology(self): assert np.allclose(diff_v_bus, 0., atol=3 * self.tol_one), "there are some discrepency in the backend after a powerflow: some nodes have two different voltages. Check the accessor for voltage in all the `***_info()` (*eg* `loads_info()`)" p_after_or, q_after_or, v_after_or, a_after_or = backend.lines_or_info() - assert not np.allclose(p_after_or, p_or), f"The p_or flow doesn't change while the topology action is supposed to have a real impact, check the `apply_action` for topology" - assert not np.allclose(q_after_or, q_or), f"The q_or flow doesn't change while the topology action is supposed to have a real impact, check the `apply_action` for topology" - assert not np.allclose(v_after_or, v_or), f"The v_or doesn't change while the topology action is supposed to have a real impact, check the `apply_action` for topology" - assert not np.allclose(a_after_or, a_or), f"The a_or flow doesn't change while the topology action is supposed to have a real impact, check the `apply_action` for topology" + assert not np.allclose(p_after_or, p_or), "The p_or flow doesn't change while the topology action is supposed to have a real impact, check the `apply_action` for topology" + assert not np.allclose(q_after_or, q_or), "The q_or flow doesn't change while the topology action is supposed to have a real impact, check the `apply_action` for topology" + assert not np.allclose(v_after_or, v_or), "The v_or doesn't change while the topology action is supposed to have a real impact, check the `apply_action` for topology" + assert not np.allclose(a_after_or, a_or), "The a_or flow doesn't change while the topology action is supposed to have a real impact, check the `apply_action` for topology" def test_15_reset(self): """Tests that when a backend is reset, it is indeed reset in the original state @@ -1904,5 +1904,24 @@ def test_35_gen_disco_v_zero(self): assert np.abs(gen_p[0]) <= 1e-8, f"disconnected gen should have a p of 0, found {gen_p[0]} (AC)" assert np.abs(gen_q[0]) <= 1e-8, f"disconnected gen should have a q of 0, found {gen_q[0]} (AC)" assert np.abs(gen_v[0]) <= 1e-8, f"disconnected gen should have a voltage set to 0, found {gen_v[0]} (AC)" - - # TODO test: disconnect a gen a load a conso and then connect it again and see what you end up with. \ No newline at end of file + + def test_36_shvnkv_present_if_shunt_supported(self): + """ + .. versionadded: 1.12.3 + + Check that the backend._sh_vnkv is set (not None) if the backend supports shunts. + + It is a requirement from grid2op version 1.12.3 + """ + self.skip_if_needed() + backend = self.aux_make_backend(allow_detachment=True) + cls = type(backend) + if not cls.shunts_data_available: + self.skipTest("This test cannot be performed as your backend does not support shunts") + + sh_vnkv = backend._sh_vnkv + assert sh_vnkv is not None, "If your backend supports shunts, then you need to implement `_sh_vnkv` attribute in the load_grid method of the backend" + assert isinstance(sh_vnkv, np.ndarray), "`_sh_vnkv` attribute should be a numpy array" + assert sh_vnkv.shape[0] == cls.n_shunt, f"_sh_vnkv has len {sh_vnkv.shape[0]} but there are {cls.n_shunt} n shunts on the grid" + + # TODO test: disconnect a gen a load a conso and then connect it again and see what you end up with. diff --git a/grid2op/tests/helper_list_test.py b/grid2op/tests/helper_list_test.py index dbc27fdd..31b33cfe 100755 --- a/grid2op/tests/helper_list_test.py +++ b/grid2op/tests/helper_list_test.py @@ -1,6 +1,44 @@ #!/usr/bin/env python3 -import sys import unittest +li_tested_elsewhere = [ + # agent (approx 1 min) + "test_Agent", "test_AgentsFast", "test_recopowerlineperarea", + # converter (approx 45s) + "test_AgentConverter", "test_Converter", "test_BackendConverter", + # Runner / EpisodeData / "score (3 mins)" + "test_EpisodeData", + "test_runner_kwargs_backend", + "test_Runner", + "test_RunnerFast", + "test_score_idf_2023_assistant", + "test_score_idf_2023_nres", + "test_score_idf_2023", + "test_score_wcci_2022", + "test_AlarmScore", + "test_RewardAlertCostScore", + "test_RewardNewRenewableSourcesUsageScore", + "test_utils", + "test_CompactEpisodeData", + "test_reset_options_runner", + # env in general (1 min) + "test_attached_envs", + "test_attached_envs_compat", + "test_l2rpn_idf_2023", + "test_MultiMix", + "test_timeOutEnvironment", + "test_MaskedEnvironment", + "test_MakeEnv", + "test_multi_steps_env", + "test_simenv_blackout", + # alert / alarm ( 1min) + "test_AlarmFeature", + "test_alert_gym_compat", + "test_alert_obs_act", + "test_alert_trust_score", + "test_AlertReward", + # TODO simulate + # TODO curtailment + ] def print_suite(suite): @@ -11,8 +49,18 @@ def print_suite(suite): testmodule = suite.__class__.__module__ testsuite = suite.__class__.__name__ testmethod = suite._testMethodName + do_print = True + if testmodule.startswith("test_issue_"): + # the test_issue_* will be tested elsewhere + do_print = False + else: + for el in li_tested_elsewhere: + if testmodule == el: + do_print = False + break test_name = "{}.{}.{}".format(testmodule, testsuite, testmethod) - print(test_name) + if do_print: + print(test_name) print_suite(unittest.defaultTestLoader.discover(".")) diff --git a/grid2op/tests/test_RewardAlertCostScore.py b/grid2op/tests/test_RewardAlertCostScore.py index 1c594a0a..8778a2c6 100644 --- a/grid2op/tests/test_RewardAlertCostScore.py +++ b/grid2op/tests/test_RewardAlertCostScore.py @@ -6,24 +6,16 @@ # SPDX-License-Identifier: MPL-2.0 # This file is part of Grid2Op, Grid2Op a testbed platform to model sequential decision making in power systems. -import warnings -import numpy as np import unittest import tempfile import grid2op -from grid2op.Reward import _AlertCostScore, _AlertTrustScore -from grid2op.Agent import DoNothingAgent, BaseAgent +from grid2op.Reward import _AlertCostScore +from grid2op.Agent import BaseAgent from grid2op.tests.helper_path_test import * -from grid2op.Exceptions import Grid2OpException from grid2op.Runner import Runner from grid2op.Observation import BaseObservation from grid2op.Episode import EpisodeData -from grid2op.Parameters import Parameters -from grid2op.Opponent import BaseOpponent, GeometricOpponent -from grid2op.Action import BaseAction, PlayableAction -from _aux_opponent_for_test_alerts import (_get_steps_attack, - TestOpponent - ) +from grid2op.Action import BaseAction ATTACKED_LINE = "48_50_136" diff --git a/grid2op/tests/test_RewardNewRenewableSourcesUsageScore.py b/grid2op/tests/test_RewardNewRenewableSourcesUsageScore.py index b09188f4..2afed2a8 100644 --- a/grid2op/tests/test_RewardNewRenewableSourcesUsageScore.py +++ b/grid2op/tests/test_RewardNewRenewableSourcesUsageScore.py @@ -14,6 +14,7 @@ from grid2op.Reward import _NewRenewableSourcesUsageScore from grid2op.Agent import DoNothingAgent, BaseAgent + class CurtailTrackerAgent(BaseAgent): def __init__(self, action_space, gen_renewable, gen_pmax, curtail_level=1.): super().__init__(action_space) diff --git a/grid2op/tests/test_Runner.py b/grid2op/tests/test_Runner.py index 28828a8b..2614aafc 100644 --- a/grid2op/tests/test_Runner.py +++ b/grid2op/tests/test_Runner.py @@ -10,6 +10,8 @@ import tempfile import json import unittest +import os +import numpy as np import pdb import packaging from packaging import version @@ -346,7 +348,7 @@ def seed(self, seed): ) # test that the right seeds are assigned to the agent - res = runner.run( + _ = runner.run( nb_episode=3, max_iter=self.max_iter, env_seeds=[1, 2, 3], @@ -356,7 +358,7 @@ def seed(self, seed): # test that is no seeds are set, then the "seed" function of the agent is not called. my_agent.seeds = [] - res = runner.run(nb_episode=3, max_iter=self.max_iter, env_seeds=[1, 2, 3]) + _ = runner.run(nb_episode=3, max_iter=self.max_iter, env_seeds=[1, 2, 3]) assert my_agent.seeds == [] def test_always_same_order(self): @@ -474,11 +476,11 @@ def _aux_backward(self, base_path, g2op_version_txt, g2op_version): assert ( EpisodeData.get_grid2op_version(full_episode_path) == grid2op.__version__ - ), "wrong grid2op version stored (test_version)" + ), f"wrong grid2op version stored (test_version): {EpisodeData.get_grid2op_version(full_episode_path)} vs {grid2op.__version__}" else: assert ( EpisodeData.get_grid2op_version(full_episode_path) == g2op_version - ), "wrong grid2op version stored (>=1.5.0)" + ), f"wrong grid2op version stored (>=1.5.0): loaded version from {full_episode_path} {EpisodeData.get_grid2op_version(full_episode_path)} vs {g2op_version}" def test_backward_compatibility(self): backward_comp_version = [ @@ -526,6 +528,8 @@ def test_backward_compatibility(self): "1.11.0", "1.12.0", "1.12.1", + "1.12.2", + "1.12.3", ] curr_version = "test_version" assert ( diff --git a/grid2op/tests/test_previous_state.py b/grid2op/tests/test_previous_state.py index 5caa753b..b4fc5240 100644 --- a/grid2op/tests/test_previous_state.py +++ b/grid2op/tests/test_previous_state.py @@ -7,6 +7,7 @@ # This file is part of Grid2Op, Grid2Op a testbed platform to model sequential decision making in power systems. import copy +import os from typing import Union import unittest import warnings @@ -17,6 +18,7 @@ import grid2op.Environment import grid2op.Environment._env_prev_state import grid2op.Observation +from grid2op.tests.helper_path_test import PATH_DATA_TEST class PreviousStateTester(unittest.TestCase): @@ -273,6 +275,7 @@ def test_line_for_env(self): assert obs.topo_vect[pos_ex_tv] == -1 assert self.env._previous_conn_state._topo_vect[pos_or_tv] == 1 assert self.env._previous_conn_state._topo_vect[pos_ex_tv] == 1 + # reconnect it (forecast env) for_env = obs.get_forecast_env() for_obs = for_env.reset() @@ -296,6 +299,7 @@ def test_line_for_env(self): assert obs.topo_vect[pos_ex_tv] == -1 assert self.env._previous_conn_state._topo_vect[pos_or_tv] == 2 assert self.env._previous_conn_state._topo_vect[pos_ex_tv] == 1 + # reconnect it (forecast env) for_env = obs.get_forecast_env() assert for_env._cst_prev_state_at_init._topo_vect[pos_or_tv] == 2, f"{for_env._cst_prev_state_at_init._topo_vect[pos_or_tv]} vs 2" @@ -362,30 +366,29 @@ def test_cst_prev_state_const(self, env=None): assert env._cst_prev_state_at_init is init_cst_prev_state assert not env._cst_prev_state_at_init._can_modif self._aux_test_matches_obs(init_cst_prev_state_cpy, env._cst_prev_state_at_init, "after 2 steps") - _ = env.reset() - assert env._cst_prev_state_at_init is init_cst_prev_state + assert env._cst_prev_state_at_init == init_cst_prev_state assert not env._cst_prev_state_at_init._can_modif self._aux_test_matches_obs(init_cst_prev_state_cpy, env._cst_prev_state_at_init, "after 1 reset") _ = env.step(env.action_space()) - assert env._cst_prev_state_at_init is init_cst_prev_state + assert env._cst_prev_state_at_init == init_cst_prev_state assert not env._cst_prev_state_at_init._can_modif self._aux_test_matches_obs(init_cst_prev_state_cpy, env._cst_prev_state_at_init, "after 1 reset 1 step") _ = env.step(env.action_space({'set_line_status': [(0, -1)]})) - assert env._cst_prev_state_at_init is init_cst_prev_state + assert env._cst_prev_state_at_init == init_cst_prev_state assert not env._cst_prev_state_at_init._can_modif self._aux_test_matches_obs(init_cst_prev_state_cpy, env._cst_prev_state_at_init, "after 1 reset 2 steps") _ = env.reset() - assert env._cst_prev_state_at_init is init_cst_prev_state + assert env._cst_prev_state_at_init == init_cst_prev_state assert not env._cst_prev_state_at_init._can_modif self._aux_test_matches_obs(init_cst_prev_state_cpy, env._cst_prev_state_at_init, "after 2 reset") _ = env.step(env.action_space()) - assert env._cst_prev_state_at_init is init_cst_prev_state + assert env._cst_prev_state_at_init == init_cst_prev_state assert not env._cst_prev_state_at_init._can_modif self._aux_test_matches_obs(init_cst_prev_state_cpy, env._cst_prev_state_at_init, "after 2 reset 1 step") _ = env.step(env.action_space({'set_line_status': [(0, -1)]})) - assert env._cst_prev_state_at_init is init_cst_prev_state + assert env._cst_prev_state_at_init == init_cst_prev_state assert not env._cst_prev_state_at_init._can_modif self._aux_test_matches_obs(init_cst_prev_state_cpy, env._cst_prev_state_at_init, "after 2 reset 2 steps") @@ -401,23 +404,28 @@ def test_shunt(self, tol=1e-5): obs, reward, done, info = self.env.step(self.env.action_space()) assert obs._shunt_bus[sh_id] == 1 assert np.abs(obs._shunt_p[sh_id] - th_val_p[obs.current_step]) <= tol, f"{obs._shunt_p[sh_id]} vs {th_val_p[obs.current_step]}" - assert np.abs(obs._shunt_q[sh_id] - th_val_q[obs.current_step]) <= tol, f"{obs._shunt_p[sh_id]} vs {th_val_q[obs.current_step]}" + assert np.abs(obs._shunt_q[sh_id] - th_val_q[obs.current_step]) <= tol, f"{obs._shunt_q[sh_id]} vs {th_val_q[obs.current_step]}" self._aux_test_matches_obs(obs, self.env, "after 1 step") # for battery of tests: the bus obs, reward, done, info = self.env.step(self.env.action_space({"shunt": {"set_bus": [(sh_id, -1)]}})) - id_pr_ok = obs.current_step - 1 assert obs._shunt_bus[sh_id] == -1 assert obs._shunt_p[sh_id] == 0. assert obs._shunt_q[sh_id] == 0. assert self.env._previous_conn_state._shunt_bus[sh_id] == 1 - assert np.abs(self.env._previous_conn_state._shunt_p - th_val_p[id_pr_ok]) <= tol, f"{obs._shunt_p[sh_id]} vs {th_val_p[id_pr_ok]}" - assert np.abs(self.env._previous_conn_state._shunt_q - th_val_q[id_pr_ok]) <= tol, f"{obs._shunt_p[sh_id]} vs {th_val_q[id_pr_ok]}" + assert np.abs(self.env._previous_conn_state._shunt_p - 0.) <= tol + assert np.abs(self.env._previous_conn_state._shunt_q - (-19.)) <= tol # setpoint of shunt is -19. and NOT the stuff in obs._shunt_q ! + assert np.abs(obs._prev_conn._shunt_p - 0.) <= tol + assert np.abs(obs._prev_conn._shunt_q - (-19.)) <= tol # setpoint of shunt is -19. and NOT the stuff in obs._shunt_q ! obs, reward, done, info = self.env.step(self.env.action_space({"shunt": {"set_bus": [(sh_id, 1)]}})) assert obs._shunt_bus[sh_id] == 1 assert np.abs(obs._shunt_p[sh_id] - th_val_p[obs.current_step]) <= tol, f"{obs._shunt_p[sh_id]} vs {th_val_p[obs.current_step]}" - assert np.abs(obs._shunt_q[sh_id] - th_val_q[obs.current_step]) <= tol, f"{obs._shunt_p[sh_id]} vs {th_val_q[obs.current_step]}" + assert np.abs(obs._shunt_q[sh_id] - th_val_q[obs.current_step]) <= tol, f"{obs._shunt_q[sh_id]} vs {th_val_q[obs.current_step]}" + assert np.abs(self.env._previous_conn_state._shunt_p - 0.) <= tol + assert np.abs(self.env._previous_conn_state._shunt_q - (-19.)) <= tol # setpoint of shunt is -19. and NOT the stuff in obs._shunt_q ! + assert np.abs(obs._prev_conn._shunt_p - 0.) <= tol + assert np.abs(obs._prev_conn._shunt_q - (-19.)) <= tol # setpoint of shunt is -19. and NOT the stuff in obs._shunt_q ! assert self.env._previous_conn_state._shunt_bus[sh_id] == 1 def test_shunt_simulate(self): @@ -428,6 +436,139 @@ def test_shunt_for_env(self): # TODO pass + +class TestWithGridLineDisco(unittest.TestCase): + def setUp(self): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + self.env = grid2op.make(os.path.join(PATH_DATA_TEST, "5bus_example_disco_el_in_grid")) + return super().setUp() + + def tearDown(self): + self.env.close() + return super().tearDown() + + def _aux_check_line_disco(self, line_id=2): + assert self.env._previous_conn_state._topo_vect[type(self.env).line_or_pos_topo_vect[line_id]] == -1 + assert self.env._previous_conn_state._topo_vect[type(self.env).line_ex_pos_topo_vect[line_id]] == -1 + assert self.env._backend_action.current_topo.values[type(self.env).line_or_pos_topo_vect[line_id]] == -1, f"{self.env._backend_action.current_topo.values[type(self.env).line_or_pos_topo_vect[line_id]]}" + assert self.env._backend_action.current_topo.values[type(self.env).line_ex_pos_topo_vect[line_id]] == -1, f"{self.env._backend_action.current_topo.values[type(self.env).line_ex_pos_topo_vect[line_id]]}" + assert self.env._backend_action.last_topo_registered.values[type(self.env).line_or_pos_topo_vect[line_id]] == -1 + assert self.env._backend_action.last_topo_registered.values[type(self.env).line_ex_pos_topo_vect[line_id]] == -1 + + def test_env_ok(self): + self._aux_check_line_disco() + + obs = self.env.reset(seed=0, options={"time serie id": 0}) + self._aux_check_line_disco() + assert not obs.line_status[2] + assert obs.topo_vect[type(self.env).line_or_pos_topo_vect[2]] == -1 + assert obs.topo_vect[type(self.env).line_ex_pos_topo_vect[2]] == -1 + + self.env.step(self.env.action_space()) + self._aux_check_line_disco() + + def test_can_step_reco_with_bus(self): + line_id = 2 + obs = self.env.reset(seed=0, options={"time serie id": 0}) + act = self.env.action_space({"set_line_status": [(line_id, 1)], + "set_bus": {"lines_or_id": [(line_id, 1)], + "lines_ex_id": [(line_id, 1)], + }, + }) + obs, reward, done, info = self.env.step(act) + assert obs.line_status[line_id] + assert obs.topo_vect[type(self.env).line_or_pos_topo_vect[line_id]] == 1 + assert obs.topo_vect[type(self.env).line_ex_pos_topo_vect[line_id]] == 1 + assert self.env._previous_conn_state._topo_vect[type(self.env).line_or_pos_topo_vect[line_id]] == 1 + assert self.env._previous_conn_state._topo_vect[type(self.env).line_ex_pos_topo_vect[line_id]] == 1 + assert obs._prev_conn._topo_vect[type(self.env).line_or_pos_topo_vect[line_id]] == 1 + assert obs._prev_conn._topo_vect[type(self.env).line_ex_pos_topo_vect[line_id]] == 1 + assert self.env._backend_action.current_topo.values[type(self.env).line_or_pos_topo_vect[line_id]] == 1 + assert self.env._backend_action.current_topo.values[type(self.env).line_ex_pos_topo_vect[line_id]] == 1 + assert self.env._backend_action.last_topo_registered.values[type(self.env).line_or_pos_topo_vect[line_id]] == 1 + assert self.env._backend_action.last_topo_registered.values[type(self.env).line_ex_pos_topo_vect[line_id]] == 1 + + def test_can_simulate_reco_with_bus(self): + line_id = 2 + obs = self.env.reset(seed=0, options={"time serie id": 0}) + sim_obs, reward, done, info = obs.simulate(self.env.action_space({"set_line_status": [(line_id, 1)], + "set_bus": {"lines_or_id": [(line_id, 1)], + "lines_ex_id": [(line_id, 1)], + }, + })) + assert sim_obs.line_status[2] + assert sim_obs.topo_vect[type(self.env).line_or_pos_topo_vect[line_id]] == 1 + assert sim_obs.topo_vect[type(self.env).line_ex_pos_topo_vect[line_id]] == 1 + self._aux_check_line_disco() + assert obs._prev_conn._topo_vect[type(self.env).line_or_pos_topo_vect[line_id]] == -1 + assert obs._prev_conn._topo_vect[type(self.env).line_ex_pos_topo_vect[line_id]] == -1 + + def test_raise_exception_if_no_bus_step(self): + line_id = 2 + obs = self.env.reset(seed=0, options={"time serie id": 0}) + act = self.env.action_space({"set_line_status": [(line_id, 1)]}) + obs, reward, done, info = self.env.step(act) + assert len(info["exception"]) > 0 + self._aux_check_line_disco() + assert not obs.line_status[2] + assert obs.topo_vect[type(self.env).line_or_pos_topo_vect[line_id]] == -1 + assert obs.topo_vect[type(self.env).line_ex_pos_topo_vect[line_id]] == -1 + + act = self.env.action_space({"set_line_status": [(line_id, 1)], + "set_bus": {"lines_or_id": [(line_id, 1)] + }, + }) + obs, reward, done, info = self.env.step(act) + assert len(info["exception"]) > 0 + self._aux_check_line_disco() + assert not obs.line_status[2] + assert obs.topo_vect[type(self.env).line_or_pos_topo_vect[line_id]] == -1 + assert obs.topo_vect[type(self.env).line_ex_pos_topo_vect[line_id]] == -1 + + act = self.env.action_space({"set_line_status": [(line_id, 1)], + "set_bus": {"lines_ex_id": [(line_id, 1)] + }, + }) + obs, reward, done, info = self.env.step(act) + assert len(info["exception"]) > 0 + self._aux_check_line_disco() + assert not obs.line_status[2] + assert obs.topo_vect[type(self.env).line_or_pos_topo_vect[line_id]] == -1 + assert obs.topo_vect[type(self.env).line_ex_pos_topo_vect[line_id]] == -1 + + def test_raise_exception_if_no_bus_simulate(self): + line_id = 2 + obs = self.env.reset(seed=0, options={"time serie id": 0}) + act = self.env.action_space({"set_line_status": [(line_id, 1)]}) + sim_obs, reward, done, info = obs.simulate(act) + assert len(info["exception"]) > 0 + self._aux_check_line_disco() + assert not sim_obs.line_status[2] + assert sim_obs.topo_vect[type(self.env).line_or_pos_topo_vect[line_id]] == -1 + assert sim_obs.topo_vect[type(self.env).line_ex_pos_topo_vect[line_id]] == -1 + + act = self.env.action_space({"set_line_status": [(line_id, 1)], + "set_bus": {"lines_or_id": [(line_id, 1)] + }, + }) + sim_obs, reward, done, info = obs.simulate(act) + assert len(info["exception"]) > 0 + self._aux_check_line_disco() + assert not sim_obs.line_status[2] + assert sim_obs.topo_vect[type(self.env).line_or_pos_topo_vect[line_id]] == -1 + assert sim_obs.topo_vect[type(self.env).line_ex_pos_topo_vect[line_id]] == -1 + + act = self.env.action_space({"set_line_status": [(line_id, 1)], + "set_bus": {"lines_ex_id": [(line_id, 1)] + }, + }) + sim_obs, reward, done, info = obs.simulate(act) + assert len(info["exception"]) > 0 + self._aux_check_line_disco() + assert not sim_obs.line_status[2] + assert sim_obs.topo_vect[type(self.env).line_or_pos_topo_vect[line_id]] == -1 + assert sim_obs.topo_vect[type(self.env).line_ex_pos_topo_vect[line_id]] == -1 # TODO shunt with obs.simulate and env.get_forecast_env # TODO storage with obs.simulate and env.get_forecast_env