Skip to content

Index

energy ¤

Energy Events

Detectors for energy-related patterns: consumption analysis, efficiency tracking, idle waste detection, EnPI, and carbon intensity on manufacturing and industrial IoT time series data.

All classes accept both the standard ts-shape schema (systime | uuid | value_*) and the raw CSV model (time | id | value) via time_column and uuid_column constructor parameters.

Input units

These detectors treat their input values as energy deltas in kWh -- the amount consumed since the previous reading -- because they aggregate with sum(). Feeding an instantaneous power signal (kW, e.g. a *.Total_Active_Power-kW signal) in directly yields a number that scales with the logging rate rather than with consumption. Integrate it first::

from ts_shape.transform.calculator.power_integration import PowerIntegrator

deltas = PowerIntegrator.to_energy_deltas(power_df, window="1h", max_gap="15min")
EnergyConsumptionEvents(deltas).consumption_by_window(uuid, window="1h")
  • EnergyConsumptionEvents: Analyze energy consumption patterns.
  • consumption_by_window: Aggregate energy consumption per time window.
  • peak_demand_detection: Detect peak demand periods exceeding thresholds.
  • consumption_baseline_deviation: Compare actual vs baseline consumption.
  • energy_per_unit: Calculate energy consumption per production unit.
  • normalize: Convert raw CSV DataFrame to standard schema.

  • EnergyEfficiencyEvents: Track energy efficiency metrics.

  • efficiency_trend: Rolling efficiency metric over time.
  • idle_energy_waste: Detect energy consumption during idle periods.
  • specific_energy_consumption: Energy per unit output over time.
  • efficiency_comparison: Compare efficiency across shifts or periods.
  • normalize: Convert raw CSV DataFrame to standard schema.

  • IdleEnergyDetectionEvents: Detect and quantify idle energy waste.

  • idle_energy_by_window: Idle vs running energy per time window.
  • idle_energy_by_shift: Idle waste aggregated per shift.
  • idle_energy_trend: Rolling trend of idle energy waste.

  • EnergyPerformanceIndicatorEvents: ISO 50001 EnPI (energy per unit produced).

  • enpi_by_window: EnPI for each time window.
  • enpi_vs_baseline: EnPI vs rolling baseline with anomaly flags.
  • enpi_by_hierarchy: EnPI across multiple meters for area comparison.

  • CarbonIntensityEvents: Scope 1 & 2 CO2e emissions tracking.

  • emissions_by_window: CO2e per source per time window.
  • total_emissions_by_window: Aggregated Scope 1 + 2 per window.
  • carbon_intensity_per_unit: kgCO2e per unit produced.
  • emission_factor_audit: Return configured factors for audit trail.

CarbonIntensityEvents ¤

CarbonIntensityEvents(
    dataframe: DataFrame,
    emission_factors: dict[str, float],
    *,
    scope_map: dict[str, int] | None = None,
    event_uuid: str = "energy:carbon",
    time_column: str = "systime",
    uuid_column: str = "uuid"
)

Bases: Base

Energy: Carbon Intensity Tracking (Scope 1 & 2)

Converts energy and fuel consumption signals to CO2-equivalent emissions using configurable emission factors. Supports Scope 1 (direct fuel) and Scope 2 (electricity) calculations, plus carbon intensity per unit produced. Designed for CSRD and ISO 14064 reporting.

Supports two data models via constructor parameters:

  • Standard (ts-shape default)::

    CarbonIntensityEvents(df, emission_factors={"meter:elec": 0.233})

    expects: systime | uuid | value_double¤

  • Raw CSV::

    CarbonIntensityEvents(df, emission_factors={"sensor_01": 0.233}, time_column="time", uuid_column="id")

emission_factors is a dict mapping signal identifier → kgCO2e per unit of the energy/fuel reading::

emission_factors = {
    "meter:electricity": 0.233,   # kgCO2e/kWh  (UK grid average 2026)
    "meter:gas":         2.034,   # kgCO2e/m³   (natural gas)
}

Each factor's scope is inferred from scope_map. Any uuid not in scope_map defaults to Scope 2.

Methods: - emissions_by_window: CO2e per source per time window. - total_emissions_by_window: Aggregated Scope 1 + 2 per window. - carbon_intensity_per_unit: kgCO2e per unit produced. - emission_factor_audit: Return configured factors for audit trail.

Parameters:

