Esempio n. 1
0
    def test_check_valid(self):
        """test the param.check_valid() is working correctly (accept valid param, reject wrong param)"""
        p = Parameters()
        p.check_valid()  # default params are valid

        # boolean attribute
        p.NO_OVERFLOW_DISCONNECTION = 1
        with self.assertRaises(RuntimeError):
            p.check_valid()
        p.NO_OVERFLOW_DISCONNECTION = True
        p.IGNORE_MIN_UP_DOWN_TIME = "True"
        with self.assertRaises(RuntimeError):
            p.check_valid()
        p.IGNORE_MIN_UP_DOWN_TIME = True
        p.ACTIVATE_STORAGE_LOSS = 42.
        with self.assertRaises(RuntimeError):
            p.check_valid()
        p.ACTIVATE_STORAGE_LOSS = False
        p.ENV_DC = [1, 2]
        with self.assertRaises(RuntimeError):
            p.check_valid()
        p.ENV_DC = True
        p.ALLOW_DISPATCH_GEN_SWITCH_OFF = {1, 2}
        with self.assertRaises(RuntimeError):
            p.check_valid()
        p.ALLOW_DISPATCH_GEN_SWITCH_OFF = False
        p.check_valid()  # everything valid again

        # int types
        for attr_nm in [
                "NB_TIMESTEP_OVERFLOW_ALLOWED", "NB_TIMESTEP_RECONNECTION",
                "NB_TIMESTEP_COOLDOWN_LINE", "NB_TIMESTEP_COOLDOWN_SUB",
                "MAX_SUB_CHANGED", "MAX_LINE_STATUS_CHANGED"
        ]:
            try:
                self._aux_check_attr_int(p, attr_nm)
            except Exception as exc_:
                raise RuntimeError(
                    f"Exception \"{exc_}\" for attribute \"{attr_nm}\"")
        # float types
        for attr_nm in ["HARD_OVERFLOW_THRESHOLD", "INIT_STORAGE_CAPACITY"]:
            try:
                self._aux_check_attr_float(p, attr_nm)
            except Exception as exc_:
                raise RuntimeError(
                    f"Exception \"{exc_}\" for attribute \"{attr_nm}\"")

        p.HARD_OVERFLOW_THRESHOLD = 0.5  # should not validate
        with self.assertRaises(RuntimeError):
            p.check_valid()
        p.ACTIVATE_STORAGE_LOSS = -0.1  # should not validate
        with self.assertRaises(RuntimeError):
            p.check_valid()
        p.ACTIVATE_STORAGE_LOSS = 1.1  # should not validate
        with self.assertRaises(RuntimeError):
            p.check_valid()
Esempio n. 2
0
    def test_activate_storage_loss(self):
        """
        test that the parameters param.ACTIVATE_STORAGE_LOSS properly deactivate the loss in the storage
        units
        """
        # first test the storage loss
        act = self.env.action_space()
        loss = 1.0 * self.env.storage_loss
        loss /= 12.  # i have 12 steps per hour (ts = (mins), losses are given in MW and capacity in MWh
        for nb_ts in range(5):
            obs, reward, done, info = self.env.step(act)
            assert np.all(np.abs(obs.storage_charge - (0.5 * obs.storage_Emax - (nb_ts + 1) * loss)) <= self.tol_one), \
                   f"wrong value computed for time step {nb_ts}"

        param = Parameters()
        param.ACTIVATE_STORAGE_LOSS = False
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore")
            env = grid2op.make("educ_case14_storage", test=True, param=param)
        obs = env.get_obs()
        assert np.all(
            np.abs(obs.storage_charge - 0.5 * obs.storage_Emax) <= self.tol_one
        ), "wrong initial capacity"
        for nb_ts in range(5):
            obs, reward, done, info = env.step(act)
            assert np.all(np.abs(obs.storage_charge - 0.5 * obs.storage_Emax) <= self.tol_one), \
                   f"wrong value computed for time step {nb_ts} (no loss in storage)"
