Exemple #1
0
    def _init_backend(self, init_grid_path, chronics_handler, backend,
                      names_chronics_to_backend, actionClass, observationClass,
                      rewardClass, legalActClass):
        self._env_dc = self.parameters.ENV_DC
        self.chronics_handler = chronics_handler
        self.backend = backend
        self._has_been_initialized()
        self._obsClass = observationClass

        if not issubclass(legalActClass, BaseRules):
            raise Grid2OpException(
                "Parameter \"legalActClass\" used to build the Environment should derived form the "
                "grid2op.BaseRules class, type provided is \"{}\"".format(
                    type(legalActClass)))
        self._game_rules = RulesChecker(legalActClass=legalActClass)
        self._legalActClass = legalActClass
        self._helper_action_player = self._do_nothing
        self.backend.set_thermal_limit(self._thermal_limit_a)
        self._create_opponent()

        self.current_obs_init = self._obsClass(seed=None,
                                               obs_env=None,
                                               action_helper=None)
        self.current_obs = self.current_obs_init

        # backend has loaded everything
        self._line_status = np.ones(shape=self.n_line, dtype=dt_bool)
        self._hazard_duration = np.zeros(shape=self.n_line, dtype=dt_int)
        self._has_been_initialized()
Exemple #2
0
    def init_backend(self,
                     init_grid_path,
                     chronics_handler,
                     backend,
                     names_chronics_to_backend,
                     actionClass,
                     observationClass,
                     rewardClass, legalActClass):
        """
        backend should not be the backend of the environment!!!

        Parameters
        ----------
        init_grid_path
        chronics_handler
        backend
        names_chronics_to_backend
        actionClass
        observationClass
        rewardClass
        legalActClass

        Returns
        -------

        """
        self.env_dc = self.parameters.FORECAST_DC
        self.chronics_handler = chronics_handler
        self.backend = backend
        self._has_been_initialized()
        self.obsClass = observationClass

        if not issubclass(legalActClass, BaseRules):
            raise Grid2OpException(
                "Parameter \"legalActClass\" used to build the Environment should derived form the "
                "grid2op.BaseRules class, type provided is \"{}\"".format(
                    type(legalActClass)))
        self.game_rules = RulesChecker(legalActClass=legalActClass)
        self.legalActClass = legalActClass
        self.helper_action_player = self._do_nothing
        self.backend.set_thermal_limit(self._thermal_limit_a)
        self._create_opponent()

        self.gen_activeprod_t_init = np.zeros(self.n_gen, dtype=dt_float)
        self.gen_activeprod_t_redisp_init = np.zeros(self.n_gen, dtype=dt_float)
        self.times_before_line_status_actionable_init = np.zeros(self.n_line, dtype=dt_int)
        self.times_before_topology_actionable_init = np.zeros(self.n_sub, dtype=dt_int)
        self.time_next_maintenance_init = np.zeros(self.n_line, dtype=dt_int)
        self.duration_next_maintenance_init = np.zeros(self.n_line, dtype=dt_int)
        self.target_dispatch_init = np.zeros(self.n_gen, dtype=dt_float)
        self.actual_dispatch_init = np.zeros(self.n_gen, dtype=dt_float)
        self.last_bus_line_or_init = np.zeros(self.n_line, dtype=dt_int)
        self.last_bus_line_ex_init = np.zeros(self.n_line, dtype=dt_int)

        self.current_obs_init = self.obsClass(seed=None,
                                              obs_env=None,
                                              action_helper=None)
        self.current_obs = self.current_obs_init
Exemple #3
0
    def test_illegal_detected(self):
        act = self.env.helper_action_player({"set_line_status": [(1, -1)]})
        self.env.game_rules = RulesChecker(legalActClass=DefaultRules)
        self.env.times_before_line_status_actionable[1] = 1
        obs, reward, done, info = self.env.step(act)

        # the action is illegal and it has not been implemented on the powergrid
        assert not info['is_ambiguous']
        assert info["is_illegal"]
        assert np.sum(obs.line_status) == 8