Name Type Description Default
dataframe DataFrame

Input signal DataFrame.

required
emission_factors dict[str, float]

Mapping of signal identifier → kgCO2e per unit.

required
scope_map dict[str, int] | None

Optional mapping of signal identifier → scope (1 or 2). Defaults to Scope 2 for any uuid not in the map.

None
event_uuid str

UUID assigned to output events.

'energy:carbon'
time_column str

Name of the timestamp column.

'systime'
uuid_column str

Name of the signal identifier column.

'uuid'

emissions_by_window ¤

emissions_by_window(
    *,
    scope: int = 0,
    value_column: str = "value_double",
    window: str = "1D"
) -> pd.DataFrame

CO2e emissions per configured source per time window.

Parameters:

Name Type Description Default
scope int

Filter by scope: 1 = fuel only, 2 = electricity only, 0 = all sources (default).

0
value_column str

Column containing consumption readings.

'value_double'
window str

Aggregation window (e.g. '1D', '1h').

'1D'

Returns:

Name Type Description
DataFrame DataFrame

start, end, duration_seconds, uuid, source_uuid, scope, consumption, emission_factor, kgco2e. end is start plus window.

total_emissions_by_window ¤

total_emissions_by_window(
    *,
    value_column: str = "value_double",
    window: str = "1D"
) -> pd.DataFrame

Aggregate Scope 1 + Scope 2 emissions across all configured meters.

Parameters:

Name Type Description Default
value_column str

Column containing consumption readings.

'value_double'
window str

Aggregation window.

'1D'

Returns:

Name Type Description
DataFrame DataFrame

start, end, duration_seconds, uuid, scope1_kgco2e, scope2_kgco2e, total_kgco2e

carbon_intensity_per_unit ¤

carbon_intensity_per_unit(
    counter_uuid: str,
    *,
    value_column: str = "value_double",
    value_column_counter: str = "value_integer",
    window: str = "1D",
    handle_resets: bool = True
) -> pd.DataFrame

Carbon intensity per unit produced (kgCO2e / unit).

Parameters:

Name Type Description Default
counter_uuid str

Identifier of the production counter signal.

required
value_column str

Column containing energy/fuel readings.

'value_double'
value_column_counter str

Column containing counter readings.

'value_integer'
window str

Aggregation window.

'1D'
handle_resets bool

True (default) treats a decreasing production counter as a reset and sums reset-aware increments per window (see :func:ts_shape.utils.counters.counter_per_window), so a window with a reset still reports what was produced. False uses the per-window max - min.

True

Returns:

Name Type Description
DataFrame DataFrame

start, end, duration_seconds, uuid, total_kgco2e, units_produced, carbon_intensity, trend

emission_factor_audit ¤

emission_factor_audit() -> pd.DataFrame

Return the configured emission factors for audit and reporting.

Returns:

Name Type Description
DataFrame DataFrame

source_uuid, scope, emission_factor_kgco2e_per_unit

EnergyConsumptionEvents ¤

EnergyConsumptionEvents(
    dataframe: DataFrame,
    *,
    event_uuid: str = "energy:consumption",
    time_column: str = "systime",
    uuid_column: str = "uuid"
)

Bases: Base

Energy: Consumption Analysis

Analyze energy consumption patterns from meter/sensor signals.

Values are expected to be energy deltas in kWh (consumption since the previous reading). For an instantaneous power signal in kW, integrate it with :class:~ts_shape.transform.calculator.power_integration.PowerIntegrator first -- summing kW samples measures the logging rate, not the energy.

Supports two data models via constructor parameters:

  • Standard (ts-shape default)::

    EnergyConsumptionEvents(df)

    expects: systime | uuid | value_double¤

  • Raw CSV (time + id + value)::

    EnergyConsumptionEvents(df, time_column="time", uuid_column="id")

    expects: time | id | value¤

    pass value_column="value" to each method¤

Methods: - consumption_by_window: Aggregate energy per time window from a meter UUID. - peak_demand_detection: Flag windows where consumption exceeds a threshold. - consumption_baseline_deviation: Compare actual vs rolling baseline. - energy_per_unit: Energy per production unit when paired with a counter. - normalize: Static helper to convert raw CSV format to standard schema.

Example