Esempio n. 3
0
    def test_storage_loss_dont_make_negative(self):
        """
        test that the storage loss dont make negative capacity
        or in other words that loss don't apply when storage are empty
        """
        init_coeff = 0.01
        param = Parameters()
        param.ACTIVATE_STORAGE_LOSS = True
        param.INIT_STORAGE_CAPACITY = init_coeff
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore")
            env = grid2op.make("educ_case14_storage", test=True, param=param)
        obs = env.get_obs()
        init_charge = init_coeff * obs.storage_Emax
        loss = 1.0 * env.storage_loss
        loss /= 12.  # i have 12 steps per hour (ts =  5mins, losses are given in MW and capacity in MWh
        act = env.action_space()

        assert np.all(
            np.abs(obs.storage_charge -
                   init_charge) <= self.tol_one), "wrong initial capacity"
        for nb_ts in range(8):
            obs, reward, done, info = env.step(act)
            assert np.all(np.abs(obs.storage_charge - (init_charge - (nb_ts + 1) * loss)) <= self.tol_one), \
                f"wrong value computed for time step {nb_ts} (with loss in storage)"

        # now a loss should 'cap' the second battery
        obs, reward, done, info = env.step(act)
        th_storage = (init_charge - (nb_ts + 1) * loss)
        th_storage[0] -= loss[0]
        th_storage[1] = 0.
        assert np.all(np.abs(obs.storage_charge - th_storage) <= self.tol_one)
        for nb_ts in range(9):
            obs, reward, done, info = env.step(act)
            th_storage[0] -= loss[0]
            assert np.all(np.abs(obs.storage_charge - th_storage) <= self.tol_one), \
                f"capacity error for time step {nb_ts}"

        # all storages are empty
        obs, reward, done, info = env.step(act)
        assert np.all(np.abs(obs.storage_charge) <= self.tol_one
                      ), "error battery should be empty - 0"
        obs, reward, done, info = env.step(act)
        assert np.all(np.abs(obs.storage_charge) <= self.tol_one
                      ), "error, battery should be empty - 1"
        obs, reward, done, info = env.step(act)
        assert np.all(np.abs(obs.storage_charge) <= self.tol_one
                      ), "error, battery should be empty - 2"
Esempio n. 4
0
    def test_env_storage_cut_because_too_low_withloss(self):
        """test the correct behaviour is met when storage energy would be too low (need to cut the action)"""
        init_coeff = 0.01
        param = Parameters()
        param.ACTIVATE_STORAGE_LOSS = True
        param.INIT_STORAGE_CAPACITY = init_coeff
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore")
            env = grid2op.make("educ_case14_storage", test=True, param=param)
        self.env.close()
        self.env = env

        obs = self.env.reset()
        init_storage = np.array([0.14999999, 0.07], dtype=dt_float)
        assert np.all(
            np.abs(obs.storage_charge - init_storage) <= self.tol_one)

        loss = 1.0 * env.storage_loss
        loss /= 12.  # i have 12 steps per hour (ts =  5mins, losses are given in MW and capacity in MWh)

        # too high in second battery, ok for first step
        array_modif = np.array([-1.5, -10.], dtype=dt_float)
        act = self.env.action_space({"set_storage": array_modif})
        obs, reward, done, info = self.env.step(act)
        assert not info["exception"]
        assert np.all(
            np.abs(obs.storage_power_target - array_modif) <= self.tol_one)
        assert np.abs(np.sum(obs.actual_dispatch) -
                      np.sum(obs.storage_power)) <= self.tol_one
        assert np.all(obs.storage_charge >= self.env.storage_Emin)
        assert np.all(obs.storage_power <= 0.)  # I emptied the battery
        bat_energy_added = obs.storage_power / 12.  # amount of energy if the power is maintained for 5mins
        # there are inefficiencies (I remove MORE energy from the battery than what i get in the grid)
        bat_energy_added /= obs.storage_discharging_efficiency
        # below i said [loss[0], 0.] because i don't have loss on an empty battery
        assert np.all(
            np.abs(obs.storage_charge - (bat_energy_added + init_storage -
                                         [loss[0], 0.])) <= self.tol_one)
        # only the loss makes the second storage unit not full
        assert np.abs(obs.storage_charge[1] -
                      (self.env.storage_Emin[1])) <= self.tol_one
        state_of_charge = 1. * obs.storage_charge

        # after this action both batteries are capped
        obs, reward, done, info = self.env.step(act)
        assert not info["exception"]
        assert np.all(
            np.abs(obs.storage_power_target - array_modif) <= self.tol_one)
        assert np.abs(np.sum(obs.actual_dispatch) -
                      np.sum(obs.storage_power)) <= self.tol_one
        assert np.all(obs.storage_charge >= self.env.storage_Emin)
        assert np.all(obs.storage_power <= 0.)  # I emptied the battery
        # second battery cannot be discharged more
        assert np.abs(obs.storage_power[1] - 0.) <= self.tol_one
        # all batteries are charged at minimum now (only because Emin is 0.)
        assert np.all(
            np.abs(obs.storage_charge - self.env.storage_Emin) <= self.tol_one)
        bat_energy_added = 1.0 * obs.storage_power / 12.  # amount of energy if the power is maintained for 5mins
        # there are inefficiencies (I remove MORE energy from the battery than what i get in the grid)
        bat_energy_added /= obs.storage_discharging_efficiency  # there are inefficiencies
        # below i said [0., 0.] because i don't have loss on an empty battery
        assert np.all(
            np.abs(obs.storage_charge - (bat_energy_added + state_of_charge -
                                         [0., 0.])) <= self.tol_one)
        state_of_charge = 1. * obs.storage_charge

        # both batteries are at maximum, i can only charge them of the losses
        obs, reward, done, info = self.env.step(act)
        assert not info["exception"]
        assert np.all(
            np.abs(obs.storage_power_target - array_modif) <= self.tol_one)
        assert np.abs(np.sum(obs.actual_dispatch) -
                      np.sum(obs.storage_power)) <= self.tol_one
        assert np.all(obs.storage_charge >= self.env.storage_Emin)
        assert np.all(obs.storage_power <= 0.)  # I emptied the battery
        # second battery cannot be discharged more than it is
        assert np.all(np.abs(obs.storage_power - 0.) <= self.tol_one)
        # all batteries are charged at maximum now
        assert np.all(
            np.abs(obs.storage_charge - self.env.storage_Emin) <= self.tol_one)
        bat_energy_added = 1.0 * obs.storage_power / 12.  # amount of energy if the power is maintained for 5mins
        # there are inefficiencies (I remove MORE energy from the battery than what i get in the grid)
        bat_energy_added /= obs.storage_discharging_efficiency  # there are inefficiencies
        # below i said [0., 0.] because i don't have loss on an empty battery
        assert np.all(
            np.abs(obs.storage_charge - (bat_energy_added + state_of_charge -
                                         [0., 0.])) <= self.tol_one)
