Skip to main content

oee

CI PyPI License: MIT

Overall Equipment Effectiveness for Python.

Compute OEE (Availability x Performance x Quality) from machine times and piece counts, get the full time waterfall and the three loss categories, TEEP and utilization, and roll figures up correctly across machines and shifts. Computed from the standard definitions and validated against published worked examples.

oee framework: inputs (times and counts, or an event log) flow through the OEE engine (availability, performance, quality, the time waterfall and six big losses) into an OEEResult with provenance, consumed by aggregate(), pareto() and charts

Motivation

OEE is the standard manufacturing efficiency metric, but Python has no library for it: what exists is monitoring applications (Flask/Django dashboards) or one-off tutorial scripts. The arithmetic looks trivial (three numbers multiplied) and that is exactly why it is usually done wrong:

  • the time waterfall (planned -> run -> net run -> fully productive) and where each loss sits is skipped;
  • TEEP and utilization (which capture schedule loss) are left out;
  • and figures are averaged across machines, which is incorrect: a fast machine and a slow one do not combine to the mean of their OEEs.

oee does these properly, from the standard definitions, and returns one result with the factors, the waterfall, every loss, and provenance.

pip install oee

No runtime dependencies.

Usage

The canonical worked example (Vorne's Fast Guide to OEE):

import oee

r = oee.oee(
    planned_production_time=420,   # minutes (480 shift - 60 of breaks)
    downtime=47,
    ideal_rate=60,                 # pieces per minute
    total_count=19271,
    reject_count=423,
    all_time=480,                  # optional, for TEEP and utilization
)
r.availability   # 0.888
r.performance    # 0.861
r.quality        # 0.978
r.oee            # 0.748
r.teep           # 0.654
print(r.summary())

Roll up across machines (correctly, not by averaging):

m1 = oee.oee(planned_production_time=100, run_time=90, ideal_cycle_time=1,
             total_count=80, good_count=80)     # OEE 0.80
m2 = oee.oee(planned_production_time=300, run_time=150, ideal_cycle_time=1,
             total_count=150, good_count=135)   # OEE 0.45

line = oee.aggregate([m1, m2])
line.oee         # 0.5375, not the 0.625 average of the two

Break the losses down into the six big losses:

r = oee.oee(
    planned_production_time=480, downtime=80, ideal_cycle_time=0.5,
    total_count=700, reject_count=100,
    setup_time=30,        # of the 80 min down, 30 was setup
    startup_rejects=40,   # of the 100 rejects, 40 were at startup
)
r.six_losses
# {'breakdowns': 50.0, 'setup_and_adjustments': 30.0,
#  'minor_stops_and_reduced_speed': 50.0,
#  'process_defects': 30.0, 'reduced_yield': 20.0}

Rank the losses (or any downtime-reason breakdown) with a Pareto:

for e in oee.pareto(r.six_losses):
    print(f"{e.label:30} {e.value:5.0f}  {e.share:5.0%}  cum {e.cumulative:5.0%}")
# breakdowns                        50    28%  cum   28%
# minor_stops_and_reduced_speed     50    28%  cum   56%
# process_defects                   30    17%  cum   72%
# setup_and_adjustments             30    17%  cum   89%
# reduced_yield                     20    11%  cum  100%

Or compute it from an event log of production runs and downtime events:

r = oee.from_log(
    planned_production_time=420,
    runs=[{"count": 19271, "good": 18848, "ideal_rate": 60}],
    downtime_events=[
        {"reason": "changeover", "duration": 30, "planned": True},
        {"reason": "jam",        "duration": 17},
    ],
)
r.oee                  # 0.748
r.downtime_reasons     # {'changeover': 30, 'jam': 17} - ready for pareto()

When you already have the three factors:

oee.oee_from_factors(0.90, 0.95, 0.999).world_class   # True (OEE >= 85%)

Charts come with the optional plot extra (pip install oee[plot]):

oee.waterfall(r)              # the OEE time waterfall
oee.losses_pareto(r)          # a Pareto of the six big losses
oee.trend(shifts, factors=True)   # OEE and the factors across a sequence

Each draws onto a matplotlib Axes and returns it (ax.figure.savefig(...) to save); matplotlib stays an optional extra, so the core has no dependencies.

Every result carries the factors, the time waterfall, the losses, world_class and meets_target flags, summary(), and a JSON-safe to_dict() with provenance (version, input hash, timestamp).

What it computes

Group Output
Factors availability, performance, quality, OEE
Extended TEEP, utilization (when total calendar time is given)
Waterfall planned -> run -> net run -> fully productive time, with schedule, availability, performance and quality losses
Six big losses breakdowns, setup and adjustments, minor stops and reduced speed, process defects, reduced yield
Pareto rank any loss breakdown by share and cumulative share
Roll-up correct aggregation across machines, lines and shifts
Charts waterfall, six-big-losses Pareto and trend (optional plot extra)

All times must be in the same unit; ideal_cycle_time is that unit per piece (or pass ideal_rate in pieces per that unit). Performance above 100% is capped and flagged, since it means the ideal rate or counts are off.

Beyond OEE

The same data supports the metrics that surround OEE, each in the same Result style with provenance.

The effectiveness family. Pass the planned downtime and oee() adds OOE (measured over operating time = planned production time + planned downtime), so you get all three at once (TEEP <= OOE <= OEE):

r = oee.oee(planned_production_time=420, downtime=47, ideal_rate=60,
            total_count=19271, reject_count=423, all_time=480, planned_downtime=33)
r.oee, r.ooe, r.teep        # OEE >= OOE >= TEEP

Reliability, the maintenance driver of the availability factor:

oee.reliability(operating_time=1000, failures=5, total_repair_time=50)
# MTBF 200, MTTR 10, inherent availability 95.2%

Yield, the multi-step quality view that extends the single-step quality factor:

oee.rolled_throughput_yield([0.99, 0.98, 0.97]).rty    # 0.941

Capacity, and the money behind the losses:

oee.takt_time(available_time=480, demand=240)          # 2.0 per unit
oee.loss_value(r, value_per_unit=12.0)                 # losses as units and money
Metric What it adds
oee() with planned_downtime OOE alongside OEE and TEEP
reliability() MTBF, MTTR, inherent availability
first_pass_yield(), rolled_throughput_yield() multi-step quality
takt_time(), capacity() the pace needed to meet demand
loss_value() losses in lost units and money

Status

Version 0.1.0. Single-machine OEE, the time waterfall, TEEP/utilization, and correct roll-up. The OEEResult contract is append-only from here.

Roadmap

Version Scope
0.2 an MCP server so an agent can compute and explain OEE

Out of scope: data collection / machine connectivity (that is the job of an MES or an IoT dashboard); oee is the calculation layer they can build on.

References

Definitions

OEE follows the standard definitions: Availability x Performance x Quality, the time waterfall, the six big losses, TEEP and the world-class benchmark.

  • Nakajima, S. (1988). Introduction to TPM. Productivity Press. The origin of OEE and the world-class benchmark (availability >= 90%, performance >= 95%, quality >= 99.9%, OEE >= 85%).
  • SEMI E79. The semiconductor industry standard for equipment efficiency and OEE.
  • Vorne Industries, The Fast Guide to OEE (oee.com).

Worked examples

The validation suite checks the computation against published worked examples, each cited in its case:

Example OEE Source
8-hour shift (widgets) 74.79% Vorne, The Fast Guide to OEE (oee.com)
CNC machining shift 68.52% TeepTrak, How to Calculate OEE
Shift, clean numbers 72.4% ReliaMag, How to Calculate OEE
Longer-horizon run 70.6% ReliaMag, How to Calculate OEE
Packaging line 67.5% FIRGELLI Automations, OEE Calculator
World-class benchmark 85.4% Nakajima (1988), Introduction to TPM

License

MIT. Written and maintained by Atakan Arikan, MSc Student at Tsinghua University and Politecnico di Milano.

Metadata

Release files for oee 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for oee 0.2.0
File Size Uploaded
oee-0.2.0.tar.gz 26.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for oee 0.2.0
File Interpreter ABI Platform
oee-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 48.8 kB

Release files / oee-0.2.0.tar.gz

Download URL oee-0.2.0.tar.gz
Size 26.4 kB
Tags Source
SHA-256 checksum
How to use checksums
46218a99b79f4678ff6fb4fb6cee228827179bfc201d84666344869105c2bbe9
BLAKE2b-256 checksum
How to use checksums
798e23c164bd97c9996eb87849f8fc93231d251ad9ffdd284a06f255446baa17
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 16, 2026.

Transparency log

Release files / oee-0.2.0-py3-none-any.whl

Download URL oee-0.2.0-py3-none-any.whl
Size 22.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e50743b01e0e1f4742c443c005d20d3a0a27081fee0fcc41ae5d2c73d7435bd5
BLAKE2b-256 checksum
How to use checksums
9e239c743c4198d80d0c53e8abffab3ab3a11c7b88a1ed02663c6bfb069c14c0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 16, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page