import ts_shape df = ts_shape.make_timeseries(["meter"], n_points=96, freq="15min", ... baseline=5.0, noise=0.5) # kWh per 15 min energy = ts_shape.EnergyConsumptionEvents(df) out = energy.consumption_by_window("meter", window="6h") out[["start", "consumption"]].round({"consumption": 1}) start consumption 0 2025-01-01 00:00:00 119.8 1 2025-01-01 06:00:00 122.1 2 2025-01-01 12:00:00 118.9 3 2025-01-01 18:00:00 118.1

normalize staticmethod ¤

normalize(
    dataframe: DataFrame,
    *,
    series_id: str,
    time_column: str = "time",
    value_column: str = "value",
    uuid_column: str | None = None
) -> pd.DataFrame

Convert a raw energy DataFrame to the standard ts-shape schema.

Handles two input formats:

  • Two-column CSV: (time, value) — series_id is assigned as uuid.
  • Three-column with explicit id: (time, uuid_column, value) — values from uuid_column are used as uuid; series_id is ignored.

Parameters:

Name Type Description Default
dataframe DataFrame

Raw DataFrame.

required
series_id str

UUID to assign when no uuid_column is provided.

required
time_column str

Name of the timestamp column in dataframe.

'time'
value_column str

Name of the value column in dataframe.

'value'
uuid_column str | None

Optional column name whose values become the uuid.

None

Returns:

Type Description
DataFrame

DataFrame with columns: systime, uuid, value_double, is_delta

consumption_by_window ¤

consumption_by_window(
    meter_uuid: str,
    *,
    value_column: str = "value_double",
    window: str = "1h",
    agg: str = "sum"
) -> pd.DataFrame

Aggregate energy consumption per time window.

Parameters:

Name Type Description Default
meter_uuid str

UUID of the energy meter signal.

required
value_column str

Column containing energy readings.

'value_double'
window str

Resample window (e.g. '1h', '15min', '1D').

'1h'
agg str

Aggregation method ('sum', 'mean', 'max').

'sum'

Returns:

Name Type Description
DataFrame DataFrame

start, end, duration_seconds, uuid, source_uuid, is_delta, consumption. end is start plus window.

peak_demand_detection ¤

peak_demand_detection(
    meter_uuid: str,
    *,
    value_column: str = "value_double",
    window: str = "15min",
    threshold: float | None = None,
    percentile: float = 0.95
) -> pd.DataFrame

Detect peak demand periods exceeding a threshold.

If threshold is None, uses the given percentile of windowed consumption.

Parameters:

Name Type Description Default
meter_uuid str

UUID of the energy meter signal.

required
value_column str

Column containing energy readings.

'value_double'
window str

Resample window for demand calculation.

'15min'
threshold float | None

Absolute demand threshold. If None, auto-calculated.

None
percentile float

Percentile to use for auto-threshold (default 95th).

0.95

Returns:

Name Type Description
DataFrame DataFrame

start, end, duration_seconds, uuid, source_uuid, is_delta, demand, threshold, is_peak

consumption_baseline_deviation ¤

consumption_baseline_deviation(
    meter_uuid: str,
    *,
    value_column: str = "value_double",
    window: str = "1h",
    baseline_periods: int = 24,
    deviation_threshold: float = 0.2
) -> pd.DataFrame

Compare actual consumption vs rolling baseline.

Parameters:

Name Type Description Default
meter_uuid str

UUID of the energy meter signal.

required
value_column str

Column containing energy readings.

'value_double'
window str

Resample window for consumption.

'1h'
baseline_periods int

Number of windows for rolling baseline.

24
deviation_threshold float

Fractional deviation to flag (0.2 = 20%).

0.2

Returns:

Name Type Description
DataFrame DataFrame

start, end, duration_seconds, uuid, source_uuid, is_delta, consumption, baseline, deviation_pct, is_anomaly

energy_per_unit ¤

energy_per_unit(
    meter_uuid: str,
    counter_uuid: str,
    *,
    value_column_energy: str = "value_double",
    value_column_counter: str = "value_integer",
    window: str = "1h",
    handle_resets: bool = True
) -> pd.DataFrame

Calculate energy consumption per production unit.

Parameters:

Name Type Description Default
meter_uuid str

UUID of the energy meter signal.

required
counter_uuid str

UUID of the production counter signal.

required
value_column_energy str

Column with energy readings.

'value_double'
value_column_counter str

Column with counter readings.

'value_integer'
window str

Time window for aggregation.

'1h'
handle_resets bool