Esempio n. 5
0
    def test_env_storage_cut_because_too_low_noloss(self):
        """
        test the correct behaviour is met when storage energy would be too low (need to cut the action)
        and we don't take into account the loss and inefficiencies
        """
        init_coeff = 0.01
        param = Parameters()
        param.ACTIVATE_STORAGE_LOSS = False  # to simplify the computation, in this first test
        param.INIT_STORAGE_CAPACITY = init_coeff
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore")
            env = grid2op.make("educ_case14_storage", test=True, param=param)
        self.env.close()
        self.env = env

        obs = self.env.reset()
        init_storage = np.array([0.14999999, 0.07], dtype=dt_float)
        assert np.all(
            np.abs(obs.storage_charge - init_storage) <= self.tol_one)

        # too high in second battery, ok for first step
        array_modif = np.array([-1.5, -10.], dtype=dt_float)
        act = self.env.action_space({"set_storage": array_modif})
        obs, reward, done, info = self.env.step(act)
        assert not info["exception"]
        assert np.all(
            np.abs(obs.storage_power_target - array_modif) <= self.tol_one)
        assert np.abs(np.sum(obs.actual_dispatch) -
                      np.sum(obs.storage_power)) <= self.tol_one
        assert np.all(obs.storage_charge >= self.env.storage_Emin)
        bat_energy_added = obs.storage_power / 12.  # amount of energy if the power is maintained for 5mins
        assert np.all(
            np.abs(obs.storage_charge -
                   (bat_energy_added + init_storage)) <= self.tol_one)
        state_of_charge = 1. * obs.storage_charge

        # now both batteries are capped
        obs, reward, done, info = self.env.step(act)
        assert not info["exception"]
        assert np.all(
            np.abs(obs.storage_power_target - array_modif) <= self.tol_one)
        assert np.abs(np.sum(obs.actual_dispatch) -
                      np.sum(obs.storage_power)) <= self.tol_one
        assert np.all(obs.storage_charge >= self.env.storage_Emin)
        assert np.abs(obs.storage_power[1]
                      ) <= self.tol_one  # second battery cannot charge anymore
        bat_energy_added = obs.storage_power / 12.  # amount of energy if the power is maintained for 5mins
        assert np.all(
            np.abs(obs.storage_charge -
                   (bat_energy_added + state_of_charge)) <= self.tol_one)
        state_of_charge = 1. * obs.storage_charge

        # now both batteries are capped
        obs, reward, done, info = self.env.step(act)
        assert not info["exception"]
        assert np.all(
            np.abs(obs.storage_power_target - array_modif) <= self.tol_one)
        assert np.abs(np.sum(obs.actual_dispatch) -
                      np.sum(obs.storage_power)) <= self.tol_one
        assert np.all(obs.storage_charge >= self.env.storage_Emin)
        assert np.all(np.abs(obs.storage_power) <=
                      self.tol_one)  # all batteries cannot charge anymore
        bat_energy_added = obs.storage_power / 12.  # amount of energy if the power is maintained for 5mins
        assert np.all(
            np.abs(obs.storage_charge -
                   (bat_energy_added + state_of_charge)) <= self.tol_one)