Exemple #4
0
    def _init_backend(
            self,
            chronics_handler,
            backend,
            names_chronics_to_backend,
            actionClass,
            observationClass,  # base grid2op type
            rewardClass,
            legalActClass):
        self._env_dc = self.parameters.ENV_DC
        self.chronics_handler = chronics_handler
        self.backend = backend
        self._has_been_initialized(
        )  # really important to include this piece of code! and just here after the

        if not issubclass(legalActClass, BaseRules):
            raise Grid2OpException(
                "Parameter \"legalActClass\" used to build the Environment should derived form the "
                "grid2op.BaseRules class, type provided is \"{}\"".format(
                    type(legalActClass)))
        self._game_rules = RulesChecker(legalActClass=legalActClass)
        self._legalActClass = legalActClass
        # self._action_space = self._do_nothing
        self.backend.set_thermal_limit(self._thermal_limit_a)

        # create the opponent
        self._create_opponent()

        # create the attention budget
        self._create_attention_budget()
        self._obsClass = observationClass.init_grid(type(self.backend))
        self._obsClass._INIT_GRID_CLS = observationClass
        self.current_obs_init = self._obsClass(seed=None,
                                               obs_env=None,
                                               action_helper=None)
        self.current_obs = self.current_obs_init

        # backend has loaded everything
        self._hazard_duration = np.zeros(shape=self.n_line, dtype=dt_int)
Exemple #5
0
    def init_backend(self, init_grid_path, chronics_handler, backend,
                     names_chronics_to_backend, actionClass, observationClass,
                     rewardClass, legalActClass):
        """
        backend should not be the backend of the environment!!!

        Parameters
        ----------
        init_grid_path
        chronics_handler
        backend
        names_chronics_to_backend
        actionClass
        observationClass
        rewardClass
        legalActClass

        Returns
        -------

        """
        self.env_dc = self.parameters.FORECAST_DC
        self.chronics_handler = chronics_handler
        self.backend = backend
        self.init_grid(self.backend)
        self._has_been_initialized()
        self.obsClass = observationClass

        if not issubclass(legalActClass, BaseRules):
            raise Grid2OpException(
                "Parameter \"legalActClass\" used to build the Environment should derived form the "
                "grid2op.BaseRules class, type provided is \"{}\"".format(
                    type(legalActClass)))
        self.game_rules = RulesChecker(legalActClass=legalActClass)
        self.legalActClass = legalActClass
        self.helper_action_player = self._do_nothing
        self.backend.set_thermal_limit(self._thermal_limit_a)
        self._create_opponent()
Exemple #6
0
    def setUp(self):
        """
        The case file is a representation of the case14 as found in the ieee14 powergrid.
        :return:
        """
        # from ADNBackend import ADNBackend
        # self.backend = ADNBackend()
        # self.path_matpower = "/home/donnotben/Documents/RL4Grid/RL4Grid/data"
        # self.case_file = "ieee14_ADN.xml"
        # self.backend.load_grid(self.path_matpower, self.case_file)
        self.tolvect = 1e-2
        self.tol_one = 1e-5
        self.game_rules = RulesChecker()
        # pdb.set_trace()
        self.rewardClass = L2RPNReward
        self.reward_helper = self.rewardClass()
        self.obsClass = CompleteObservation
        self.parameters = Parameters()

        # powergrid
        self.backend = PandaPowerBackend()
        self.path_matpower = PATH_DATA_TEST_PP
        self.case_file = "test_case14.json"

        # chronics
        self.path_chron = os.path.join(PATH_CHRONICS, "chronics_with_hazards")
        self.chronics_handler = ChronicsHandler(
            chronicsClass=GridStateFromFile, path=self.path_chron)

        self.tolvect = 1e-2
        self.tol_one = 1e-5
        self.id_chron_to_back_load = np.array(
            [0, 1, 10, 2, 3, 4, 5, 6, 7, 8, 9])

        # force the verbose backend
        self.backend.detailed_infos_for_cascading_failures = True

        self.names_chronics_to_backend = {
            "loads": {
                "2_C-10.61": 'load_1_0',
                "3_C151.15": 'load_2_1',
                "14_C63.6": 'load_13_2',
                "4_C-9.47": 'load_3_3',
                "5_C201.84": 'load_4_4',
                "6_C-6.27": 'load_5_5',
                "9_C130.49": 'load_8_6',
                "10_C228.66": 'load_9_7',
                "11_C-138.89": 'load_10_8',
                "12_C-27.88": 'load_11_9',
                "13_C-13.33": 'load_12_10'
            },
            "lines": {
                '1_2_1': '0_1_0',
                '1_5_2': '0_4_1',
                '9_10_16': '8_9_2',
                '9_14_17': '8_13_3',
                '10_11_18': '9_10_4',
                '12_13_19': '11_12_5',
                '13_14_20': '12_13_6',
                '2_3_3': '1_2_7',
                '2_4_4': '1_3_8',
                '2_5_5': '1_4_9',
                '3_4_6': '2_3_10',
                '4_5_7': '3_4_11',
                '6_11_11': '5_10_12',
                '6_12_12': '5_11_13',
                '6_13_13': '5_12_14',
                '4_7_8': '3_6_15',
                '4_9_9': '3_8_16',
                '5_6_10': '4_5_17',
                '7_8_14': '6_7_18',
                '7_9_15': '6_8_19'
            },
            "prods": {
                "1_G137.1": 'gen_0_4',
                "3_G36.31": "gen_2_1",
                "6_G63.29": "gen_5_2",
                "2_G-56.47": "gen_1_0",
                "8_G40.43": "gen_7_3"
            },
        }

        # _parameters for the environment
        self.env_params = Parameters()
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore")
            self.env = Environment(
                init_grid_path=os.path.join(self.path_matpower,
                                            self.case_file),
                backend=self.backend,
                chronics_handler=self.chronics_handler,
                parameters=self.env_params,
                names_chronics_to_backend=self.names_chronics_to_backend,
                rewardClass=self.rewardClass,
                name="test_obs_env1")