True (default) treats a decreasing production counter as a reset and sums reset-aware increments per window (see :func:ts_shape.utils.counters.counter_per_window), so a window with a reset still reports what was produced. False uses the per-window max - min.

True

Returns:

Name Type Description
DataFrame DataFrame

start, end, duration_seconds, uuid, source_uuid, is_delta, energy, units_produced, energy_per_unit

EnergyEfficiencyEvents ¤

EnergyEfficiencyEvents(
    dataframe: DataFrame,
    *,
    event_uuid: str = "energy:efficiency",
    time_column: str = "systime",
    uuid_column: str = "uuid"
)

Bases: Base

Energy: Efficiency Tracking

Track energy efficiency metrics against production and machine state.

Supports two data models via constructor parameters:

  • Standard (ts-shape default)::

    EnergyEfficiencyEvents(df)

    expects: systime | uuid | value_double / value_integer / value_bool¤

  • Raw CSV (time + id + value)::

    EnergyEfficiencyEvents(df, time_column="time", uuid_column="id")

    pass value_column="value" to each method¤

Methods: - efficiency_trend: Rolling efficiency metric over time. - idle_energy_waste: Detect energy consumption during idle periods. - specific_energy_consumption: Energy per unit output trend. - efficiency_comparison: Compare efficiency across shifts or periods. - normalize: Static helper to convert raw CSV format to standard schema.

normalize staticmethod ¤

normalize(
    dataframe: DataFrame,
    *,
    series_id: str,
    time_column: str = "time",
    value_column: str = "value",
    uuid_column: str | None = None
) -> pd.DataFrame

Convert a raw energy DataFrame to the standard ts-shape schema.

Parameters:

Name Type Description Default
dataframe DataFrame

Raw DataFrame.

required
series_id str

UUID to assign when no uuid_column is provided.

required
time_column str

Name of the timestamp column in dataframe.

'time'
value_column str

Name of the value column in dataframe.

'value'
uuid_column str | None

Optional column name whose values become the uuid.

None

Returns:

Type Description
DataFrame

DataFrame with columns: systime, uuid, value_double, is_delta

efficiency_trend ¤

efficiency_trend(
    meter_uuid: str,
    counter_uuid: str,
    *,
    value_column_energy: str = "value_double",
    value_column_counter: str = "value_integer",
    window: str = "1h",
    handle_resets: bool = True,
    trend_window: int = 24
) -> pd.DataFrame

Rolling energy efficiency trend (units produced per kWh).

Parameters:

Name Type Description Default
meter_uuid str

UUID of the energy meter signal.

required
counter_uuid str

UUID of the production counter signal.

required
value_column_energy str

Column with energy readings.

'value_double'
value_column_counter str

Column with counter readings.

'value_integer'
window str

Time window for aggregation.

'1h'
trend_window int

Number of trailing windows (itself included) in rolling_avg_efficiency: their summed units over their summed energy.

24
handle_resets bool

True (default) treats a decreasing production counter as a reset and sums reset-aware increments per window (see :func:ts_shape.utils.counters.counter_per_window), so a window with a reset still reports what was produced. False uses the per-window max - min.

True

Returns:

Name Type Description
DataFrame DataFrame

start, end, duration_seconds, uuid, source_uuid, is_delta, energy, units, efficiency, rolling_avg_efficiency, trend_direction

idle_energy_waste ¤

idle_energy_waste(
    meter_uuid: str,
    run_state_uuid: str,
    *,
    value_column_energy: str = "value_double",
    value_column_state: str = "value_bool",
    window: str = "15min",
    idle_threshold: float = 0.0,
    time_weighted: bool = True
) -> pd.DataFrame

Detect energy consumed during idle periods (waste).

Compares energy consumption with machine run/idle state to find windows where the machine is idle but still consuming energy.

Parameters:

Name Type Description Default
meter_uuid str

UUID of the energy meter signal.

required
run_state_uuid str

UUID of the boolean machine state signal (True=run).

required
value_column_energy str

Column with energy readings.

'value_double'
value_column_state str

Column with boolean state.

'value_bool'
window str

Time window for analysis.

'15min'
idle_threshold float

Energy above this during idle is waste.

0.0
time_weighted bool

True (default) weights the machine state by how long it was held (until the next state change) and keeps every energy window. False averages state samples and keeps only windows that contain a state row; that is only right for a densely, uniformly sampled state signal.

True

Returns:

