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:
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 edge node is online and what version of the Sparkplug B stack it's running
- Which devices are attached and their metadata
- The current sequence number and the timestamp of the last successful publish
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
- Map all PLC tags relevant to OEE calculation (availability, performance, quality)
- Document current OEE calculation methodology vs. ISA 95 standard
- Establish the OEE baseline from existing shift logs and PI historian
- Install Ignition Edge on nominated industrial PC
Week 2 — OEE Stack Commissioning
- Configure Sparkplug B namespace on Ignition Edge
- Commission EMQX edge broker with store-and-forward queue
- Connect to central Ignition Gateway (satellite or site WAN)
- Configure first MES dashboard — one circuit, all three OEE factors
Week 3 — Live OEE + Cyclone Test
- Run automated OEE in parallel with existing manual method
- Document the delta — how far does the automated number differ from the manual entry?
- If cyclone window exists, test store-and-forward recovery
- Refine threshold/deadband configuration based on real tag behaviour
Week 4 — OEE Delta Report
- Measure the OEE delta: automated OEE vs. shift-log baseline
- Document data gaps, reconciliation methodology, and FIFO handover accuracy
- Present findings: what OEE accuracy did we achieve, what remains manual, what should the paid rollout target
- Define the Phase 2 scope: additional circuits, enterprise historian integration, dashboard roll-out
# 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