Why OEE Projects in WA Mining Fail

Most iron ore sites in the Pilbara have an OEE dashboard. It's on a PC that runs Internet Explorer 11, it was built in 2014, and the last person who knew how to edit it left in 2021. The numbers it shows are wrong — not because the PLCs are misconfigured, but because nobody's updated the shift-log baseline in three years. The dashboard is a historical artifact dressed up as operational tooling.

That's the soft failure. The hard failure is when an OEE project actually starts and then breaks under Pilbara operating conditions. Here's where projects die:

Manual Data Entry

The OEE calculation requires availability, performance, and quality inputs. In practice, half these inputs come from a shift supervisor manually typing numbers into a spreadsheet at the end of each shift. The OEE number is only as good as the transcription. On a 14:14 FIFO rotation, the new supervisor starts with no handover context beyond a whiteboard note that says "crusher issue — see John." Nobody typed the nature of the issue anywhere. The OEE report for that shift says 0% unplanned downtime.

Vendor-Locked Historians

PI Server, Wonderware, and Inductive Automation dashboards are typically installed and locked by whoever commissioned the system. Updating a tag address, adding a new line, or changing a calculation requires a vendor engagement — either a service contract or a billable visit. The OEE formula becomes fixed. If the production engineer wants to add a new quality metric (say, lump:fines ratio deviation), it's a project, not a configuration change.

Cyclone-Season Comms Dropouts

The Pilbara cyclone season runs November to April. A Category 2 cyclone that tracks across the central Pilbara will take out satellite backhaul for 48–72 hours at remote sites. If your OEE dashboard is running on a centralised system that requires real-time connectivity, you'll have three days of missing data, then a backlog of manual entries with incorrect timestamps. The OEE report for that cyclone week will say "data unavailable" — and nobody will know if the plant actually ran at 40% OEE or 70%.

FIFO Crew Handovers

On a 14:14 FIFO rotation, the crew changes every two weeks. Production context — current issues, running conditions, shift targets — lives in the heads of the people on site. The outgoing supervisor tells the incoming supervisor about the SAG mill bearing temperature, but that conversation doesn't make it into the OEE system. New crew means new calculation assumptions, new baselines, and a week of degraded data until someone notices.

What a Real OEE Stack Looks Like

OEE is Availability × Performance × Quality. Each factor requires clean tag data from the PLC layer:

Availability — Allen-Bradley ControlLogix Tags

Availability measures unplanned stops and planned stops. From a ControlLogix PLC:

// Example: Conveyor CV-01 availability tags (Allen-Bradley)
OEE_AVAIL_CV01_RUN      = "[PLC]CV01_RUN"        // Running state (bool)
OEE_AVAIL_CV01_STOP_REASON = "[PLC]CV01_STOP_CODE"  // 0=running, 1=planned, 2=unplanned
OEE_AVAIL_CV01_BD_COUNT   = "[PLC]CV01_BD_COUNT"    // Bad actors counter
OEE_AVAIL_CV01_PLAN_MIN    = "[PLC]CV01_PLAN_MIN"     // Planned maintenance minutes (int)

Performance — Siemens S7 Tags

Performance measures actual speed vs. ideal cycle time:

// Example: SAG Mill SAG-01 performance tags (Siemens S7)
OEE_PERF_SAG01_ACT_RATE  = "S7-1200.SAG01.ACT_TPH"   // Actual throughput (real)
OEE_PERF_SAG01_IDEAL_RATE = "S7-1200.SAG01.DESIGN_TPH" // Design/ideal throughput (real)
OEE_PERF_SAG01_CYC_SEC    = "S7-1200.SAG01.CYCLE_SEC" // Current cycle time (real)
OEE_PERF_SAG01_IDEAL_SEC  = "S7-1200.SAG01.IDEAL_CYC" // Ideal cycle time (real)

Quality — Reject and Yield Tags

Quality measures good product vs. total product:

