# Copyright (c) 2023, RTE (http://www.rte-france.com)
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
#
from typing import Optional
from numpy.typing import ArrayLike
from pandas import DataFrame
from pypowsybl import _pypowsybl as _pp
from pypowsybl.utils import _add_index_to_kwargs, \
_adapt_df_or_kwargs, _create_c_dataframe, create_data_frame_from_series_array # pylint: disable=protected-access
[docs]
class EventMapping:
"""
Class to map events
"""
def __init__(self) -> None:
self._handle = _pp.create_event_mapping()
[docs]
def add_disconnection(self, df: Optional[DataFrame] = None, **kwargs: ArrayLike) -> None:
""" Creates an equipment disconnection event
Args:
df: Attributes as a dataframe.
kwargs: Attributes as keyword arguments.
Notes:
Data may be provided as a dataframe or as keyword arguments.
In the latter case, all arguments must have the same length.
Valid attributes are:
- **static_id**: id of the network element to disconnect
- **start_time**: timestep at which the event happens
- **disconnect_only**: the disconnection is made on the provided side only for branch equipment (ONE or TWO)
Examples:
Using keyword arguments:
.. code-block:: python
event_mapping.add_disconnection(static_id='LINE', start_time=3.3, disconnect_only='TWO')
"""
self._add_all_event_mappings("Disconnect", df, **kwargs)
[docs]
def add_active_power_variation(self, df: Optional[DataFrame] = None, **kwargs: ArrayLike) -> None:
""" Creates an active power variation event on generator or load
Args:
df: Attributes as a dataframe.
kwargs: Attributes as keyword arguments.
Notes:
Data may be provided as a dataframe or as keyword arguments.
In the latter case, all arguments must have the same length.
Valid attributes are:
- **static_id**: id of the load or generator affected by the event
- **start_time**: timestep at which the event happens
- **delta_p**: active power variation
Examples:
Using keyword arguments:
.. code-block:: python
event_mapping.add_active_power_variation(static_id='LOAD', start_time=14, delta_p=2)
"""
self._add_all_event_mappings("ActivePowerVariation", df, **kwargs)
[docs]
def add_reactive_power_variation(self, df: Optional[DataFrame] = None, **kwargs: ArrayLike) -> None:
""" Creates a reactive power variation event on load and generator without dynamic model
Args:
df: Attributes as a dataframe.
kwargs: Attributes as keyword arguments.
Notes:
Data may be provided as a dataframe or as keyword arguments.
In the latter case, all arguments must have the same length.
Valid attributes are:
- **static_id**: id of the load or generator affected by the event
- **start_time**: timestep at which the event happens
- **delta_q**: reactive power variation
Examples:
Using keyword arguments:
.. code-block:: python
event_mapping.add_reactive_power_variation(static_id='LOAD', start_time=14, delta_q=2)
"""
self._add_all_event_mappings("ReactivePowerVariation", df, **kwargs)
[docs]
def add_reference_voltage_variation(self, df: Optional[DataFrame] = None, **kwargs: ArrayLike) -> None:
""" Creates a reference voltage variation event on synchronized and synchronous generator
Args:
df: Attributes as a dataframe.
kwargs: Attributes as keyword arguments.
Notes:
Data may be provided as a dataframe or as keyword arguments.
In the latter case, all arguments must have the same length.
Valid attributes are:
- **static_id**: id of the generator affected by the event
- **start_time**: timestep at which the event happens
- **delta_u**: reference voltage variation
Examples:
Using keyword arguments:
.. code-block:: python
event_mapping.add_reference_voltage_variation(static_id='GEN', start_time=14, delta_u=2)
"""
self._add_all_event_mappings("ReferenceVoltageVariation", df, **kwargs)
[docs]
def add_node_fault(self, df: Optional[DataFrame] = None, **kwargs: ArrayLike) -> None:
""" Creates a bus node fault event
Args:
df: Attributes as a dataframe.
kwargs: Attributes as keyword arguments.
Notes:
Data may be provided as a dataframe or as keyword arguments.
In the latter case, all arguments must have the same length.
Valid attributes are:
- **static_id**: id of the bus affected by the event
- **start_time**: timestep at which the event happens
- **fault_time:** delta with start_time at which the event ends
- **r_pu**: r pu variation
- **x_pu**: x pu variation
Examples:
Using keyword arguments:
.. code-block:: python
event_mapping.add_node_fault(static_id='BUS', start_time=12, fault_time=2, r_pu=0.1, x_pu=0.2)
"""
self._add_all_event_mappings("NodeFault", df, **kwargs)
[docs]
def add_event_model(self, event_name: str, df: Optional[DataFrame] = None, **kwargs: ArrayLike) -> None:
"""
Add an event model with event_name
:Args:
event_name: event model name
df: Attributes as a dataframe.
kwargs: Attributes as keyword arguments.
Examples:
Using keyword arguments:
.. code-block:: python
model_mapping.add_event_model(event_name='Disconnect',
static_id='GEN',
start_time=3.3)
Using dataframe:
.. code-block:: python
df = pd.DataFrame.from_records(
index='static_id',
columns=['static_id', 'start_time'],
data=[('GEN', 3.3), ('LOAD', 5.2)])
model_mapping.add_event_model(event_name='Disconnect', df)
"""
self._add_all_event_mappings(event_name, df, **kwargs)
def _add_all_event_mappings(self, event_name: str, mapping_df: Optional[DataFrame], **kwargs: ArrayLike) -> None:
metadata = _pp.get_event_mappings_meta_data(event_name)
if kwargs:
kwargs = _add_index_to_kwargs(metadata, **kwargs)
mapping_df = _adapt_df_or_kwargs(metadata, mapping_df, **kwargs)
c_mapping_df = _create_c_dataframe(mapping_df, metadata)
_pp.add_all_event_mappings(self._handle, event_name, c_mapping_df)