@@ -339,7 +339,7 @@ class BaseAction(GridObjects):
339339 Typically `0 <= storage_id < env.n_storage` and `amount` is a floating point between the maximum
340340 power and minimum power the storage unit can absorb / produce.
341341
342- Finally, in order to perform curtailment action on renewable generators, you can:
342+ In order to perform curtailment action on renewable generators, you can:
343343
344344 .. code-block:: python
345345
@@ -354,7 +354,40 @@ class BaseAction(GridObjects):
354354 giving the limit of power you allow each renewable generator to produce (expressed in ratio of
355355 Pmax). For example if `gen_id=1` and `amount=0.7` it means you limit the production of
356356 generator 1 to 70% of its Pmax.
357+
358+ Finally, provided that the environment is loaded with `allow_detachment=True`, you can also
359+ perform "detachment" action on the grid with:
360+
361+ .. code-block:: python
362+
363+ import grid2op
364+ from grid2op.Action import BaseAction
365+ env_name = "l2rpn_case14_sandbox" # or any other name
366+ env = grid2op.make(env_name, allow_detachment=True)
367+
368+ # method 1
369+ act = env.action_space({"detach_load": [load1_id, load2_id, ...]})
370+
371+ # method 2
372+ act = env.action_space()
373+ act.detach_load = [load1_id, load2_id, ...]
357374
375+ You can do similar action for storage and generator, for example
376+
377+ .. code-block:: python
378+
379+ import grid2op
380+ from grid2op.Action import BaseAction
381+ env_name = "educ_case14_storage" # or any other name
382+ env = grid2op.make(env_name, test=True, allow_detachment=True)
383+
384+ # for generators (method 1 showed here, but method 2 works, of course)
385+ act = env.action_space({"detach_gen": [gen1_id, gen2_id, ...]})
386+
387+ # for storage units (method 2 showed here, but method 1 works too, of course)
388+ act = env.action_space()
389+ act.detach_storage = [storage1_id, storage2_id, ...]
390+
358391 """
359392
360393 authorized_keys = {
@@ -550,19 +583,6 @@ def process_detachment(cls):
550583 if el in cls .authorized_keys :
551584 cls .authorized_keys .remove (el )
552585 cls ._update_value_set ()
553- # else:
554- # # I support detachment, I need to make sure this is registered
555- # cls.attr_list_vect = copy.deepcopy(cls.attr_list_vect)
556- # cls.attr_list_set = copy.deepcopy(cls.attr_list_set)
557- # # add the detachment from the list to vector
558- # for el in ["_detach_load", "_detach_gen", "_detach_storage"]:
559- # if el not in cls.attr_list_vect:
560- # cls.attr_list_vect.append(el)
561- # # add the detachment from the allowed action
562- # for el in ["detach_load", "detach_gen", "detach_storage"]:
563- # if el not in cls.authorized_keys:
564- # cls.authorized_keys.add(el)
565- # cls._update_value_set()
566586 return super ().process_detachment ()
567587
568588 def copy (self ) -> "BaseAction" :
@@ -3569,6 +3589,16 @@ def __str__(self) -> str:
35693589 res .append (f"\t - Raise alert(s) { line_str } " )
35703590 else :
35713591 res .append ("\t - Not raise any alert" )
3592+
3593+ if my_cls .detachment_is_allowed :
3594+ for el in my_cls .OBJ_SUPPORT_DETACH :
3595+ _modif_detach_xxx = getattr (self , f"_modif_detach_{ el } " )
3596+ _detach_xxx = getattr (self , f"_detach_{ el } " )
3597+ if _modif_detach_xxx :
3598+ res .append (f"\t - Detach { el } : { _detach_xxx .nonzero ()[0 ]} " )
3599+ else :
3600+ res .append (f"\t - Not detach any { el } " )
3601+
35723602 return "\n " .join (res )
35733603
35743604 def impact_on_objects (self ) -> dict :
0 commit comments