An engineer asked how a conveyor's OEE state is calculated. The routine they were reading only calls the instruction that decides it. The state machine sits inside three vendor add-on instructions, among 148 in a 112 MB export, and the rule that separates blocked from faulted is a single alarm-code threshold.
An engineer asked, in plain language, how a conveyor reports its OEE state. The routine they were reading only calls the instruction that decides it. The decision itself sits inside an OEM add-on instruction that most sites treat as a sealed box.
The question came in the way real questions do. Not as a tag name, not as a routine, just: how is the OEE state for this inbound conveyor calculated, in terms an operator can use?
The engineer had already pasted the structured text they were looking at. It was the wrong layer. That routine calls three OEM add-on instructions and passes them arguments. The state machine, the alarm precedence, and the thresholds all live inside those instructions, in a 112 MB full-controller export holding 148 of them.
What the decode returned
The three instruction bodies came out of the export and were read as one unit. The state resolution is a precedence chain evaluated last-write-wins, in this order: maintenance, manual, abort, stopped, idle, running.
For this conveyor, only three of those states are reachable. The rest are not wired.
| State | Code | What it means on the floor |
|---|---|---|
| Running | 129 | The zone is enabled and allowed to run. An empty belt still reports Running. Running does not mean product is moving. |
| Stopped | 128 | The zone is not enabled and nothing is faulted. Normal stop, or downstream cannot accept. |
| Faulted | 127 | A real fault is active and the line is down. |
The rule that mattered was inside the abort branch. The instruction sets its abort output on any active alarm code from 1 to 119. Codes of 120 and above deliberately do not fault the conveyor. Alarm 121, downstream disabled, is the common one.
That single threshold is the whole difference between blocked and faulted:
- A jam, a motor fault, an air pressure fault, a power fault, a network fault, or a fire system shutdown all sit below 120, so they drive the conveyor to Faulted with an alarm code attached.
- Downstream full raises alarm 121 and leaves the state at Stopped. The pairing of Stopped plus alarm 121 is the site's actual definition of blocked, and nothing on the screen says so.
You do not get that from the calling routine. You get it by reading the instruction body, which is exactly the layer most teams cannot open.
The gap that mattered more than the answer
The engineer's real interest was the percentage numbers: available, starved, blocked. The decode showed that this conveyor has no starved input wired at all. A running belt with nothing on it reports Running, full stop.
The percentages are computed above the controller, in a performance service that the instruction's own comment names. That boundary is the useful finding. It tells the site where the number they are arguing about is actually produced, which is not where they were looking.
Three defects found on the way through
Reading logic carefully surfaces things nobody asked about:
- The idle branch of the state instruction skips the multi-state error code check that every other branch performs.
- The manager instruction contains a timer enable assignment that is immediately overwritten, so it does nothing.
- One routine block is missing the inversion on the downstream-disabled bit that all of its sibling blocks have, which means that block treats a blocked condition differently from the rest of the line.
None of these were the question. All three are real, and all three are cited to the line that contains them.
From answer to artifact
The session ended with a one-page operator reference: the three states, the fault table with the alarm number and the signal behind each one, an explicit note that the safety stop path is safety logic and gets read rather than defeated, and a four-step triage list.
The triage is the part that travels:
- 01State 127: read the active alarm number, clear that device, reset.
- 02State 128 with alarm 121: not a fault. Downstream is full. Check the next area, not this conveyor.
- 03State 128 with no alarm: normal or commanded stop. Check the start permissive and zone enable.
- 04State 129 with no throughput: the belt is up and starved. Look upstream.
What this does and does not prove
Worth being direct about the boundary: a senior controls engineer with the unprotected export open can read the same instruction. The difference here is time, the fact that the output is a document a shift can keep, and the three unrelated defects that turned up on the way through.
Two limits were live in this session and worth stating plainly.
The first is the one above. Comprehension stops at the controller boundary. The service that computes the availability percentages could be named, from a comment inside the instruction, but not read, because it was not in the corpus. The answer to "why is this number wrong" needs the layer above the PLC too.
The second is vocabulary. Roughly half the operator-facing abbreviations on this line had no confirmed expansion for this site. The system flagged them as unconfirmed and told the reader to ask a site expert rather than inventing plausible expansions. That is the correct behavior and it still means a person finishes the last mile on wording.
The logic relationships were exact. The prose around them was honest about what it did not know. Both of those matter more than a clean-looking answer.