A report shows “Reactor temperature: 72.4 °C”. But was this value measured just now, or did the sensor drop out three hours ago and the system is showing the last valid value? Is it a true measurement or a default? Quality and timestamp answer these questions; without them a value is an untrustworthy number.
In OPC UA a data point is not just a value: value + source timestamp + server timestamp + status code (quality). Reporting and integration should carry all four together.
The structure of a data point
Quality: Good, Uncertain, Bad
The severity bits of the OPC UA status code split data reliability into three classes:
| Class | Meaning | Example situations | Report behaviour |
|---|---|---|---|
| Good | The value is reliable | Normal measurement; local override | Use normally |
| Uncertain | The value is usable but doubtful | Last usable value; substitute value; sensor accuracy reduced | Flag it; be careful in calculations |
| Bad | The value is not reliable | No communication, device or sensor failure, configuration error | Exclude from calculations; show as a gap |
Beneath these classes are detailed codes (for example Bad_NotConnected, Bad_SensorFailure, Uncertain_LastUsableValue); in troubleshooting these codes point the way.
Timestamps: two separate times
- Source timestamp (SourceTimestamp): when the value was produced at the source (in the device or driver).
- Server timestamp (ServerTimestamp): when the server received the value.
The difference between them reveals latency and stale data. Points to watch:
- Who stamps the time? If the device supplies its own time, the source time is close to the event. If the device gives no timestamp, the driver stamps the read moment, which is the read time, not the event time. If you need sequence of events (SOE), use devices that produce timestamped events.
- Are the clocks synchronized? Without NTP (or PTP for precise applications), times from different devices cannot be compared with confidence.
- Time zone and daylight saving: store time in UTC and convert to local time for display.
- Sampling interval: the scan rate limits time resolution; a value read once a second does not mean a millisecond-accurate event.
How to preserve quality in SQL and reports
- For each record, store the quality and source timestamp together with the value (moving PLC data into SQL).
- Do not write a Bad value as zero. Zero is a valid measurement; it makes bad data indistinguishable from a real zero. Leave it NULL and record the quality.
- Detect stale data: if
now − source_timeexceeds a threshold, flag the value as stale. - In calculations (OEE, consumption, averages) use only Good records, or handle the gap explicitly (preparing OEE data).
- In transformations (OPC UA → MQTT/SQL) do not drop quality and timestamp; otherwise the information the source provided is lost on the way.
What to verify in acceptance testing
- Whether pulling a cable turns quality to Bad and whether reports show it.
- Whether the difference between source and server time is reasonable.
- Whether values flow again with the correct quality when the connection returns.
These checks can be added to the integration acceptance test list. For OPC UA basics see What is OPC UA?.
Frequently asked questions
Can I use Uncertain-quality data?
It depends. For example, “last usable value” can be an approximate indicator in short outages, but it is safer not to use it in critical calculations such as billing or quality decisions. Write a rule for each use.
Why do source and server time differ?
Because of latency, scan interval, clock offset or the device not supplying its own time. If the difference grows, inspect the connection and clock synchronization.
Is quality lost when data moves to MQTT?
Yes, if fields are not mapped in the transformation. A schema such as Sparkplug B, or your own JSON schema, must include quality and timestamp fields.