// Example: Crushing circuit quality tags
OEE_QUAL_CRUSHER_REJECT   = "[PLC]CR01_REJECT_TPH"    // Reject tonnes/hr
OEE_QUAL_CRUSHER_FEED      = "[PLC]CR01_FEED_TPH"       // Feed tonnes/hr
OEE_QUAL_CRUSHER_LUMP_RATIO= "[PLC]CR01_LUMP_RATIO"     // Lump:fines ratio (quality proxy)

The OEE calculation then runs in real time at the edge — not in a central server — so it survives satellite outages:

// OEE = Availability × Performance × Quality
// Runs at Ignition Edge — local compute, no central dependency

AVAIL = (Run_Minutes - Unplanned_Stop_Minutes) / Run_Minutes
PERF  = Actual_Rate / Ideal_Rate
QUAL  = (Feed_TPH - Reject_TPH) / Feed_TPH
OEE   = AVAIL × PERF × QUAL   // Expressed as decimal, e.g. 0.73

Reference Architecture — Ignition Edge → MES Dashboard

The data flows from PLC register to OEE dashboard in three hops, all surviving disconnection:

FIELD LAYER (L0) Allen-Bradley ControlLogix PLC EtherNet/IP · Rockwell tags Siemens S7-1500 PLC Profinet · Siemens DB blocks EDGE (L2) Inductive Automation Ignition Edge OEE calculation engine · Sparkplug B publisher · store-and-forward buffer Runs on local industrial PC · survives 72hr satellite outage · no cloud dependency EMQX Edge Broker (Sparkplug B / MQTT) Queue depth 10,000 messages · NBIRTH/DBIRTH on reconnect · RBE compression 4Mbps / 600ms Satellite 48–72hr queue CLOUD (L4) EMQX Cloud MQTT bridge Ignition Gateway MES tag store MES Dashboard OEE · Availability · Performance EtherNet/IP Profinet Sparkplug B OEE Data Flow — Pilbara Iron Ore — Ignition Edge + Sparkplug B + MES OEE calc runs local — satellite outage does not interrupt OEE data collection
Figure 1: OEE data path — PLC tags → Ignition Edge (local OEE calc) → EMQX Edge (queue on outage) → Ignition Gateway → MES dashboard. The OEE calculation survives 72-hour satellite dropouts because it runs at the edge, not in the cloud.

Sparkplug B Namespace — Crushing/Screening Circuit

The Sparkplug B namespace structure for the crushing circuit follows the ISA-95 hierarchy — Group maps to Site/Area, Edge Node maps to a physical data concentrator, and Device maps to an individual PLC or sub-system:

# Sparkplug B namespace — crushing/screening circuit, Pilbara iron ore

## Group ID: site-level namespace
group_id: "pilbara-crusher-north"
  # Maps to site: Crusher North, Newman WA

## Edge Node ID: PLC gateway / data concentrator
edge_node_id: "en-cr01-primary"
  # Ignition Edge on site network — primary OEE node

## Device IDs: individual sub-systems
device_id: "cr01-feeder"     # Crusher 01 apron feeder
device_id: "cr01-jaw"       # Primary jaw crusher
device_id: "cr01-hydraulic"  # Crusher hydraulic unit
device_id: "cv01-conveyor"   # CV01 product conveyor
device_id: "screen-01"      # Vibrating screen deck 1

Metric naming uses a consistent schema for OEE-specific metrics, so dashboards can aggregate across circuits without per-site mapping:

# OEE metric payload — Sparkplug B message on device "cr01-feeder"
# Published from Ignition Edge every scan cycle

metric: [
  { name: "oee/availability/run_min",      type: "Float",  value: 420.0 },
  { name: "oee/availability/unplanned_min", type: "Float",  value: 34.5  },
  { name: "oee/availability/avail_pct",     type: "Float",  value: 0.917 },
  { name: "oee/performance/actual_tph",    type: "Float",  value: 1825.0 },
  { name: "oee/performance/design_tph",     type: "Float",  value: 2100.0 },
  { name: "oee/performance/perf_pct",       type: "Float",  value: 0.869 },
  { name: "oee/quality/reject_tph",         type: "Float",  value: 55.0   },
  { name: "oee/quality/quality_pct",        type: "Float",  value: 0.97  },
  { name: "oee/oee_pct",                    type: "Float",  value: 0.774 },
  { name: "oee/shift_id",                   type: "String", value: "AM-2024-11-22-06" },
  { name: "oee/seq",                        type: "Int",    value: 4817  }
]