Name Type Description
DataFrame DataFrame

start, end, duration_seconds, uuid, source_uuid, is_delta, energy_consumed, machine_running_pct (0-100), machine_running_ratio (0-1), is_idle_waste, waste_energy. A window is idle waste when the machine ran less than 10 % of it and consumed more than idle_threshold.

specific_energy_consumption ¤

specific_energy_consumption(
    meter_uuid: str,
    counter_uuid: str,
    *,
    value_column_energy: str = "value_double",
    value_column_counter: str = "value_integer",
    window: str = "1D",
    handle_resets: bool = True
) -> pd.DataFrame

Daily/periodic specific energy consumption (SEC = energy / output).

Lower SEC indicates better efficiency.

Parameters:

Name Type Description Default
meter_uuid str

UUID of the energy meter signal.

required
counter_uuid str

UUID of the production counter.

required
value_column_energy str

Column with energy readings.

'value_double'
value_column_counter str

Column with counter readings.

'value_integer'
window str

Time window (default daily).

'1D'
handle_resets bool

True (default) treats a decreasing production counter as a reset and sums reset-aware increments per window (see :func:ts_shape.utils.counters.counter_per_window), so a window with a reset still reports what was produced. False uses the per-window max - min.

True

Returns:

Name Type Description
DataFrame DataFrame

start, end, duration_seconds, uuid, source_uuid, is_delta, total_energy, total_output, sec, sec_trend

efficiency_comparison ¤

efficiency_comparison(
    meter_uuid: str,
    counter_uuid: str,
    *,
    value_column_energy: str = "value_double",
    value_column_counter: str = "value_integer",
    shift_definitions: dict[str, tuple] | None = None
) -> pd.DataFrame

Compare energy efficiency across shifts.

Parameters:

Name Type Description Default
meter_uuid str

UUID of the energy meter signal.

required
counter_uuid str

UUID of the production counter.

required
value_column_energy str

Column with energy readings.

'value_double'
value_column_counter str

Column with counter readings.

'value_integer'
shift_definitions dict[str, tuple] | None

Dict mapping shift name to (start_time, end_time) strings. Default: 3-shift operation.

None

Returns:

Name Type Description
DataFrame DataFrame

shift, avg_energy, avg_output, avg_efficiency, total_energy, total_output. total_output is the counter increase within the shift (reset-aware) and avg_output the mean increase per counter reading.

EnergyPerformanceIndicatorEvents ¤

EnergyPerformanceIndicatorEvents(
    dataframe: DataFrame,
    *,
    event_uuid: str = "energy:enpi",
    time_column: str = "systime",
    uuid_column: str = "uuid"
)

Bases: Base

Energy: Performance Indicator (EnPI) per ISO 50001

Calculate energy consumed per unit of production output (EnPI = kWh/unit). Tracks EnPI against a rolling baseline and identifies improvement/degradation trends. Supports comparison across multiple meters / production areas.

Supports two data models via constructor parameters:

  • Standard (ts-shape default)::

    EnergyPerformanceIndicatorEvents(df)

    expects: systime | uuid | value_double | value_integer¤

  • Raw CSV::

    EnergyPerformanceIndicatorEvents(df, time_column="time", uuid_column="id")

Methods: - enpi_by_window: EnPI (energy / units) per time window. - enpi_vs_baseline: EnPI vs rolling baseline with anomaly flags. - enpi_by_hierarchy: EnPI across multiple meters for area comparison.

enpi_by_window ¤

enpi_by_window(
    meter_uuid: str,
    counter_uuid: str,
    *,
    value_column_energy: str = "value_double",
    value_column_counter: str = "value_integer",
    window: str = "1D",
    handle_resets: bool = True
) -> pd.DataFrame

Calculate energy per unit produced (EnPI) for each time window.

Parameters:

Name Type Description Default
meter_uuid str

Identifier of the energy meter signal.

required
counter_uuid str

Identifier of the production counter signal.

required
value_column_energy str

Column containing energy readings.

'value_double'
value_column_counter str

Column containing counter readings.

'value_integer'
window str

Aggregation window (e.g. '1D', '1h', '1W').

'1D'
handle_resets bool

True (default) treats a decreasing production counter as a reset and sums reset-aware increments per window (see :func:ts_shape.utils.counters.counter_per_window), so a window with a reset still reports what was produced. False uses the per-window max - min.

True

Returns:

