A sensor produces a value, a protocol adapter acquires it, the server converts it to a typed internal point, and an OPC UA client reads that point through the server's Address Space. Follow that path in order. A well-designed Information Model describes the measurement independently of whether its source is MODBUS, NMEA, or another device protocol.
Where does each sensor value enter the data path?
Layer one first. Confirm that the sensor interface delivers valid data before creating OPC UA nodes. For a register-oriented source, verify the device connection and register read. For a message-oriented source, verify reception and parsing of complete messages. A server cannot correct stale registers, malformed frames, missing terminators, or an incorrect physical interface.
| Path element | Setting to record | Commissioning check |
|---|---|---|
| Sensor to protocol adapter | Physical interface, device address, serial or network settings | Observe a valid value changing at the adapter |
| Adapter to acquisition software | Register or message field, data type, byte order, scaling | Compare the decoded value with the device indication |
| Acquisition software to OPC UA server | Internal point name, update trigger, status, source timestamp | Log one complete point update before node publication |
| OPC UA server to client | Server address, configured port, security settings, sampling behavior | Connect and browse from the sample client |
Address and port values belong to the actual device and server configurations; read them there rather than copying assumed defaults. Likewise, derive update timing from device delivery and server configuration. The check that permits the next step is a decoded engineering value at the acquisition boundary with its source identity and update time intact.
How should transport-specific data be normalized?
Do not expose raw transport details as the primary client interface unless clients genuinely need them. Convert each input into a protocol-neutral point record containing a stable name, value, data type, engineering unit when known, status, source timestamp, and source mapping. This separates acquisition from publication: a later device change affects the adapter mapping without forcing every OPC UA client to understand the new transport.
| Input characteristic | Normalization decision | Common failure |
|---|---|---|
MODBUS register or register group |
Decode signedness, width, byte order, and scale before publication | A numerically valid but physically incorrect value |
NMEA message field |
Validate the message, parse the field, and assign its meaning and type | Publishing text when clients require a numeric measurement |
| Missing or rejected update | Retain an explicit bad or uncertain status according to server behavior | Presenting the last value as current and good |
| Device time available | Carry it as the source timestamp | Replacing measurement time with client read time |
Keep the raw register, message, or field mapping in configuration or diagnostic properties. Give clients the decoded measurement. Prove this stage by comparing the normalized value, type, status, and timestamp with one known sensor sample.
Which OPC UA nodes should represent the measurements?
Use objects to represent equipment or logical groups and variables to represent values. A sensor can be an object with variables beneath it, while a collection of related sensors can sit below a subsystem object. This produces a browsable hierarchy without making the hierarchy itself carry the data.
Choose each variable's OPC UA data type from the normalized value, not from the transport container. A pair of registers may decode to one numeric value; a message field may also decode to that same type. Both should appear consistently to clients when they represent the same engineering concept. Keep identifiers stable across server restarts and configuration reloads so client subscriptions and saved displays do not break.
| Model element | Purpose | Client-visible result |
|---|---|---|
| Equipment or sensor object | Represents the logical asset | A stable browse location |
| Measurement variable | Publishes the current typed value | Readable or subscribable process data |
| Properties | Describe unit, source mapping, or configuration metadata | Context for interpreting the value |
| Status and timestamps | Describe validity and age | Detection of stale or failed acquisition |
Avoid building one flat list when the data naturally belongs to devices, and avoid creating a new node for every sample. The variable is persistent; its value, status, and timestamps change. Browse the proposed tree and confirm that an engineer can locate a measurement from the asset name without knowing its MODBUS register or NMEA field.
How do references organize the Address Space?
References are typed relationships between nodes. They let a client navigate from a parent object to components and properties, and from an instance to the type that defines its structure. A reference does not copy a value or move data. It states how two nodes relate.
Use hierarchical relationships for the browse path from a system to a device and then to its measurements. Use non-hierarchical relationships only when the model needs another semantic connection that the hierarchy cannot express. The forward direction should read naturally from the parent toward the child. If two folders point to the same variable merely to create alternate navigation, clients may encounter the same node through multiple paths; use that deliberately, not as a substitute for a clear primary hierarchy.
Define a reusable type when multiple sensors share the same structure. Instances can then expose the same measurement and metadata pattern while holding different values and source mappings. For a small first server, a direct object-and-variable hierarchy is enough; introduce reusable types when repetition becomes real.
Test references with a generic browse operation: expand the root grouping, select one sensor, and locate its measurement and properties. Then read the variable directly. Successful browsing plus a correct read proves that both the relationships and value binding work.
How should the model be built with the Java SDK?
Use the SDK's sample server as the construction pattern, but replace demonstration nodes with the normalized sensor model. Keep acquisition code separate from address-space construction. The model-building layer creates stable objects, variables, identifiers, types, and references; the update layer writes new values, statuses, and timestamps to existing variables.
- Create one namespace for the application's model using the mechanism provided by the Java SDK.
- Create the top-level equipment or sensor grouping.
- Create a stable object for each configured sensor or logical device.
- Add typed measurement variables and the properties needed to interpret them.
- Connect the nodes with the SDK's hierarchical reference or component APIs.
- Bind each variable to its normalized point rather than reading the device again inside a client read callback.
- On every accepted acquisition update, write the value together with its status and timestamp.
- Start the server and use the existing sample client to connect, browse, read, and subscribe.
Do not derive persistent node identity from a transient list position. Reordering a configuration file must not silently turn yesterday's temperature node into today's pressure node. After restarting the server, reconnect the sample client and confirm that the same configured sensor resolves to the same node and data type.
How is the complete path verified?
Exercise one controlled sensor change and follow it through every hop. Record the raw input, decoded value, normalized point, server variable, and client observation. For a subscription, distinguish source update time from client delivery time; network and client scheduling can delay delivery without changing when the sensor value was acquired.
| Test | Expected observation | If it fails |
|---|---|---|
| Browse | The sensor appears under the intended object hierarchy | Inspect node creation and hierarchical references |
| Read | Value and data type match the normalized point | Inspect decoding, scaling, and variable binding |
| Status | A failed acquisition is not reported as a current good sample | Inspect adapter error propagation |
| Timestamp | The source timestamp follows acquisition time | Inspect the update record passed to the server |
| Subscription | A controlled source change reaches the client | Follow updates from adapter to variable before changing client settings |
| Restart | The client finds the same nodes with compatible types | Replace transient identifiers with stable configuration-based identities |
Finish by disconnecting the source long enough to trigger the acquisition layer's configured failure handling, observing the resulting status at the client, restoring the source, and confirming that a fresh value and source timestamp travel end to end.
FAQ
Can I publish raw MODBUS registers directly through OPC UA?
Yes, but decoded engineering variables make clients independent of register width, byte order, and scaling. Keep the raw mapping as diagnostic metadata when maintenance users need it.
Can I represent NMEA fields and MODBUS values in one model?
Yes. Normalize both sources into typed points, then organize them by sensor or equipment function rather than transport protocol.
Does an OPC UA reference contain the sensor value?
No. A reference relates nodes and supports navigation; the variable node carries the value, status, and timestamps.
Can I change the browse hierarchy after clients are deployed?
You can, but changing stable node identities can break saved client references and subscriptions. Preserve node identity and data type when reorganizing navigation.
Does a successful OPC UA read prove the sensor path works?
No. Change one sensor input, trace its decoded and normalized forms, observe the subscribed client update, test acquisition failure status, restore the source, and verify the fresh value and source timestamp at the client.