Part of our Manufacturing in the AI Era series
Read the complete guideManufacturing Analytics in Power BI: OEE, Quality, and Throughput
World-class manufacturing facilities run at 85%+ OEE. The average manufacturer runs at 60%. That 25-percentage-point gap translates directly to capacity — a facility that improves from 60% to 85% OEE adds 41% more output without a single new machine or hire. The difference between world-class and average is almost always not equipment — it is the visibility to see waste and the data to eliminate it.
Power BI, connected to MES (Manufacturing Execution System) and ERP data, provides that visibility. This guide builds a complete manufacturing analytics platform covering OEE calculation, quality SPC charts, downtime root cause analysis, and throughput management — with the precise DAX formulas manufacturing engineers need.
Key Takeaways
- OEE = Availability × Performance × Quality (world class = 85%+)
- Each OEE component requires separate data streams: downtime logs, production counts, scrap records
- SPC (Statistical Process Control) charts in Power BI use custom visuals or calculated control limits
- Downtime Pareto analysis (top 20% of reasons cause 80% of downtime) drives prioritized improvement
- First Pass Yield (FPY) and Defects per Million Opportunities (DPMO) are the key quality KPIs
- Throughput analysis compares actual vs theoretical capacity using bottleneck theory
- Power BI streaming datasets enable near-real-time OEE dashboards updating every minute
- ERP integration (Odoo Manufacturing, SAP PP, Dynamics 365 SCM) provides work order context
Data Model for Manufacturing Analytics
Core Manufacturing Tables
Production_Runs (one row per production run / work order):
| Column | Description |
|---|---|
RunID | Work order or production run ID |
MachineID | FK to Machine dimension |
ProductID | FK to Product |
ShiftID | FK to Shift |
StartTime | Run start datetime |
EndTime | Run end datetime |
PlannedStartTime | Scheduled start |
PlannedEndTime | Scheduled end |
PlannedQuantity | Target output quantity |
ActualQuantity | Actual units produced |
GoodQuantity | Units passing quality check |
ScrapQuantity | Defective units |
ReworkQuantity | Units requiring rework |
IdealCycleTime | Seconds per unit at design speed |
Downtime_Events (one row per stoppage):
| Column | Description |
|---|---|
DowntimeID | Unique ID |
MachineID | FK to Machine |
RunID | FK to Production Run (if applicable) |
StartTime | Downtime start |
EndTime | Downtime end |
DurationMinutes | Total downtime duration |
DowntimeCategory | Planned (PM, changeover) / Unplanned |
DowntimeReasonCode | Specific reason code |
DowntimeReasonDesc | Description |
IsScheduledMaintenance | Planned maintenance flag |
ResponseTimeMinutes | Time until technician responded |
RepairTimeMinutes | Active repair time |
Quality_Events (one row per defect/inspection):
| Column | Description |
|---|---|
InspectionID | Unique ID |
RunID | FK to Production Run |
MachineID | FK to Machine |
InspectionDate | Date/time of inspection |
DefectCode | FK to Defect Type |
DefectCount | Number of defects found |
SampleSize | Units inspected |
MeasuredValue | Variable measurement (for SPC) |
IsInSpec | Boolean — within tolerance |
Dim_Machine:
MachineID,MachineName,Line,Cell,Department,MachineType,IdealRunRate,PlannedCapacity
Dim_Shift:
ShiftID,ShiftName,StartTime,EndTime,PlannedMinutes,PlannedBreakMinutes
OEE Calculation in Power BI
OEE = Availability × Performance × Quality
Availability
Availability = Actual Run Time / Planned Production Time
// Planned Production Time (from shift schedule minus planned downtime)
Planned Production Time =
SUMX(
Production_Runs,
DATEDIFF(Production_Runs[PlannedStartTime],
Production_Runs[PlannedEndTime], MINUTE)
)
// Unplanned Downtime (excludes scheduled maintenance, changeovers)
Unplanned Downtime =
CALCULATE(
SUM(Downtime_Events[DurationMinutes]),
Downtime_Events[DowntimeCategory] = "Unplanned"
)
// Changeover Time (planned but reduces availability)
Changeover Time =
CALCULATE(
SUM(Downtime_Events[DurationMinutes]),
Downtime_Events[DowntimeReasonCode] = "CHANGEOVER"
)
// Actual Run Time
Actual Run Time = [Planned Production Time] - [Unplanned Downtime] - [Changeover Time]
// OEE Availability
Availability =
DIVIDE([Actual Run Time], [Planned Production Time], 0)
Performance
Performance = (Ideal Cycle Time × Total Count) / Actual Run Time Or equivalently: Actual Output / Theoretical Maximum Output
// Theoretical Maximum Output at ideal run rate
Theoretical Max Output =
SUMX(
Production_Runs,
[Actual Run Time Per Run] / Production_Runs[IdealCycleTime]
)
// Actual total output (good + scrap + rework)
Total Output =
SUM(Production_Runs[ActualQuantity])
// OEE Performance
Performance =
DIVIDE([Total Output], [Theoretical Max Output], 0)
// Performance per machine (for benchmarking)
Machine Performance =
DIVIDE(
SUMX(Production_Runs, Production_Runs[ActualQuantity]),
SUMX(Production_Runs,
DATEDIFF(Production_Runs[StartTime], Production_Runs[EndTime], MINUTE) /
RELATED(Dim_Machine[IdealCycleTime]) * 60
),
0
)
Quality
Quality = Good Output / Total Output (excludes all defects)
// Good Quantity (first pass, no rework)
Good Quantity = SUM(Production_Runs[GoodQuantity])
// Total Quantity Produced (good + scrap + rework)
Total Quantity = SUM(Production_Runs[ActualQuantity])
// OEE Quality
Quality Rate =
DIVIDE([Good Quantity], [Total Quantity], 0)
// First Pass Yield (no rework, no scrap)
First Pass Yield =
DIVIDE(
SUM(Production_Runs[GoodQuantity]),
SUM(Production_Runs[ActualQuantity]),
0
)
Overall OEE
// Overall Equipment Effectiveness
OEE =
[Availability] * [Performance] * [Quality Rate]
// OEE Status (for conditional formatting)
OEE Status =
SWITCH(TRUE(),
[OEE] >= 0.85, "World Class", -- 85%+
[OEE] >= 0.75, "Good", -- 75-85%
[OEE] >= 0.60, "Acceptable", -- 60-75%
"Poor" -- <60%
)
// OEE Loss Analysis (what is the primary constraint)
Primary OEE Constraint =
SWITCH(TRUE(),
[Availability] < [Performance] && [Availability] < [Quality Rate], "Availability",
[Performance] < [Quality Rate], "Performance",
"Quality"
)
// OEE trend (for sparkline visualization)
OEE Weekly Avg =
CALCULATE(
[OEE],
DATESINPERIOD(Date[Date], LASTDATE(Date[Date]), -7, DAY)
)
Downtime Analysis
Downtime KPIs and Pareto
// Total Unplanned Downtime Hours
Unplanned Downtime Hours =
DIVIDE(
CALCULATE(
SUM(Downtime_Events[DurationMinutes]),
Downtime_Events[DowntimeCategory] = "Unplanned"
),
60,
0
)
// Mean Time Between Failures (MTBF)
MTBF =
DIVIDE(
[Actual Run Time],
CALCULATE(COUNTROWS(Downtime_Events),
Downtime_Events[DowntimeCategory] = "Unplanned"),
0
)
// Mean Time to Repair (MTTR)
MTTR =
AVERAGEX(
FILTER(Downtime_Events, Downtime_Events[DowntimeCategory] = "Unplanned"),
Downtime_Events[RepairTimeMinutes]
)
// Downtime % by reason (for Pareto chart)
Downtime Pareto % =
DIVIDE([Unplanned Downtime Hours],
CALCULATE([Unplanned Downtime Hours], ALL(Downtime_Events[DowntimeReasonCode])),
0
)
// Cumulative Downtime % (for Pareto 80/20 line)
Cumulative Downtime % =
DIVIDE(
SUMX(
FILTER(
ALL(Downtime_Events[DowntimeReasonCode]),
RANKX(ALL(Downtime_Events[DowntimeReasonCode]),
[Unplanned Downtime Hours], , DESC) <=
RANKX(ALL(Downtime_Events[DowntimeReasonCode]),
[Unplanned Downtime Hours], , DESC)
),
[Unplanned Downtime Hours]
),
CALCULATE([Unplanned Downtime Hours], ALL(Downtime_Events[DowntimeReasonCode])),
0
)
Downtime Heatmap
Create a heatmap of downtime by Machine × Time of Day to identify shift-related patterns:
// Downtime by Hour of Day (for heatmap rows)
Downtime by Hour =
CALCULATE(
SUM(Downtime_Events[DurationMinutes]),
Downtime_Events[HourOfDay] = SELECTEDVALUE(HourDim[Hour])
)
Quality Analytics: SPC Charts
Statistical Process Control charts monitor whether a process is in control. Power BI builds SPC charts using control limit calculations in DAX.
Control Limits for X-Bar Chart
// Process Mean (X-bar)
Process Mean =
AVERAGE(Quality_Events[MeasuredValue])
// Standard Deviation of measurements
Process StdDev =
STDEV.P(Quality_Events[MeasuredValue])
// Upper Control Limit (UCL = mean + 3σ)
UCL = [Process Mean] + 3 * [Process StdDev]
// Lower Control Limit (LCL = mean - 3σ)
LCL = [Process Mean] - 3 * [Process StdDev]
// Upper Warning Limit (mean + 2σ)
UWL = [Process Mean] + 2 * [Process StdDev]
// Lower Warning Limit (mean - 2σ)
LWL = [Process Mean] - 2 * [Process StdDev]
// Out of Control flag (point outside 3σ limits)
Out of Control =
IF(
Quality_Events[MeasuredValue] > [UCL] ||
Quality_Events[MeasuredValue] < [LCL],
"Out of Control",
"In Control"
)
// Process Capability Index (Cpk)
Cpk =
MIN(
DIVIDE([UCL] - [Process Mean], 3 * [Process StdDev], 0),
DIVIDE([Process Mean] - [LCL], 3 * [Process StdDev], 0)
)
Key Quality KPIs
// Defects per Million Opportunities (DPMO)
DPMO =
DIVIDE(
SUM(Quality_Events[DefectCount]),
SUM(Quality_Events[SampleSize]) * [Opportunities per Unit],
0
) * 1000000
// Sigma Level (from DPMO)
Sigma Level =
SWITCH(TRUE(),
[DPMO] < 3.4, 6,
[DPMO] < 233, 5,
[DPMO] < 6210, 4,
[DPMO] < 66807, 3,
[DPMO] < 308537, 2,
1
)
// Defect Rate %
Defect Rate = DIVIDE(SUM(Quality_Events[DefectCount]), SUM(Quality_Events[SampleSize]), 0)
// Scrap Rate
Scrap Rate =
DIVIDE(
SUM(Production_Runs[ScrapQuantity]),
SUM(Production_Runs[ActualQuantity]),
0
)
// Cost of Poor Quality (COPQ)
COPQ =
SUMX(
Production_Runs,
(Production_Runs[ScrapQuantity] + Production_Runs[ReworkQuantity]) *
RELATED(Dim_Product[StandardCost])
)
Throughput Analysis
Production Throughput KPIs
// Actual Throughput (units per hour)
Throughput =
DIVIDE(
SUM(Production_Runs[ActualQuantity]),
SUMX(Production_Runs,
DATEDIFF(Production_Runs[StartTime], Production_Runs[EndTime], HOUR)
),
0
)
// Theoretical Maximum Throughput
Max Throughput =
SUMX(
Dim_Machine,
60 / Dim_Machine[IdealCycleTime] -- Units per minute × 60
) * 60 -- Per hour
// Capacity Utilization
Capacity Utilization =
DIVIDE([Throughput], [Max Throughput], 0)
// Schedule Attainment (actual vs planned quantity)
Schedule Attainment =
DIVIDE(
SUM(Production_Runs[ActualQuantity]),
SUM(Production_Runs[PlannedQuantity]),
0
)
// Changeover Time (as % of planned time)
Changeover % =
DIVIDE(
[Changeover Time],
[Planned Production Time],
0
)
Line Balancing Analysis
Identify bottleneck machines using throughput comparison:
// Machine Throughput Rate (for bottleneck identification)
Machine Throughput Rate =
DIVIDE(
CALCULATE(SUM(Production_Runs[GoodQuantity])),
CALCULATE(
DATEDIFF(MIN(Production_Runs[StartTime]),
MAX(Production_Runs[EndTime]), HOUR)
),
0
)
// Bottleneck indicator (lowest throughput machine in a line)
Is Bottleneck =
IF(
[Machine Throughput Rate] = MINX(
FILTER(ALL(Dim_Machine), Dim_Machine[Line] = SELECTEDVALUE(Dim_Machine[Line])),
[Machine Throughput Rate]
),
"Bottleneck",
"OK"
)
Manufacturing Dashboard Architecture
Page 1: OEE Summary
- OEE gauge (current vs world-class 85% target)
- Availability, Performance, Quality — three KPI cards
- OEE trend 30 days (line chart)
- OEE by machine (bar chart, sorted low to high)
- OEE by shift (bar chart — identify shift performance differences)
- OEE heatmap (Machine × Day of week)
Page 2: Downtime Analysis
- Total unplanned downtime hours (KPI card)
- MTBF and MTTR (two KPI cards)
- Downtime Pareto (combination bar + line with cumulative %)
- Downtime by machine (horizontal bar chart)
- Downtime by shift (grouped bar)
- Downtime trend 90 days (line chart)
- Active downtime events (real-time table if streaming)
Page 3: Quality Dashboard
- First Pass Yield (gauge vs target)
- DPMO and Sigma Level (KPI cards)
- Scrap Rate by product (bar chart)
- COPQ trend (line chart showing cost of quality issues)
- Defect Pareto by defect code
- SPC Chart (line chart with UCL, LCL, UWL, LWL reference lines)
Page 4: Throughput and Capacity
- Schedule Attainment % (gauge)
- Actual vs Planned production (grouped bar by day)
- Capacity utilization by machine (heatmap)
- Changeover time analysis (bar chart by product/machine)
- Production output trend (area chart, actual vs target)
- Bottleneck machine highlight table
Frequently Asked Questions
What is OEE and why does it matter for manufacturing?
OEE (Overall Equipment Effectiveness) is the gold standard metric for manufacturing productivity. It combines three factors: Availability (equipment running when it should), Performance (running at the right speed), and Quality (producing good parts). A 60% OEE means you are realizing only 60% of your theoretical capacity — the other 40% is waste. Improving OEE directly increases output without capital investment in new equipment.
Can Power BI connect to MES systems for real-time OEE?
Yes — most MES systems (Ignition SCADA, GE Proficy, Siemens MES, Rockwell FactoryTalk) support database connectivity (SQL Server, Oracle) or REST API access. Power BI connects to these databases and can use streaming datasets for near-real-time updates (every 30 seconds to 1 minute). For true real-time OEE (sub-second), use Azure IoT Hub or Event Hub with Power BI Streaming datasets pushed directly from plant floor sensors.
What data does a factory need to start tracking OEE?
Minimum data requirements for basic OEE: (1) Production count data — when did the machine run and how many units were produced, (2) Downtime events — when did the machine stop and why, (3) Quality counts — how many good vs defective units. This can come from manual operator entry (Excel/paper → Power BI), basic MES, or PLC counter data. Perfect data is not required to start — even imperfect OEE visibility drives improvement.
How do I build an SPC chart in Power BI?
Create a line chart with the measurement values as the main series. Add four additional measures (UCL, LCL, UWL, LWL) as separate line series in the chart. Format UCL/LCL as red dashed lines and UWL/LWL as orange dashed lines. Conditional formatting on data points highlights out-of-control points in red. The built-in SPC custom visual from AppSource provides Western Electric rule detection (runs above/below center, trends, etc.) beyond the basic control limit approach.
What is a realistic timeline to implement a Power BI manufacturing dashboard?
A basic OEE dashboard (single machine, manual data entry via SharePoint list or Excel) can be built in 1-2 weeks. A full manufacturing analytics platform connected to MES and ERP (multi-machine, multi-line, with quality SPC, downtime Pareto, and throughput analysis) typically takes 6-12 weeks. The longest phase is always data integration and data quality — machine timestamps, downtime reason codes, and product changeovers need to be captured consistently before analytics add value.
How does ECOSIRE connect Power BI to Odoo Manufacturing?
Odoo Manufacturing stores production work orders, materials consumption, quality checks, and maintenance requests in PostgreSQL. ECOSIRE connects Power BI directly to Odoo's PostgreSQL database (on a read replica) and models the manufacturing tables (mrp.production, mrp.workcenter, quality.check, maintenance.request) into the OEE data model described in this guide. We handle the work center-level capacity planning and quality integration as part of our Odoo ERP integration practice.
Next Steps
Manufacturing analytics in Power BI — when connected to your production floor data — provides the real-time visibility that separates world-class manufacturers from average performers. OEE, downtime root cause analysis, and quality SPC charts give operations teams the information to improve before problems compound.
ECOSIRE builds manufacturing dashboards connected to MES systems, ERP platforms (Odoo, SAP, Dynamics 365), and IoT data streams. Our Power BI dashboard development services cover the full manufacturing analytics stack from data model design to production-ready dashboards.
Contact our manufacturing analytics team to discuss your plant floor data sources and design a Power BI analytics platform that drives measurable OEE improvement.
Written by
ECOSIRE TeamTechnical Writing
The ECOSIRE technical writing team covers Odoo ERP, Shopify eCommerce, AI agents, Power BI analytics, GoHighLevel automation, and enterprise software best practices. Our guides help businesses make informed technology decisions.
ECOSIRE
Unlock Data-Driven Decisions
Custom Power BI dashboards, data modeling, and embedded analytics solutions.
Related Articles
Power BI vs Tableau 2026: Complete Business Intelligence Comparison
Power BI vs Tableau 2026: head-to-head on features, pricing, ecosystem, governance, and TCO. Clear guidance on when to pick each and how to migrate.
Data Warehouse for Business Intelligence: Architecture & Implementation
Build a modern data warehouse for business intelligence. Compare Snowflake, BigQuery, Redshift, learn ETL/ELT, dimensional modeling, and Power BI integration.
ERP for Furniture Manufacturing: BOM, Custom Orders & Delivery
Learn how ERP systems handle configure-to-order furniture, complex BOMs, wood and fabric inventory, custom dimensions, delivery scheduling, and showroom POS.
More from Manufacturing in the AI Era
ERP for Fashion & Apparel: PLM, Sizing & Seasonal Collections
How ERP systems manage fashion product lifecycle, size-color matrices, seasonal collections, fabric sourcing, sample management, and B2B plus DTC channels.
ERP for Furniture Manufacturing: BOM, Custom Orders & Delivery
Learn how ERP systems handle configure-to-order furniture, complex BOMs, wood and fabric inventory, custom dimensions, delivery scheduling, and showroom POS.
Odoo vs Epicor: Manufacturing ERP Comparison 2026
Odoo vs Epicor Kinetic manufacturing ERP comparison covering MRP, shop floor, quality control, scheduling, IoT, pricing, and implementation timelines.
Case Study: Manufacturing ERP Implementation with Odoo 19
How a Pakistani auto-parts manufacturer cut order processing time by 68% and reduced inventory variance to under 2% with ECOSIRE's Odoo 19 implementation.
Digital Twins in Manufacturing: Connecting Physical and Digital
Understand how digital twin technology is transforming manufacturing—from machine-level predictive maintenance to full factory simulation and ERP integration strategies.
ERP for Automotive: Parts Management, Service, and Manufacturing
Complete guide to ERP for the automotive industry — parts management, dealer operations, vehicle service, manufacturing, and supply chain for 2026.