Name Type Description
DataFrame DataFrame

start, end, duration_seconds, uuid, source_uuid, is_delta, energy_kwh, units_produced, enpi. end is start plus window.

enpi_vs_baseline ¤

enpi_vs_baseline(
    meter_uuid: str,
    counter_uuid: str,
    *,
    value_column_energy: str = "value_double",
    value_column_counter: str = "value_integer",
    window: str = "1D",
    handle_resets: bool = True,
    baseline_window: int = 30,
    deviation_threshold: float = 0.1,
    baseline: str = "rolling",
    baseline_period: (
        tuple[str | Timestamp, str | Timestamp] | None
    ) = None
) -> pd.DataFrame

Compare current EnPI against a baseline.

baseline="rolling" (default) compares each window with the EnPI of the preceding baseline_window windows (itself included) taken as one period: their summed energy over their summed output (ISO 50006), not the mean of the per-window EnPI values, which over-weights low-output windows. A rolling baseline drifts with the process, so it never shows a lasting improvement, and kWh/unit is biased by load: a fixed base load makes EnPI look worse whenever output is low.

baseline="regression" is the ISO 50006 energy baseline: fit energy = a + b * units on a fixed baseline period, then compare each window's energy with what the model expects for its output. baseline_enpi is that expected energy per unit and deviation_pct is (actual - expected) / expected energy, so the comparison is normalized for production volume. Two columns are added: expected_energy_kwh and energy_savings_kwh (expected - actual; its cumulative sum is the CUSUM of savings).

Parameters:

Name Type Description Default
meter_uuid str

Identifier of the energy meter signal.

required
counter_uuid str

Identifier of the production counter signal.

required
value_column_energy str

Column containing energy readings.

'value_double'
value_column_counter str

Column containing counter readings.

'value_integer'
window str

Aggregation window.

'1D'
baseline_window int

Number of windows for rolling baseline.

30
deviation_threshold float

Fractional deviation to flag as anomaly (0.1 = 10%).

0.1
baseline str

"rolling" or "regression" (see above).

'rolling'
baseline_period tuple[str | Timestamp, str | Timestamp] | None

(start, end) of the regression baseline period, end exclusive. Default: the first baseline_window windows.

None
handle_resets bool

True (default) treats a decreasing production counter as a reset and sums reset-aware increments per window (see :func:ts_shape.utils.counters.counter_per_window), so a window with a reset still reports what was produced. False uses the per-window max - min.

True

Returns:

Name Type Description
DataFrame DataFrame

start, end, duration_seconds, uuid, source_uuid, enpi, baseline_enpi, deviation_pct, is_anomaly, trend

enpi_by_hierarchy ¤

enpi_by_hierarchy(
    meter_uuids: list[str],
    counter_uuid: str,
    *,
    value_column_energy: str = "value_double",
    value_column_counter: str = "value_integer",
    window: str = "1D",
    handle_resets: bool = True
) -> pd.DataFrame

Calculate EnPI per meter for cross-area comparison.

Useful for comparing energy intensity across production lines, buildings, or hierarchy levels. Combine with series metadata to map meter_uuid to label_lvl / hierarchy columns.

Parameters:

Name Type Description Default
meter_uuids list[str]

List of energy meter identifiers.

required
counter_uuid str

Shared production counter identifier.

required
value_column_energy str

Column containing energy readings.

'value_double'
value_column_counter str

Column containing counter readings.

'value_integer'
window str

Aggregation window.

'1D'
handle_resets bool

True (default) treats a decreasing production counter as a reset and sums reset-aware increments per window (see :func:ts_shape.utils.counters.counter_per_window), so a window with a reset still reports what was produced. False uses the per-window max - min.

True

Returns:

Name Type Description
DataFrame DataFrame

start, end, duration_seconds, meter_uuid, energy_kwh, units_produced, enpi

IdleEnergyDetectionEvents ¤

IdleEnergyDetectionEvents(
    dataframe: DataFrame,
    *,
    event_uuid: str = "energy:idle",
    time_column: str = "systime",
    uuid_column: str = "uuid"
)

Bases: Base

Energy: Idle Energy Detection

Cross-reference an energy meter signal with a boolean machine-state signal to detect and quantify energy consumed during idle (non-production) periods.

