# Path: edisgo/flex_opt/check_tech_constraints.py
# def mv_line_load(edisgo_obj):
# def lv_line_load(edisgo_obj):
# def lines_allowed_load(edisgo_obj, voltage_level):
# def lines_relative_load(edisgo_obj, lines_allowed_load):
# def _line_load(edisgo_obj, voltage_level):
# def hv_mv_station_load(edisgo_obj):
# def mv_lv_station_load(edisgo_obj):
# def _station_load(edisgo_obj, grid):
# def mv_voltage_deviation(edisgo_obj, voltage_levels="mv_lv"):
# def lv_voltage_deviation(edisgo_obj, mode=None, voltage_levels="mv_lv"):
# def _mv_allowed_voltage_limits(edisgo_obj, voltage_levels):
# def _lv_allowed_voltage_limits(edisgo_obj, lv_grid, mode):
# def voltage_diff(edisgo_obj, buses, v_dev_allowed_upper, v_dev_allowed_lower):
# def _voltage_deviation(edisgo_obj, buses, v_limits_upper, v_limits_lower):
#     def _append_crit_buses(df):
# def check_ten_percent_voltage_deviation(edisgo_obj):


import logging
import pandas as pd
import numpy as np
from edisgo.flex_opt import check_tech_constraints
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
        The eDisGo API object
    window : int
        The additional hours to include before and after each critical time
        step.

    Returns
    -------
    `pandas.DatetimeIndex`
        the reduced time index for modeling storage

    """
    # Run power flow if not available
    if edisgo_obj.results.i_res is None:
        logger.debug("Running initial power flow")
        edisgo_obj.analyze(mode="mv")

    crit_periods = []

    # Get periods with voltage violations
    crit_nodes = check_tech_constraints.mv_voltage_deviation(
        edisgo_obj, voltage_levels="mv"
    )
    for v in crit_nodes.values():
        nodes = pd.DataFrame(v)
        if "time_index" in nodes:
            for step in nodes["time_index"]:
                if not step in crit_periods:
                    crit_periods.append(step)

    # Get periods with current violations

# Path: edisgo/flex_opt/check_tech_constraints.py
# def mv_line_load(edisgo_obj):
# def lv_line_load(edisgo_obj):
# def lines_allowed_load(edisgo_obj, voltage_level):
# def lines_relative_load(edisgo_obj, lines_allowed_load):
# def _line_load(edisgo_obj, voltage_level):
# def hv_mv_station_load(edisgo_obj):
# def mv_lv_station_load(edisgo_obj):
# def _station_load(edisgo_obj, grid):
# def mv_voltage_deviation(edisgo_obj, voltage_levels="mv_lv"):
# def lv_voltage_deviation(edisgo_obj, mode=None, voltage_levels="mv_lv"):
# def _mv_allowed_voltage_limits(edisgo_obj, voltage_levels):
# def _lv_allowed_voltage_limits(edisgo_obj, lv_grid, mode):
# def voltage_diff(edisgo_obj, buses, v_dev_allowed_upper, v_dev_allowed_lower):
# def _voltage_deviation(edisgo_obj, buses, v_limits_upper, v_limits_lower):
#     def _append_crit_buses(df):
# def check_ten_percent_voltage_deviation(edisgo_obj):


# Path: edisgo/opf/timeseries_reduction.py
import logging
import pandas as pd
import numpy as np
from edisgo.flex_opt import check_tech_constraints
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans

        The eDisGo API object
    window : int
        The additional hours to include before and after each critical time
        step.

    Returns
    -------
    `pandas.DatetimeIndex`
        the reduced time index for modeling storage

    """
    # Run power flow if not available
    if edisgo_obj.results.i_res is None:
        logger.debug("Running initial power flow")
        edisgo_obj.analyze(mode="mv")

    crit_periods = []

    # Get periods with voltage violations
    crit_nodes = check_tech_constraints.mv_voltage_deviation(
        edisgo_obj, voltage_levels="mv"
    )
    for v in crit_nodes.values():
        nodes = pd.DataFrame(v)
        if "time_index" in nodes:
            for step in nodes["time_index"]:
                if not step in crit_periods:
                    crit_periods.append(step)

    # Get periods with current violations

    crit_lines = check_tech_constraints.mv_line_load(edisgo_obj)