Exemple #7
0
    def init_backend(self, init_grid_path, chronics_handler, backend,
                     names_chronics_to_backend, actionClass, observationClass,
                     rewardClass, legalActClass):

        if not isinstance(rewardClass, type):
            raise Grid2OpException(
                "Parameter \"rewardClass\" used to build the Environment should be a type (a class) "
                "and not an object (an instance of a class). "
                "It is currently \"{}\"".format(type(rewardClass)))
        if not issubclass(rewardClass, BaseReward):
            raise Grid2OpException(
                "Parameter \"rewardClass\" used to build the Environment should derived form the grid2op.BaseReward class, "
                "type provided is \"{}\"".format(type(rewardClass)))
        self.rewardClass = rewardClass
        self.actionClass = actionClass
        self.observationClass = observationClass

        # backend
        self.init_grid_path = os.path.abspath(init_grid_path)

        if not isinstance(backend, Backend):
            raise Grid2OpException(
                "Parameter \"backend\" used to build the Environment should derived form the grid2op.Backend class, "
                "type provided is \"{}\"".format(type(backend)))
        self.backend = backend
        self.backend.load_grid(
            self.init_grid_path)  # the real powergrid of the environment

        self.backend.load_redispacthing_data(
            os.path.split(self.init_grid_path)[0])
        self.backend.load_grid_layout(os.path.split(self.init_grid_path)[0])

        self.backend.assert_grid_correct()
        self.init_grid(backend)
        self._has_been_initialized(
        )  # really important to include this piece of code!

        if self._thermal_limit_a is None:
            self._thermal_limit_a = self.backend.thermal_limit_a
        else:
            self.backend.set_thermal_limit(self._thermal_limit_a)

        *_, tmp = self.backend.generators_info()

        # rules of the game
        if not isinstance(legalActClass, type):
            raise Grid2OpException(
                "Parameter \"legalActClass\" used to build the Environment should be a type "
                "(a class) and not an object (an instance of a class). "
                "It is currently \"{}\"".format(type(legalActClass)))
        if not issubclass(legalActClass, BaseRules):
            raise Grid2OpException(
                "Parameter \"legalActClass\" used to build the Environment should derived form the "
                "grid2op.BaseRules class, type provided is \"{}\"".format(
                    type(legalActClass)))
        self.game_rules = RulesChecker(legalActClass=legalActClass)
        self.legalActClass = legalActClass

        # action helper
        if not isinstance(actionClass, type):
            raise Grid2OpException(
                "Parameter \"actionClass\" used to build the Environment should be a type (a class) "
                "and not an object (an instance of a class). "
                "It is currently \"{}\"".format(type(legalActClass)))
        if not issubclass(actionClass, BaseAction):
            raise Grid2OpException(
                "Parameter \"actionClass\" used to build the Environment should derived form the "
                "grid2op.BaseAction class, type provided is \"{}\"".format(
                    type(actionClass)))

        if not isinstance(observationClass, type):
            raise Grid2OpException(
                "Parameter \"actionClass\" used to build the Environment should be a type (a class) "
                "and not an object (an instance of a class). "
                "It is currently \"{}\"".format(type(legalActClass)))
        if not issubclass(observationClass, BaseObservation):
            raise Grid2OpException(
                "Parameter \"observationClass\" used to build the Environment should derived form the "
                "grid2op.BaseObservation class, type provided is \"{}\"".
                format(type(observationClass)))

        # action affecting the grid that will be made by the agent
        self.helper_action_player = ActionSpace(
            gridobj=self.backend,
            actionClass=actionClass,
            legal_action=self.game_rules.legal_action)

        # action that affect the grid made by the environment.
        self.helper_action_env = ActionSpace(
            gridobj=self.backend,
            actionClass=CompleteAction,
            legal_action=self.game_rules.legal_action)

        self.helper_observation = ObservationSpace(
            gridobj=self.backend,
            observationClass=observationClass,
            rewardClass=rewardClass,
            env=self)

        # handles input data
        if not isinstance(chronics_handler, ChronicsHandler):
            raise Grid2OpException(
                "Parameter \"chronics_handler\" used to build the Environment should derived form the "
                "grid2op.ChronicsHandler class, type provided is \"{}\"".
                format(type(chronics_handler)))
        self.chronics_handler = chronics_handler
        self.chronics_handler.initialize(
            self.name_load,
            self.name_gen,
            self.name_line,
            self.name_sub,
            names_chronics_to_backend=names_chronics_to_backend)
        self.names_chronics_to_backend = names_chronics_to_backend

        # test to make sure the backend is consistent with the chronics generator
        self.chronics_handler.check_validity(self.backend)

        # reward function
        self.reward_helper = RewardHelper(self.rewardClass)
        self.reward_helper.initialize(self)
        for k, v in self.other_rewards.items():
            v.initialize(self)

        # controler for voltage
        if not issubclass(self.voltagecontrolerClass, BaseVoltageController):
            raise Grid2OpException(
                "Parameter \"voltagecontrolClass\" should derive from \"ControlVoltageFromFile\"."
            )

        self.voltage_controler = self.voltagecontrolerClass(
            gridobj=self.backend, controler_backend=self.backend)

        # create the opponent
        # At least the 3 following attributes should be set before calling _create_opponent
        # self.opponent_action_class
        # self.opponent_class
        # self.opponent_init_budget
        self._create_opponent()

        # performs one step to load the environment properly (first action need to be taken at first time step after
        # first injections given)
        self._reset_maintenance()
        do_nothing = self.helper_action_env({})
        *_, fail_to_start, info = self.step(do_nothing)
        if fail_to_start:
            raise Grid2OpException(
                "Impossible to initialize the powergrid, the powerflow diverge at iteration 0. "
                "Available information are: {}".format(info))

        # test the backend returns object of the proper size
        self.backend.assert_grid_correct_after_powerflow()

        # for gym compatibility
        self.action_space = self.helper_action_player  # this should be an action !!!
        self.observation_space = self.helper_observation  # this return an observation.
        self.reward_range = self.reward_helper.range()
        self.viewer = None

        self.metadata = {'render.modes': ["human", "rgb_array"]}
        self.spec = None

        self.current_reward = self.reward_range[0]
        self.done = False

        # reset everything to be consistent
        self._reset_vectors_and_timings()