Supports two data models via constructor parameters:

  • Standard (ts-shape default)::

    IdleEnergyDetectionEvents(df)

    expects: systime | uuid | value_double | value_bool¤

  • Raw CSV::

    IdleEnergyDetectionEvents(df, time_column="time", uuid_column="id")

Methods: - idle_energy_by_window: Idle vs running energy per time window. - idle_energy_by_shift: Idle waste aggregated per shift. - idle_energy_trend: Rolling trend of idle energy waste.

idle_energy_by_window ¤

idle_energy_by_window(
    meter_uuid: str,
    run_state_uuid: str,
    *,
    value_column_energy: str = "value_double",
    value_column_state: str = "value_bool",
    window: str = "1h",
    idle_threshold: float = 0.1,
    time_weighted: bool = True
) -> pd.DataFrame

Aggregate energy consumed during idle periods per time window.

The machine-running share is the share of each window the boolean state signal was True. It is reported as machine_running_ratio (0-1) and as machine_running_pct (0-100). Windows whose ratio is below idle_threshold count as fully idle; otherwise the idle fraction is 1 - machine_running_ratio.

Parameters:

Name Type Description Default
meter_uuid str

Identifier of the energy meter signal.

required
run_state_uuid str

Identifier of the boolean machine-state signal (True=running).

required
value_column_energy str

Column containing energy readings.

'value_double'
value_column_state str

Column containing boolean state values.

'value_bool'
window str

Resample window (e.g. '1h', '15min').

'1h'
idle_threshold float

Running ratio (0-1) below which the window is classified as fully idle.

0.1
time_weighted bool

True (default) weights the machine state by how long it was held (until the next state change) and keeps every energy window. False averages state samples and keeps only windows that contain a state row; that is only right for a densely, uniformly sampled state signal.

True

Returns:

Name Type Description
DataFrame DataFrame

start, end, duration_seconds, uuid, source_uuid, is_delta, total_energy, idle_energy, running_energy, machine_running_pct (0-100), idle_fraction, machine_running_ratio (0-1)

idle_energy_by_shift ¤

idle_energy_by_shift(
    meter_uuid: str,
    run_state_uuid: str,
    *,
    value_column_energy: str = "value_double",
    value_column_state: str = "value_bool",
    shift_definitions: (
        dict[str, tuple[str, str]] | None
    ) = None,
    idle_threshold: float | None = None
) -> pd.DataFrame

Aggregate idle energy waste per shift across all dates.

The idle fraction of a shift is 1 - running ratio (the mean of the state samples in that shift). Pass idle_threshold to apply the same rule as :meth:idle_energy_by_window: a shift whose running ratio is below the threshold counts as fully idle.

Parameters:

Name Type Description Default
meter_uuid str

Identifier of the energy meter signal.

required
run_state_uuid str

Identifier of the boolean machine-state signal.

required
value_column_energy str

Column containing energy readings.

'value_double'
value_column_state str

Column containing boolean state values.

'value_bool'
shift_definitions dict[str, tuple[str, str]] | None

Dict mapping shift name → (start_time, end_time). Default: three-shift operation (06-14, 14-22, 22-06).

None
idle_threshold float | None

Running ratio (0-1) below which a shift counts as fully idle. Default None: no threshold, the idle fraction is always 1 - running ratio; 0.1 matches :meth:idle_energy_by_window.

None

Returns:

Name Type Description
DataFrame DataFrame

shift, total_energy, idle_energy, waste_fraction

idle_energy_trend ¤

idle_energy_trend(
    meter_uuid: str,
    run_state_uuid: str,
    *,
    value_column_energy: str = "value_double",
    value_column_state: str = "value_bool",
    window: str = "1D",
    trend_window: int = 7,
    idle_threshold: float = 0.1
) -> pd.DataFrame

Rolling trend of idle energy waste over time.

Parameters:

Name Type Description Default
meter_uuid str

Identifier of the energy meter signal.

required
run_state_uuid str

Identifier of the boolean machine-state signal.

required
value_column_energy str

Column containing energy readings.

'value_double'
value_column_state str

Column containing boolean state values.

'value_bool'
window str

Aggregation window (default daily).

'1D'
trend_window int

Number of windows for rolling average.

7
idle_threshold float

Running ratio (0-1) below which a window counts as fully idle (see :meth:idle_energy_by_window).

0.1

Returns:

Name Type Description
DataFrame DataFrame

start, end, duration_seconds, uuid, source_uuid, idle_energy, rolling_avg_idle_energy, trend_direction