Skip to content

Commit

Permalink
fix issue Grid2op#657
Browse files Browse the repository at this point in the history
Signed-off-by: DONNOT Benjamin <[email protected]>
Signed-off-by: Xavier Weiss <[email protected]>
  • Loading branch information
BDonnot authored and DEUCE1957 committed Nov 8, 2024
1 parent 4962624 commit 1e78513
Show file tree
Hide file tree
Showing 9 changed files with 346 additions and 20 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,20 @@ Native multi agents support:

[1.11.0] - 202x-yy-zz
-----------------------
- [FIXED] issue https://github.com/Grid2op/grid2op/issues/657
- [FIXED] missing an import on the `MaskedEnvironment` class
- [ADDED] possibility to set the "thermal limits" when calling `env.reset(..., options={"thermal limit": xxx})`
- [ADDED] possibility to retrieve some structural information about elements with
with `gridobj.get_line_info(...)`, `gridobj.get_load_info(...)`, `gridobj.get_gen_info(...)`
or , `gridobj.get_storage_info(...)`
- [ADDED] codacy badge on the readme
- [IMPROVED] possibility to set the injections values with names
to be consistent with other way to set the actions (*eg* set_bus)
- [IMPROVED] error messages when creating an action which changes the injections
- [IMPROVED] (linked to https://github.com/Grid2op/grid2op/issues/657) the way the
"chronics_hander" in the ObsEnv behaves (it now fully implements the public interface of
a "real" chronic_handler)
- [IMPROVED] error message in the `FromNPY` class when the backend is checked

[1.10.4] - 2024-10-15
-------------------------
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
[![PyPi_Compat](https://img.shields.io/pypi/pyversions/grid2op.svg)](https://pypi.org/project/Grid2Op/)
[![LICENSE](https://img.shields.io/pypi/l/grid2op.svg)](https://www.mozilla.org/en-US/MPL/2.0/)
[![Documentation Status](https://readthedocs.org/projects/grid2op/badge/?version=latest)](https://grid2op.readthedocs.io/en/latest/?badge=latest)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/3a4e666ba20f4f20b9131e9a6081622c)](https://app.codacy.com/gh/Grid2op/grid2op/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
[![CircleCI](https://dl.circleci.com/status-badge/img/gh/Grid2op/grid2op/tree/master.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/Grid2op/grid2op/tree/master)
[![discord](https://discord.com/api/guilds/698080905209577513/embed.png)](https://discord.gg/cYsYrPT)
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/grid2op/grid2op.git/master)
Expand Down
256 changes: 256 additions & 0 deletions grid2op/Chronics/_obs_fake_chronics_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
# Copyright (c) 2019-2024, RTE (https://www.rte-france.com)
# See AUTHORS.txt
# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0.
# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file,
# you can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
# This file is part of Grid2Op, Grid2Op a testbed platform to model sequential decision making in power systems.

from typing import Dict, Union, Literal

import grid2op
from grid2op.Exceptions import EnvError, ChronicsError
from grid2op.Chronics import ChangeNothing


class _ObsCH(ChangeNothing):
"""
INTERNAL
.. warning:: /!\\\\ Internal, do not use unless you know what you are doing /!\\\\
This class is reserved to internal use. Do not attempt to do anything with it.
"""

# properties that should not be accessed
@property
def chronicsClass(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `chronicsClass`")

@property
def action_space(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `action_space`")

@property
def path(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `path`")

@property
def _real_data(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `_real_data`")

@property
def kwargs(self):
return {}

@kwargs.setter
def kwargs(self, new_value):
raise ChronicsError('Impossible to set the "kwargs" attribute')

@property
def _kwargs(self):
return {}

@property
def real_data(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `real_data`")

# functions overriden from the ChronicsHandler class
def forecasts(self):
return []

def get_name(self):
return ""

def next_time_step(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `next_time_step`")

def max_episode_duration(self):
return 0

def seed(self, seed):
""".. warning:: This function is part of the public API of ChronicsHandler but should not do anything here"""
pass

def cleanup_action_space(self):
""".. warning:: This function is part of the public API of ChronicsHandler but should not do anything here"""
pass

# methods overriden from the ChronicsHandler class (__getattr__) so forwarded to the Chronics class
@property
def gridvalueClass(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `gridvalueClass`")

@property
def data(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `data`")

@property
def sep(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `sep`")

@property
def subpaths(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `subpaths`")

@property
def _order(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `_order`")

@property
def chunk_size(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `chunk_size`")

@property
def _order_backend_loads(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `_order_backend_loads`")

@property
def _order_backend_prods(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `_order_backend_prods`")

@property
def _order_backend_lines(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `_order_backend_lines`")

@property
def _order_backend_subs(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `_order_backend_subs`")

@property
def _names_chronics_to_backend(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `_names_chronics_to_backend`")

@property
def _filter(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `_filter`")

@property
def _prev_cache_id(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `_prev_cache_id`")

def done(self):
return True

def check_validity(self, backend):
return True

def get_id(self) -> str:
return ""

def shuffle(self, shuffler=None):
"""
.. warning::
This function is part of the public API of ChronicsHandler,
by being accessible through the __getattr__ call that is
forwarded to the GridValue class
It should not do anything here.
"""
pass

def sample_next_chronics(self, probabilities=None):
"""
.. warning::
This function is part of the public API of ChronicsHandler,
by being accessible through the __getattr__ call that is
forwarded to the GridValue class
It should not do anything here.
"""
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `sample_next_chronics`")

def set_chunk_size(self, new_chunk_size):
"""
.. warning::
This function is part of the public API of ChronicsHandler,
by being accessible through the __getattr__ call that is
forwarded to the GridValue class
It should not do anything here.
"""
pass

def init_datetime(self):
"""
.. warning::
This function is part of the public API of ChronicsHandler,
by being accessible through the __getattr__ call that is
forwarded to the GridValue class
It should not do anything here.
"""
pass

def next_chronics(self):
"""
.. warning::
This function is part of the public API of ChronicsHandler,
by being accessible through the __getattr__ call that is
forwarded to the GridValue class
It should not do anything here.
"""
pass

def tell_id(self, id_num, previous=False):
"""
.. warning::
This function is part of the public API of ChronicsHandler,
by being accessible through the __getattr__ call that is
forwarded to the GridValue class
It should not do anything here.
"""
pass

def set_filter(self, filter_fun):
"""
.. warning::
This function is part of the public API of ChronicsHandler,
by being accessible through the __getattr__ call that is
forwarded to the GridValue class
It should not do anything here.
"""
pass

def set_chunk_size(self, new_chunk_size):
"""
.. warning::
This function is part of the public API of ChronicsHandler,
by being accessible through the __getattr__ call that is
forwarded to the GridValue class
It should not do anything here.
"""
pass

def fast_forward(self, nb_timestep):
"""
.. warning::
This function is part of the public API of ChronicsHandler,
by being accessible through the __getattr__ call that is
forwarded to the GridValue class
It should not do anything here.
"""
pass

def get_init_action(self, names_chronics_to_backend: Dict[Literal["loads", "prods", "lines"], Dict[str, str]]) -> Union["grid2op.Action.playableAction.PlayableAction", None]:
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `get_init_action`")

def regenerate_with_new_seed(self):
"""
.. warning::
This function is part of the public API of ChronicsHandler,
by being accessible through the __getattr__ call that is
forwarded to the GridValue class
It should not do anything here.
"""
pass

def max_timestep(self):
raise EnvError("There are no time series in the observation from `obs.simulate`, so no `max_timestep`")

6 changes: 3 additions & 3 deletions grid2op/Chronics/fromNPY.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,12 +232,12 @@ def initialize(
order_backend_subs,
names_chronics_to_backend=None,
):
assert len(order_backend_prods) == self.n_gen
assert len(order_backend_loads) == self.n_load
assert len(order_backend_prods) == self.n_gen, f"len(order_backend_prods)={len(order_backend_prods)} vs self.n_gen={self.n_gen}"
assert len(order_backend_loads) == self.n_load, f"len(order_backend_loads)={len(order_backend_loads)} vs self.n_load={self.n_load}"
if self.n_line is None:
self.n_line = len(order_backend_lines)
else:
assert len(order_backend_lines) == self.n_line
assert len(order_backend_lines) == self.n_line, f"len(order_backend_lines)={len(order_backend_lines)} vs self.n_line={self.n_line}"

if self._forecasts is not None:
self._forecasts.initialize(
Expand Down
4 changes: 3 additions & 1 deletion grid2op/Environment/_forecast_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
# This file is part of Grid2Op, Grid2Op a testbed platform to model sequential decision making in power systems.

from typing import Tuple

from grid2op.typing_variables import STEP_INFO_TYPING
from grid2op.Action import BaseAction
from grid2op.Observation import BaseObservation
from grid2op.Environment.environment import Environment
Expand All @@ -23,6 +25,6 @@ def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._do_not_erase_local_dir_cls = True

def step(self, action: BaseAction) -> Tuple[BaseObservation, float, bool, dict]:
def step(self, action: BaseAction) -> Tuple[BaseObservation, float, bool, STEP_INFO_TYPING]:
self._highres_sim_counter += 1
return super().step(action)
19 changes: 4 additions & 15 deletions grid2op/Environment/_obsEnv.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2019-2020, RTE (https://www.rte-france.com)
# Copyright (c) 2019-2024, RTE (https://www.rte-france.com)
# See AUTHORS.txt
# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0.
# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file,
Expand All @@ -12,26 +12,15 @@
from typing import Dict, Union, Tuple, List, Optional, Any, Literal

import grid2op
from grid2op.Exceptions.envExceptions import EnvError
from grid2op.typing_variables import STEP_INFO_TYPING
from grid2op.dtypes import dt_int, dt_float, dt_bool
from grid2op.Environment.baseEnv import BaseEnv
from grid2op.Exceptions import EnvError
from grid2op.Chronics import ChangeNothing
from grid2op.Chronics._obs_fake_chronics_handler import _ObsCH
from grid2op.Rules import RulesChecker
from grid2op.operator_attention import LinearAttentionBudget


class _ObsCH(ChangeNothing):
"""
INTERNAL
.. warning:: /!\\\\ Internal, do not use unless you know what you are doing /!\\\\
This class is reserved to internal use. Do not attempt to do anything with it.
"""

def forecasts(self):
return []
from grid2op.Environment.baseEnv import BaseEnv


class _ObsEnv(BaseEnv):
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Environment/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -2135,7 +2135,7 @@ def get_params_for_runner(self):
else:
msg_ = ("You are probably using a legacy backend class that cannot "
"be copied properly. Please upgrade your backend to the latest version.")
self.logger.warn(msg_)
self.logger.warning(msg_)
warnings.warn(msg_)
res["backend_kwargs"] = None

Expand Down
1 change: 1 addition & 0 deletions grid2op/Environment/maskedEnvironment.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 warnings
import numpy as np
import os
from typing import Tuple, Union, List
Expand Down
Loading

0 comments on commit 1e78513

Please sign in to comment.