Exemple #8
0
    def setUp(self):
        """
        The case file is a representation of the case14 as found in the ieee14 powergrid.
        :return:
        """
        self.tolvect = 1e-2
        self.tol_one = 1e-5
        self.game_rules = RulesChecker()
        self.gridobj = GridObjects()
        self.gridobj.init_grid_vect(
            name_prod=["gen_{}".format(i) for i in range(5)],
            name_load=["load_{}".format(i) for i in range(11)],
            name_line=["line_{}".format(i) for i in range(20)],
            name_sub=["sub_{}".format(i) for i in range(14)],
            sub_info=np.array([3, 6, 4, 6, 5, 6, 3, 2, 5, 3, 3, 3, 4, 3],
                              dtype=np.int),
            load_to_subid=np.array([1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13]),
            gen_to_subid=np.array([0, 1, 2, 5, 7]),
            line_or_to_subid=np.array(
                [0, 0, 1, 1, 1, 2, 3, 3, 3, 4, 5, 5, 5, 6, 6, 8, 8, 9, 11,
                 12]),
            line_ex_to_subid=np.array([
                1, 4, 2, 3, 4, 3, 4, 6, 8, 5, 10, 11, 12, 7, 8, 9, 13, 10, 12,
                13
            ]),
            load_to_sub_pos=np.array([4, 2, 5, 4, 4, 4, 1, 1, 1, 2, 1]),
            gen_to_sub_pos=np.array([2, 5, 3, 5, 1]),
            line_or_to_sub_pos=np.array(
                [0, 1, 1, 2, 3, 1, 2, 3, 4, 3, 1, 2, 3, 1, 2, 2, 3, 0, 0, 1]),
            line_ex_to_sub_pos=np.array(
                [0, 0, 0, 0, 1, 1, 2, 0, 0, 0, 2, 2, 3, 0, 1, 2, 2, 0, 0, 0]),
            load_pos_topo_vect=np.array(
                [7, 11, 18, 23, 28, 39, 41, 44, 47, 51, 54]),
            gen_pos_topo_vect=np.array([2, 8, 12, 29, 34]),
            line_or_pos_topo_vect=np.array([
                0, 1, 4, 5, 6, 10, 15, 16, 17, 22, 25, 26, 27, 31, 32, 37, 38,
                40, 46, 50
            ]),
            line_ex_pos_topo_vect=np.array([
                3, 19, 9, 13, 20, 14, 21, 30, 35, 24, 45, 48, 52, 33, 36, 42,
                55, 43, 49, 53
            ]))
        # pdb.set_trace()
        self.res = {
            'name_gen': ['gen_0', 'gen_1', 'gen_2', 'gen_3', 'gen_4'],
            'name_load': [
                'load_0', 'load_1', 'load_2', 'load_3', 'load_4', 'load_5',
                'load_6', 'load_7', 'load_8', 'load_9', 'load_10'
            ],
            'name_line': [
                'line_0', 'line_1', 'line_2', 'line_3', 'line_4', 'line_5',
                'line_6', 'line_7', 'line_8', 'line_9', 'line_10', 'line_11',
                'line_12', 'line_13', 'line_14', 'line_15', 'line_16',
                'line_17', 'line_18', 'line_19'
            ],
            'name_sub': [
                'sub_0', 'sub_1', 'sub_2', 'sub_3', 'sub_4', 'sub_5', 'sub_6',
                'sub_7', 'sub_8', 'sub_9', 'sub_10', 'sub_11', 'sub_12',
                'sub_13'
            ],
            'sub_info': [3, 6, 4, 6, 5, 6, 3, 2, 5, 3, 3, 3, 4, 3],
            'load_to_subid': [1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13],
            'gen_to_subid': [0, 1, 2, 5, 7],
            'line_or_to_subid':
            [0, 0, 1, 1, 1, 2, 3, 3, 3, 4, 5, 5, 5, 6, 6, 8, 8, 9, 11, 12],
            'line_ex_to_subid': [
                1, 4, 2, 3, 4, 3, 4, 6, 8, 5, 10, 11, 12, 7, 8, 9, 13, 10, 12,
                13
            ],
            'load_to_sub_pos': [4, 2, 5, 4, 4, 4, 1, 1, 1, 2, 1],
            'gen_to_sub_pos': [2, 5, 3, 5, 1],
            'line_or_to_sub_pos':
            [0, 1, 1, 2, 3, 1, 2, 3, 4, 3, 1, 2, 3, 1, 2, 2, 3, 0, 0, 1],
            'line_ex_to_sub_pos':
            [0, 0, 0, 0, 1, 1, 2, 0, 0, 0, 2, 2, 3, 0, 1, 2, 2, 0, 0, 0],
            'load_pos_topo_vect': [7, 11, 18, 23, 28, 39, 41, 44, 47, 51, 54],
            'gen_pos_topo_vect': [2, 8, 12, 29, 34],
            'line_or_pos_topo_vect': [
                0, 1, 4, 5, 6, 10, 15, 16, 17, 22, 25, 26, 27, 31, 32, 37, 38,
                40, 46, 50
            ],
            'line_ex_pos_topo_vect': [
                3, 19, 9, 13, 20, 14, 21, 30, 35, 24, 45, 48, 52, 33, 36, 42,
                55, 43, 49, 53
            ],
            'gen_type':
            None,
            'gen_pmin':
            None,
            'gen_pmax':
            None,
            'gen_redispatchable':
            None,
            'gen_max_ramp_up':
            None,
            'gen_max_ramp_down':
            None,
            'gen_min_uptime':
            None,
            'gen_min_downtime':
            None,
            'gen_cost_per_MW':
            None,
            'gen_startup_cost':
            None,
            'gen_shutdown_cost':
            None,
            "grid_layout":
            None,
            "shunt_to_subid":
            None,
            "name_shunt":
            None
        }

        # self.size_act = 229

        # self.helper_action = ActionSpace(self.gridobj, legal_action=self.game_rules.legal_action)
        self.helper_action = self._action_setup()
        save_to_dict(self.res, self.helper_action, "subtype",
                     lambda x: re.sub("(<class ')|('>)", "", "{}".format(x)))
        # print(self.res["subtype"])
        self.authorized_keys = self.helper_action().authorized_keys
        self.size_act = self.helper_action.size()