The seq field is critical — it's the Sparkplug B sequence number, and it allows the receiving system to detect missing messages after a satellite dropout. If the sequence jumps from 4814 to 4817, the system knows three messages were queued and not yet delivered. Time-series ingest pipelines use this to mark data continuity and flag gaps.

Survives-a-Cyclone Design

When Cyclone Heidi crossed the Newman–Tom Price corridor in March 2024, several remote sites lost satellite connectivity for 67 hours. Sites with centralised OEE systems had 67 hours of missing data and no recovery path. Sites running Ignition Edge with EMQX local store-and-forward didn't miss a measurement.

Store-and-Forward at the Edge

The EMQX edge broker on the Ignition Edge node has a local message queue configured with a depth of 10,000 messages. When the satellite link drops, MQTT publish attempts fail and messages are written to the local queue in order. The queue persists on the industrial PC's local SSD — not in memory — so it survives the edge node being power-cycled during the storm.

When the satellite restores, the EMQX edge broker reconnects to the enterprise MQTT broker and drains the queue in order. The sequence number field ensures the enterprise system knows which messages were in the queue vs. newly published.

NBIRTH / DBIRTH on Reconnect

When the edge node reconnects, it sends an NBIRTH (Node Birth) message to the enterprise MQTT broker. This tells the central system:

The enterprise broker uses the NBIRTH to re-register the edge node in the MQTT topic tree and reconcile the queue drain against the sequence numbers. No manual intervention required — the system self-heals.

RBE Compression — Optimising Satellite Bandwidth

During a satellite dropout, the edge node should not simply buffer everything and dump it all on reconnect. That's inefficient and can saturate the restored link. The design uses Report By Exception (RBE) compression: the edge node only publishes a metric when it changes by more than a configured deadband.

# Telegraf → EMQX — RBE/deadband configuration
# Only publishes when value changes by more than deadband

[[inputs.mqtt_consumer]]
  servers = ["tcp://localhost:1883"]
  qos = 1
  topics = ["spBv1.0/#"]

[[processors.threshold]]
  nameprefix = "rbe_"
  tagpass = ["topic"]

# Deadband: only send when value changes by 1% or more
[[outputs.mqtt]]
  broker = "tcp://satellite-gateway:1883"
  qos = 1
  store_on_disk = true       # Persist queue across restarts
  max_queued_messages = 10000  # Queue depth for outage

Satellite Backhaul Fallback

The edge node is configured with two MQTT broker endpoints: the primary (via site LAN) and the satellite fallback (via BGAN or Starlink backhaul). On primary failure, the EMQX edge broker switches to the fallback endpoint. The MQTT session state is preserved — the session is persistent, not clean — so the queue drain starts immediately without re-sending.

What a 4-Week RATECH OEE Pilot Proves

The RATECH OEE pilot is four weeks on-site at a single processing line. We instrument the line, connect the OEE stack, and measure the actual OEE delta against your existing shift-log baseline. This is not a proof of concept — it's a production prototype that runs on live data from day one.

Here's what the pilot delivers:

Week 1 — Tag Audit and OEE Baseline

Week 2 — OEE Stack Commissioning

Week 3 — Live OEE + Cyclone Test

Week 4 — OEE Delta Report

# OEE Pilot — success criteria summary
OEE_DELTA     = Automated_OEE - Shift_Log_OEE
TARGET       = |OEE_DELTA| < 3%  // Accurate to within 3 percentage points
DATA_COVERAGE = Uptime / Total_Time > 98%  // No missing shifts
FIFO_HANDOFF = OEE calculation continuous across crew change // No gaps at shift boundary