oee_calculator
oee_calculator ¤
Overall Equipment Effectiveness (OEE) calculator.
OEE = Availability x Performance x Quality
Industry-standard metric for manufacturing productivity: - Availability: actual run time / planned production time - Performance: actual throughput / ideal throughput - Quality: good parts / total parts
OEEEvents ¤
OEEEvents(
dataframe: DataFrame, *, time_column: str = "systime"
)
Bases: Base
Calculate Overall Equipment Effectiveness from timeseries signals.
Combines availability (from run/idle state), performance (from part counters
and ideal cycle time), and quality (from total/reject counters) into a single
OEE metric per day. Each daily row uses the canonical summary schema:
start (midnight) / end (next midnight) / duration_seconds (the
real day length: 86400, or 23 h / 25 h on DST days with tz-aware data).
Example
import pandas as pd, ts_shape kw = dict(n_points=60, freq="1min") run = ts_shape.make_timeseries(["run"], value_column="value_bool", **kw) parts = ts_shape.make_timeseries(["parts"], noise=0, drift=59, ... value_column="value_integer", **kw) daily = ts_shape.OEEEvents(pd.concat([run, parts])).oee( ... "run", "parts", ideal_cycle_time=30.0) daily[["availability_pct", "performance_pct", "quality_pct", "oee_pct"]].round(1) availability_pct performance_pct quality_pct oee_pct 0 54.2 92.2 100.0 50.0
Initialize OEE calculator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataframe
|
DataFrame
|
Input DataFrame with timeseries data. |
required |
time_column
|
str
|
Name of timestamp column (default: 'systime'). |
'systime'
|
availability ¤
availability(
run_state_uuid: str,
planned_time_hours: float | None = None,
*,
value_column: str = "value_bool",
max_gap: str | None = None
) -> pd.DataFrame
Calculate availability percentage from run/idle intervals.
Availability = run_time / planned_time (ISO 22400-2: APT / PBT).
Each reading's state holds until the next reading; the interval is
split at midnight, so a run across midnight counts in both days. When
planned_time_hours is None the planned time is the time the
state signal covers that day. A day the state signal does not cover
is not reported. A value above 100 % (run time longer than a fixed
planned time) is kept and reported with a
:class:~ts_shape.errors.DataQualityWarning naming the day.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run_state_uuid
|
str
|
UUID of the boolean run-state signal (True = running). |
required |
planned_time_hours
|
float | None
|
Fixed planned production hours per day. If None, the time the state signal covers each day is used. |
None
|
value_column
|
str
|
Column holding the boolean state. |
'value_bool'
|
max_gap
|
str | None
|
Optional cap (e.g. "15min"). A sample's duration is the gap
to the next reading; a gap longer than this is treated as a
logging outage ("no data") and excluded from both run time and
planned time. Without it, an overnight or logger gap while the
last state was |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Summary-shape DataFrame with columns: |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
performance ¤
performance(
counter_uuid: str,
ideal_cycle_time: float,
run_state_uuid: str | None = None,
*,
value_column: str = "value_integer",
value_column_state: str = "value_bool",
handle_resets: bool = True,
max_gap: str | None = None
) -> pd.DataFrame
Calculate performance percentage (actual vs ideal throughput).
Performance = (actual_parts * ideal_cycle_time) / run_time
(ISO 22400-2: PQ x pICT / APT). If run_state_uuid is None, the time
the counter readings cover each day is used as run time. With a
state signal, a day it does not cover has unknown run time:
run_seconds, ideal_parts and performance_pct are NaN.
A value above 100 % means the inputs disagree; it is kept (not
clipped) and reported with a
:class:~ts_shape.errors.DataQualityWarning naming the day.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
counter_uuid
|
str
|
UUID of the monotonic part counter. |
required |
ideal_cycle_time
|
float
|
Ideal cycle time in seconds per part. |
required |
run_state_uuid
|
str | None
|
Optional UUID for run-state to compute actual run time. |
None
|
value_column
|
str
|
Column holding counter values. |
'value_integer'
|
value_column_state
|
str
|
Column holding boolean run state. |
'value_bool'
|
handle_resets
|
bool
|
When True (default), treat a decreasing counter as a reset and
count the production after the reset instead of losing it, so
|
True
|
max_gap
|
str | None
|
Optional cap forwarded to :meth: |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Summary-shape DataFrame with columns: |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
quality ¤
quality(
total_uuid: str,
reject_uuid: str,
*,
value_column: str = "value_integer",
handle_resets: bool = True
) -> pd.DataFrame
Calculate quality percentage (good parts / total parts).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
total_uuid
|
str
|
UUID of the total-parts counter. |
required |
reject_uuid
|
str
|
UUID of the reject-parts counter. |
required |
value_column
|
str
|
Column holding counter values. |
'value_integer'
|
handle_resets
|
bool
|
When True (default), treat a decreasing counter as a reset and
count the production after the reset for both the total and the
reject counters, so a day containing a reset is not
under-reported. Increments are spread over the time between
two readings and split at midnight in proportion to time (see
:meth: |
True
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Summary-shape DataFrame with columns: |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
oee ¤
oee(
run_state_uuid: str,
counter_uuid: str,
ideal_cycle_time: float,
total_uuid: str | None = None,
reject_uuid: str | None = None,
*,
planned_time_hours: float | None = None,
handle_resets: bool = True,
max_gap: str | None = None
) -> pd.DataFrame
Calculate daily OEE = Availability * Performance * Quality.
When total_uuid / reject_uuid are not provided, quality is assumed to be 100 %.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run_state_uuid
|
str
|
UUID of the boolean run-state signal. |
required |
counter_uuid
|
str
|
UUID of the monotonic part counter. |
required |
ideal_cycle_time
|
float
|
Ideal cycle time in seconds per part. |
required |
total_uuid
|
str | None
|
Optional UUID of total-parts counter (for quality). |
None
|
reject_uuid
|
str | None
|
Optional UUID of reject-parts counter (for quality). |
None
|
planned_time_hours
|
float | None
|
Fixed planned production hours per day. |
None
|
handle_resets
|
bool
|
When True (default), the part / total / reject counters are
treated as reset-aware (see :meth: |
True
|
max_gap
|
str | None
|
Optional cap (e.g. "15min") forwarded to the availability
and performance components so a logging gap is not booked as run
time (which would inflate availability and understate
performance). |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Summary-shape DataFrame with columns: |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
followed by the basis each percentage was computed from, taken |
DataFrame
|
from the components (a day missing from a component reports 0, except |
DataFrame
|
that a day the state signal does not cover has NaN |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
time is unknown): |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|