KPI Availability Values¶
KpiAvailabilityValues(perfdb)
¶
Class used for handling availability values. Can be accessed via perfdb.kpis.availability.values.
Parameters:
Source code in echo_postgres/perfdb_root.py
def __init__(self, perfdb: e_pg.PerfDB) -> None:
"""Base class that all subclasses should inherit from.
Parameters
----------
perfdb : PerfDB
Top level object carrying all functionality and the connection handler.
"""
self._perfdb: e_pg.PerfDB = perfdb
get(period, time_res='daily', aggregation_window=None, object_or_group_names=None, object_group_types=None, availability_types=None, filter_type='and', output_type='DataFrame')
¶
Gets all availability values with detailed information.
The most useful keys/columns returned are:
- time_unavailable
- time_available
- time_availability
- time_unavailable_target
- time_available_target
- time_availability_target
- energy_available
- energy_unavailable
- energy_availability
- energy_available_target
- energy_unavailable_target
- energy_availability_target
Parameters:
-
(period¶DateTimeRange) –Period of time to get the data for.
-
(time_res¶Literal['daily', 'monthly', 'quarterly', 'yearly'], default:'daily') –Time resolution of the data. Can be one of ["daily", "monthly", "quarterly", "yearly"], by default "daily"
-
(aggregation_window¶Literal['mtd', 'ytd', '12m'] | None, default:None) –Aggregation window to use. Can be one of ["mtd", "ytd", "12m"], by default None
-
(object_or_group_names¶list[str], default:None) –List of object or group names to get the data for. By default None
-
(object_group_types¶list[str], default:None) –List of object group types to get the data for. By default None
-
(availability_types¶list[str], default:None) –List of availability types to get the data for. By default None
-
(filter_type¶Literal['and', 'or'], default:'and') –How to treat multiple filters. Can be one of ["and", "or"]. By default "and"
-
(output_type¶Literal['dict', 'DataFrame'], default:'DataFrame') –Output type of the data. Can be one of ["dict", "DataFrame"] By default "dict"
Returns:
-
DataFrame–In case output_type is "DataFrame", returns a DataFrame with the following format: index = MultiIndex[group_type_name, object_or_group_name, date, availability_type_name], columns = [time_unavailable, time_available, ...]
-
dict[str, dict[str, dict[Timestamp, dict[str, dict[str, Any]]]]]–In case output_type is "dict", returns a dictionary in the format {group_type_name: {object_or_group_name: {date: {availability_type_name: {attribute: value, ...}, ...}, ...}, ...}, ...}
Source code in echo_postgres/kpi_availability_values.py
@validate_call
def get(
self,
period: DateTimeRange,
time_res: Literal["daily", "monthly", "quarterly", "yearly"] = "daily",
aggregation_window: Literal["mtd", "ytd", "12m"] | None = None,
object_or_group_names: list[str] | None = None,
object_group_types: list[str] | None = None,
availability_types: list[str] | None = None,
filter_type: Literal["and", "or"] = "and",
output_type: Literal["dict", "DataFrame"] = "DataFrame",
) -> DataFrame | dict[str, dict[str, dict[Timestamp, dict[str, dict[str, Any]]]]]:
"""Gets all availability values with detailed information.
The most useful keys/columns returned are:
- time_unavailable
- time_available
- time_availability
- time_unavailable_target
- time_available_target
- time_availability_target
- energy_available
- energy_unavailable
- energy_availability
- energy_available_target
- energy_unavailable_target
- energy_availability_target
Parameters
----------
period : DateTimeRange
Period of time to get the data for.
time_res : Literal["daily", "monthly", "quarterly", "yearly"], optional
Time resolution of the data. Can be one of ["daily", "monthly", "quarterly", "yearly"], by default "daily"
aggregation_window : Literal["mtd", "ytd", "12m"] | None, optional
Aggregation window to use. Can be one of ["mtd", "ytd", "12m"], by default None
object_or_group_names : list[str], optional
List of object or group names to get the data for. By default None
object_group_types : list[str], optional
List of object group types to get the data for. By default None
availability_types : list[str], optional
List of availability types to get the data for. By default None
filter_type : Literal["and", "or"], optional
How to treat multiple filters. Can be one of ["and", "or"].
By default "and"
output_type : Literal["dict", "DataFrame"], optional
Output type of the data. Can be one of ["dict", "DataFrame"]
By default "dict"
Returns
-------
DataFrame
In case output_type is "DataFrame", returns a DataFrame with the following format: index = MultiIndex[group_type_name, object_or_group_name, date, availability_type_name], columns = [time_unavailable, time_available, ...]
dict[str, dict[str, dict[Timestamp, dict[str, dict[str, Any]]]]]
In case output_type is "dict", returns a dictionary in the format {group_type_name: {object_or_group_name: {date: {availability_type_name: {attribute: value, ...}, ...}, ...}, ...}, ...}
"""
# build the query
query = [
sql.SQL(
"SELECT * FROM performance.{table} WHERE (date >= {start} AND date <= {end})",
).format(
table=sql.Identifier(
f"mv_availability_{time_res}{f'_{aggregation_window}' if aggregation_window else ''}",
),
start=sql.Literal(f"{period.start:%Y-%m-%d %H:%M:%S}"),
end=sql.Literal(f"{period.end:%Y-%m-%d %H:%M:%S}"),
),
]
where = []
if object_or_group_names:
where.append(
sql.SQL("object_or_group_name IN ({names})").format(
names=sql.SQL(", ").join(map(sql.Literal, object_or_group_names)),
),
)
if object_group_types:
where.append(
sql.SQL("group_type_name IN ({names})").format(
names=sql.SQL(", ").join(map(sql.Literal, object_group_types)),
),
)
if availability_types:
where.append(
sql.SQL("availability_type_name IN ({names})").format(
names=sql.SQL(", ").join(map(sql.Literal, availability_types)),
),
)
if where:
query.append(sql.SQL(" AND ("))
query.append(sql.SQL(f" {filter_type.upper()} ").join(where))
query.append(sql.SQL(")"))
query.append(sql.SQL(" ORDER BY group_type_name, object_or_group_name, date, availability_type_name"))
query = sql.Composed(query)
with self._perfdb.conn.reconnect() as conn:
df = conn.read_to_pandas(query, post_convert="pyarrow")
# forcing date to be a Timestamp
df["date"] = df["date"].astype("datetime64[s]")
# forcing object_name and object_group_name to be a string
df = df.astype(
{"object_or_group_name": "string[pyarrow]", "group_type_name": "string[pyarrow]"},
)
df = df.astype({"object_or_group_id": "int64[pyarrow]", "group_type_id": "int64[pyarrow]"})
df = df.set_index(["group_type_name", "object_or_group_name", "date", "availability_type_name"])
if output_type == "DataFrame":
return df
# dropping id columns not used in dict format
df = df.drop(columns=[col for col in df.columns if col.endswith("_id")])
# converting to Dict
result = df.to_dict(orient="index")
final_result = {}
for (group_type_name, object_or_group_name, date, availability_type_name), data in result.items():
if group_type_name not in final_result:
final_result[group_type_name] = {}
if object_or_group_name not in final_result[group_type_name]:
final_result[group_type_name][object_or_group_name] = {}
if date not in final_result[group_type_name][object_or_group_name]:
final_result[group_type_name][object_or_group_name][date] = {}
final_result[group_type_name][object_or_group_name][date][availability_type_name] = data
return final_result