Report-by-Exception in SCADA: Why It Breaks When You Treat It Like Slow Polling
Running report-by-exception and change-of-state — DNP3 events, deadbands, heartbeats, integrity polls — without losing short events or stale values.
A trend that sits dead flat for six hours and then jumps 40% in a single sample is almost never the process. It's a report-by-exception path that dropped an event, buffered it wrong, or stamped it with receive time instead of source time. By the time an operator asks why the tank "suddenly" filled, the evidence is three queues back and gone.
Report-by-exception (RBE) means a device, gateway, or driver sends an update only when a value changes enough to matter. Change-of-state (COS) is the digital case: send the transition when a bit flips. In DNP3 (IEEE 1815) this is the whole point of Class 1/2/3 event data and unsolicited responses; Modbus has no native version, which is why people bolt deadbands onto poll drivers and then wonder why it behaves differently.
It does behave differently, and that's the mistake I see most: treating RBE as polling with fewer messages. Polling is stateless — miss one, the next scan corrects it. RBE is stateful. Miss one event and the wrong value can sit on the HMI until the next real change, which for a breaker status might be next month. The system has to preserve every transition, timestamp it correctly, and still prove that a point that hasn't spoken in four hours is alive rather than dead.
Decide which points can be event-driven
Not every tag is a good RBE candidate. Classify tags by operational risk and by the kind of change the operator needs to see.
| Tag type | Good RBE use | Watch carefully |
|---|---|---|
| Digital equipment state | Run, stop, open, closed, fault bits | Fast pulses, chattering contacts, interlock bits |
| Analog process value | Slow level, temperature, pressure | Fast control loops, vibration, short excursions |
| Counters and totals | Batch count, energy total, runtime | Counter rollover, reset, missed increments |
| Alarms | Alarm set and clear events | Ordering, duplicate clears, shelving state |
| Communication health | Link up/down, device online | Heartbeat still needed when nothing changes |
A good rule is simple: if a missed transition would change the operator's action or the production record, do not rely on an untested RBE path.
Keep a heartbeat separate from value changes
A quiet value is not the same as a healthy value. If a remote tank level has not changed for four hours, that may be normal. It may also mean the radio link failed four hours ago.
Use a separate heartbeat or communication-quality tag. Common patterns include:
- device sequence number increments every fixed interval;
- gateway publishes a link status and last-good timestamp;
- SCADA driver records last update time per device;
- RTU sends a periodic integrity scan even if values did not change;
- alarm is raised when no update arrives within the expected window.
Do not make operators infer communication health from a flat process value. Show stale data clearly and keep the last-good value distinct from current quality.
Set deadbands by process meaning, not network fear
Analog RBE fires on a deadband: report when the value moves more than a configured amount. Know which kind of deadband you're setting before you argue about the number. OPC UA (part 4, DataChangeFilter) gives you DeadbandType of Absolute or Percent — and Percent is percent of the item's EU range, not percent of the current value, which trips people up constantly. DNP3 analog change events (Group 32) work off a per-point deadband register you set on the outstation. Set that amount from what the process means, not from network anxiety:
- A storage tank level tolerates a 0.5% deadband — nobody acts on 2 mm of sludge.
- A reactor temperature near an alarm setpoint may need 0.1 °C, or a periodic confirmation so the last-good value doesn't age silently.
- A compressed-air header wants tighter reporting near the low-pressure trip and can loosen well above it.
- A noisy 4–20 mA signal needs filtering before the deadband — a big deadband to swallow the noise also swallows the real 3% excursion you were trying to catch.
If the only justification for a wide deadband is "the network is busy," you have a scan-design or data-grouping problem wearing a deadband as a disguise. Fix the capacity. A deadband that hides useful movement doesn't save bandwidth; it just moves the cost to whoever troubleshoots the flat trend six months later.
Preserve ordering and timestamps
RBE data often crosses queues: device buffer, radio master, protocol gateway, SCADA driver, historian interface, and alarm service. The receive order may not match the event order.
For useful records, capture at least:
- source timestamp when the field device detected the change;
- receive timestamp at the SCADA or gateway;
- point value and quality;
- sequence number or event number if available;
- device or channel that produced the event.
The historian should store the source timestamp when that timestamp is trustworthy. If only receive time is available, document that limitation. During an outage, all buffered events may arrive at once; without source time they look like a sudden process jump.
Test short pulses and chatter
RBE systems fail most often on short digital changes. A motor overload bit may turn on for 300 ms and clear. A limit switch may bounce. A PLC one-shot may exist for one scan. A radio link may batch several changes into one transmission.
Commissioning tests should include:
- a normal state change that stays active;
- a short pulse shorter than the normal poll interval;
- rapid on/off chatter for a known number of transitions;
- a change during a network disconnect;
- a change while the gateway queue is near full;
- a device restart while the point is active.
For each test, compare the PLC or RTU record, SCADA alarm/event list, historian samples, and operator screen. The same event should be explainable in all four places.
Use integrity scans to recover state
Event-driven systems still need a full-state read. In DNP3 that's the integrity poll — a Class 0 read that returns current static values, which the master should fire on startup and any time it sees the outstation's restart IIN bit (IIN1.7, "device restart") or an event-buffer-overflow indication. Without it, SCADA can hold a stale value forever, because no new change ever arrives to correct it.
That's merely annoying on a tank level and dangerous on alarms and permissives. A fault bit that set and cleared while the link was down never appears at all; worse, a fault that cleared during the outage stays latched active on the HMI, and an operator refuses to start equipment that's actually fine — or trusts one that isn't.
Typical recovery behavior:
- mark affected points uncertain or stale when communication is lost;
- buffer events where the protocol supports it;
- request current state after reconnect;
- reconcile buffered events with the current state;
- create an operator-visible communication event if data may be incomplete.
Common failure modes
| Symptom | Likely cause | Field check |
|---|---|---|
| Flat trend during an outage, then sudden step | Receive time stored instead of source time | Compare source timestamp and archive timestamp |
| Alarm set is missing but clear exists | Short pulse or queue loss | Test with PLC event counter and driver diagnostics |
| HMI shows old state after RTU restart | No integrity scan or stale quality handling | Force restart and watch quality transitions |
| Counter is lower than production count | Missed increments or rollover handling | Test rollover and compare against local counter |
| Network improves but events still missing | Gateway queue or SCADA event thread overloaded | Check queue depth, discard counters, CPU, and logs |
Practical commissioning record
For each RBE channel, leave behind a short record:
- points using RBE or COS;
- deadband and minimum reporting interval;
- heartbeat or integrity scan interval;
- timestamp source and timezone rule;
- buffer depth and overflow behavior;
- diagnostics tags exposed to SCADA;
- test results for short pulses, disconnect, reconnect, and restart.
That record is more useful than a generic statement that the system "uses RBE." It tells the next engineer what behavior was actually proven.