Esempio n. 6
0
    def test_env_storage_cut_because_too_high_withloss(self):
        """test the correct behaviour is met when storage energy would be too high (need to cut DOWN the action)"""
        init_coeff = 0.99
        param = Parameters()
        param.ACTIVATE_STORAGE_LOSS = True
        param.INIT_STORAGE_CAPACITY = init_coeff
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore")
            env = grid2op.make("educ_case14_storage", test=True, param=param)
        self.env.close()
        self.env = env

        obs = self.env.reset()
        init_storage = np.array([14.85, 6.9300003], dtype=dt_float)
        assert np.all(
            np.abs(obs.storage_charge - init_storage) <= self.tol_one)

        loss = 1.0 * env.storage_loss
        loss /= 12.  # i have 12 steps per hour (ts =  5mins, losses are given in MW and capacity in MWh)

        # too high in second battery, ok for first step
        array_modif = np.array([1.5, 10.], dtype=dt_float)
        act = self.env.action_space({"set_storage": array_modif})
        obs, reward, done, info = self.env.step(act)
        assert not info["exception"]
        assert np.all(
            np.abs(obs.storage_power_target - array_modif) <= self.tol_one)
        assert np.abs(np.sum(obs.actual_dispatch) -
                      np.sum(obs.storage_power)) <= self.tol_one
        assert np.all(obs.storage_charge <= self.env.storage_Emax)
        bat_energy_added = obs.storage_power / 12.  # amount of energy if the power is maintained for 5mins
        bat_energy_added *= obs.storage_charging_efficiency  # there are inefficiencies
        assert np.all(
            np.abs(obs.storage_charge -
                   (bat_energy_added + init_storage - loss)) <= self.tol_one)
        # only the loss makes the second storage unit not full
        assert np.abs(obs.storage_charge[1] -
                      (self.env.storage_Emax[1] - loss[1])) <= self.tol_one
        state_of_charge = 1. * obs.storage_charge

        # after this action both batteries are capped
        obs, reward, done, info = self.env.step(act)
        assert not info["exception"]
        assert np.all(
            np.abs(obs.storage_power_target - array_modif) <= self.tol_one)
        assert np.abs(np.sum(obs.actual_dispatch) -
                      np.sum(obs.storage_power)) <= self.tol_one
        assert np.all(obs.storage_charge <= self.env.storage_Emax)
        # second battery cannot charge more than the loss
        val = env.storage_loss[1] / self.env.storage_charging_efficiency[1]
        assert np.abs(obs.storage_power[1] - val) <= self.tol_one
        # all batteries are charged at maximum now
        assert np.all(
            np.abs(obs.storage_charge -
                   (self.env.storage_Emax - loss)) <= self.tol_one)
        bat_energy_added = 1.0 * obs.storage_power / 12.  # amount of energy if the power is maintained for 5mins
        bat_energy_added *= obs.storage_charging_efficiency  # there are inefficiencies
        assert np.all(
            np.abs(obs.storage_charge - (bat_energy_added + state_of_charge -
                                         loss)) <= self.tol_one)
        state_of_charge = 1. * obs.storage_charge

        # both batteries are at maximum, i can only charge them of the losses
        obs, reward, done, info = self.env.step(act)
        assert not info["exception"]
        assert np.all(
            np.abs(obs.storage_power_target - array_modif) <= self.tol_one)
        assert np.abs(np.sum(obs.actual_dispatch) -
                      np.sum(obs.storage_power)) <= self.tol_one
        assert np.all(obs.storage_charge <= self.env.storage_Emax)
        # second battery cannot charge more than the loss
        val = env.storage_loss / self.env.storage_charging_efficiency
        assert np.all(np.abs(obs.storage_power - val) <= self.tol_one)
        # all batteries are charged at maximum now
        assert np.all(
            np.abs(obs.storage_charge -
                   (self.env.storage_Emax - loss)) <= self.tol_one)
        bat_energy_added = 1.0 * obs.storage_power / 12.  # amount of energy if the power is maintained for 5mins
        bat_energy_added *= obs.storage_charging_efficiency  # there are inefficiencies
        assert np.all(
            np.abs(obs.storage_charge - (bat_energy_added + state_of_charge -
                                         loss)) <= self.tol_one)