Read measurements through OPC UA
Browse the gateway address space and retrieve current or historical values.
Preserved OPC UA node layout and AccelerationPack format from the earlier Sensor Dashboard documentation and public asyncua examples. Browse names, data types and available history must match your installed sensor and software.
Connect and browse the sensor
The guide uses opc.tcp://<gateway-ip>:4840. With the documented hotspot, the address is opc.tcp://192.168.42.1:4840. The public Python programs use an endpoint ending in /freeopcua/server; use the endpoint exposed by your actual gateway.
In UaExpert, choose Server > Add, enter the endpoint and connect. Expand the sensor identified by its macId in the Address Space to inspect its attributes. The Python examples resolve the iQunet namespace from http://www.iqunet.com instead of hard-coding a namespace number.
Read temperature history in UaExpert
Choose Document > Add and select History Trend View. Drag the sensor’s boardTemperature attribute into the configuration window.
A single update requests the values between two selected times. A cyclic update repeats the historical request over the configured timespan at the selected update interval. Set an interval that contains recorded data; an empty response is not a zero-valued measurement.
Read bounded history in Python
This shortened read-only example follows the public OPCuaGetVibrationData.py browsing and read_raw_history sequence. It accepts an endpoint, a sensor macId and explicit timezone-aware start/end datetimes, and requests up to 100 values for the chosen interval.
It keeps SourceTimestamp, ServerTimestamp and StatusCode beside each value instead of discarding them. Check status before analysis. A bounded request is not a complete export of an arbitrary history: handle further ranges or continuation behavior supported by your client and server.
Adapt this asyncua function to your client version and installation access settings. Call it with your selected endpoint, sensor identity and time range.
from asyncua import Client, ua
async def read_temperature_history(
endpoint, mac_id, start, end
):
# Use timezone-aware start/end datetimes.
async with Client(endpoint, timeout=15) as client:
namespace = (
await client.get_namespace_index(
"http://www.iqunet.com"
)
)
root = client.get_root_node()
objects = await root.get_child(
[ua.QualifiedName("Objects", 0)]
)
node = await objects.get_child([
ua.QualifiedName(mac_id, namespace),
ua.QualifiedName(
"boardTemperature", namespace
),
])
values = await node.read_raw_history(
starttime=start,
endtime=end,
numvalues=100,
)
return [
(
value.SourceTimestamp,
value.ServerTimestamp,
value.StatusCode,
value.Value.Value,
)
for value in values
]Use processed vibration values
For a direct correspondence with the documented dashboard output, use the processed vibration structure rather than rescaling accelerationPack. The public structure example loads the server’s data-type definitions before reading custom values.
Under the sensor’s vibration node, it browses axis, quantity and end-node names. For example, x / accel / xAccelTime returns a structure with x_abscissa, y_ordinate and axis. The processed acceleration values are already in g; the velocity values are in mm/s.
The following example reads only X-axis acceleration in the time domain. The original program iterates X, Y and Z, acceleration and velocity, and time and frequency domains. Inspect the actual node tree before substituting another path.
from asyncua import Client, ua
async def read_x_acceleration_history(
endpoint, mac_id, start, end
):
async with Client(endpoint, timeout=15) as client:
await client.load_data_type_definitions()
namespace = (
await client.get_namespace_index(
"http://www.iqunet.com"
)
)
root = client.get_root_node()
objects = await root.get_child(
[ua.QualifiedName("Objects", 0)]
)
node = await objects.get_child([
ua.QualifiedName(mac_id, namespace),
ua.QualifiedName(
"vibration", namespace
),
ua.QualifiedName("x", namespace),
ua.QualifiedName("accel", namespace),
ua.QualifiedName(
"xAccelTime", namespace
),
])
values = await node.read_raw_history(
starttime=start,
endtime=end,
numvalues=100,
)
return [
(
value.SourceTimestamp,
value.StatusCode,
value.Value.Value.x_abscissa,
value.Value.Value.y_ordinate,
value.Value.Value.axis,
)
for value in values
]| Browse path | Data represented |
|---|---|
| x / accel / xAccelTime | X-axis acceleration versus time. |
| x / accel / xAccelFreq | X-axis acceleration versus frequency. |
| x / veloc / xVelocTime | X-axis velocity versus time. |
| x / veloc / xVelocFreq | X-axis velocity versus frequency. |
Interpret the legacy raw acceleration pack
The earlier accelerationPack node contains the sample count, then the raw sample array, then six trailing metadata values. The public Python extraction uses values[0] for numSamples, values[1:-6] for samples, values[-6] for sampleRate and values[-5] for formatRange.
This layout and scale belong to that legacy pack. The processed vibration structure and newer sensor payloads must be interpreted using their own definitions.
acceleration_g = [sample / 512.0 * formatRange for sample in raw_samples]
time_s = [index / sampleRate for index in range(numSamples)]| Field | Meaning in the original guide |
|---|---|
| numSamples | Number of captured samples. |
| accelArray | Raw samples, indexed from 0 to numSamples - 1. |
| sampleRate | Capture sampling rate in Hz. |
| formatRange | Accelerometer capture range; 4 means ±4 g. |
| offset | Unused hardware-offset field, documented as 0. |
| encoded_axis | X = 0, Y = 1, Z = 2. |
| prescaler | Described as unused except for an uncompressed debug format. |
| compression | Documented debug/compression flag: 0 without compression, 1 with compression. |
Keep processing and timestamps consistent
The old article notes a compression-startup transient in the first seven raw samples. It explains that its Hann-windowed DFT and RMS processing suppresses the transient. That explanation does not mean the transient disappears from an unprocessed time trace.
The later public raw-data script replaces the first six values from later samples before applying its high-pass filters. These are different descriptions of historical processing. Use the processed structure when matching dashboard results, or explicitly validate your own windowing and filtering instead of combining the two recipes.
In the documented wireless workflow, the measurement SourceTimestamp marks the end of the axis download; ServerTimestamp is when the OPC UA server receives the measurement. Historical selection uses SourceTimestamp. Preserve the returned times rather than inventing a common capture-start time for separate axes.