Exemple #9
0
    def _init_backend(self, init_grid_path, chronics_handler, backend,
                      names_chronics_to_backend, actionClass, observationClass,
                      rewardClass, legalActClass):
        """
        INTERNAL

        .. warning:: /!\\\\ Internal, do not use unless you know what you are doing /!\\\\

        Create a proper and valid environment.
        """

        if not isinstance(rewardClass, type):
            raise Grid2OpException(
                "Parameter \"rewardClass\" used to build the Environment should be a type (a class) "
                "and not an object (an instance of a class). "
                "It is currently \"{}\"".format(type(rewardClass)))
        if not issubclass(rewardClass, BaseReward):
            raise Grid2OpException(
                "Parameter \"rewardClass\" used to build the Environment should derived form "
                "the grid2op.BaseReward class, type provided is \"{}\"".format(
                    type(rewardClass)))
        self._rewardClass = rewardClass
        self._actionClass = actionClass
        self._observationClass = observationClass

        # backend
        self._init_grid_path = os.path.abspath(init_grid_path)

        if not isinstance(backend, Backend):
            raise Grid2OpException(
                "Parameter \"backend\" used to build the Environment should derived form the "
                "grid2op.Backend class, type provided is \"{}\"".format(
                    type(backend)))
        self.backend = backend
        # all the above should be done in this exact order, otherwise some weird behaviour might occur
        # this is due to the class attribute
        self.backend.set_env_name(self.name)
        self.backend.load_grid(
            self._init_grid_path)  # the real powergrid of the environment
        self.backend.load_redispacthing_data(self.get_path_env())
        self.backend.load_storage_data(self.get_path_env())
        self.backend.load_grid_layout(self.get_path_env())
        self.backend.assert_grid_correct()
        self._has_been_initialized(
        )  # really important to include this piece of code! and just here after the
        # backend has loaded everything
        self._line_status = np.ones(shape=self.n_line, dtype=dt_bool)

        if self._thermal_limit_a is None:
            self._thermal_limit_a = self.backend.thermal_limit_a.astype(
                dt_float)
        else:
            self.backend.set_thermal_limit(
                self._thermal_limit_a.astype(dt_float))

        *_, tmp = self.backend.generators_info()

        # rules of the game
        if not isinstance(legalActClass, type):
            raise Grid2OpException(
                "Parameter \"legalActClass\" used to build the Environment should be a type "
                "(a class) and not an object (an instance of a class). "
                "It is currently \"{}\"".format(type(legalActClass)))
        if not issubclass(legalActClass, BaseRules):
            raise Grid2OpException(
                "Parameter \"legalActClass\" used to build the Environment should derived form the "
                "grid2op.BaseRules class, type provided is \"{}\"".format(
                    type(legalActClass)))
        self._game_rules = RulesChecker(legalActClass=legalActClass)
        self._legalActClass = legalActClass

        # action helper
        if not isinstance(actionClass, type):
            raise Grid2OpException(
                "Parameter \"actionClass\" used to build the Environment should be a type (a class) "
                "and not an object (an instance of a class). "
                "It is currently \"{}\"".format(type(legalActClass)))
        if not issubclass(actionClass, BaseAction):
            raise Grid2OpException(
                "Parameter \"actionClass\" used to build the Environment should derived form the "
                "grid2op.BaseAction class, type provided is \"{}\"".format(
                    type(actionClass)))

        if not isinstance(observationClass, type):
            raise Grid2OpException(
                "Parameter \"actionClass\" used to build the Environment should be a type (a class) "
                "and not an object (an instance of a class). "
                "It is currently \"{}\"".format(type(legalActClass)))
        if not issubclass(observationClass, BaseObservation):
            raise Grid2OpException(
                "Parameter \"observationClass\" used to build the Environment should derived form the "
                "grid2op.BaseObservation class, type provided is \"{}\"".
                format(type(observationClass)))

        # action affecting the grid that will be made by the agent
        self._helper_action_class = ActionSpace.init_grid(gridobj=self.backend)
        self._helper_action_player = self._helper_action_class(
            gridobj=self.backend,
            actionClass=actionClass,
            legal_action=self._game_rules.legal_action)

        # action that affect the grid made by the environment.
        self._helper_action_env = self._helper_action_class(
            gridobj=self.backend,
            actionClass=CompleteAction,
            legal_action=self._game_rules.legal_action)
        self._helper_observation_class = ObservationSpace.init_grid(
            gridobj=self.backend)
        self._helper_observation = self._helper_observation_class(
            gridobj=self.backend,
            observationClass=observationClass,
            rewardClass=rewardClass,
            env=self)
        # handles input data
        if not isinstance(chronics_handler, ChronicsHandler):
            raise Grid2OpException(
                "Parameter \"chronics_handler\" used to build the Environment should derived form the "
                "grid2op.ChronicsHandler class, type provided is \"{}\"".
                format(type(chronics_handler)))
        self.chronics_handler = chronics_handler
        self.chronics_handler.initialize(
            self.name_load,
            self.name_gen,
            self.name_line,
            self.name_sub,
            names_chronics_to_backend=names_chronics_to_backend)
        self.names_chronics_to_backend = names_chronics_to_backend

        # test to make sure the backend is consistent with the chronics generator
        self.chronics_handler.check_validity(self.backend)
        self.delta_time_seconds = dt_float(
            self.chronics_handler.time_interval.seconds)
        self._reset_storage(
        )  # this should be called after the  self.delta_time_seconds is set

        # reward function
        self._reward_helper = RewardHelper(self._rewardClass)
        self._reward_helper.initialize(self)
        for k, v in self.other_rewards.items():
            v.initialize(self)

        # controller for voltage
        if not issubclass(self._voltagecontrolerClass, BaseVoltageController):
            raise Grid2OpException(
                "Parameter \"voltagecontrolClass\" should derive from \"ControlVoltageFromFile\"."
            )

        self._voltage_controler = self._voltagecontrolerClass(
            gridobj=self.backend, controler_backend=self.backend)

        # create the opponent
        # At least the 3 following attributes should be set before calling _create_opponent
        self._create_opponent()

        # performs one step to load the environment properly (first action need to be taken at first time step after
        # first injections given)
        self._reset_maintenance()
        self._reset_redispatching()
        do_nothing = self._helper_action_env({})
        *_, fail_to_start, info = self.step(do_nothing)
        if fail_to_start:
            raise Grid2OpException(
                "Impossible to initialize the powergrid, the powerflow diverge at iteration 0. "
                "Available information are: {}".format(info))

        # test the backend returns object of the proper size
        self.backend.assert_grid_correct_after_powerflow()

        # for gym compatibility
        self.action_space = self._helper_action_player  # this should be an action !!!
        self.observation_space = self._helper_observation  # this return an observation.
        self.reward_range = self._reward_helper.range()
        self.viewer = None
        self.viewer_fig = None

        self.metadata = {'render.modes': []}
        self.spec = None

        self.current_reward = self.reward_range[0]
        self.done = False

        # reset everything to be consistent
        self._reset_vectors_and_timings()