Read Historical OPC UA Server Data
This example shows you how to read historical data from an OPC UA server.
This example reads data from a Prosys OPC UA Simulation Server v4.0.2. For other Prosys server versions, you might have to modify this code.
To run this example in your MATLAB® session, you must install and start the Prosys OPC UA Simulation Server. For further information, see the Getting Started section of the Industrial Communication Toolbox™ documentation.
Create a Client and Connect to the Server
You create client objects using the results of a query to the Local Discovery Service using opcuaserverinfo
, or directly using the host name and port number of the server you are connecting to. In this case, connect directly to the OPC UA server on port 53530.
uaClient = opcua('localhost',53530);
connect(uaClient);
uaClient.Status
ans = 'Connected'
Define Nodes to Read Historical Data
The Prosys OPC UA Simulation Server provides simulated signals for nodes in the "Simulation" branch. By default the Simulation Server updates the values each second. Define these nodes using the opcuanode
function.
simNodeIds = {'Random'; 'Triangle'; 'Sinusoid'}; simNodes = opcuanode(3,simNodeIds,uaClient)
simNodes = 1×3 OPC UA Node array: index Name NsInd Identifier NodeType ----- -------- ----- ---------- -------- 1 Random 3 Random Variable 2 Triangle 3 Triangle Variable 3 Sinusoid 3 Sinusoid Variable
Read Historical Data from Nodes
Use the readHistory
function to read the history of a node. You must pass a time range in which to read historical data. For the Prosys server, read the most recent 30 seconds of data.
dataSample = readHistory(uaClient,simNodes,datetime('now')-seconds(30),datetime('now'))
dataSample = 1-by-3 OPC UA Data object array: Timestamp Random Triangle Sinusoid ----------------------- -------------------------- -------------------------- -------------------------- 2019-12-20 01:18:14.000 1.402465 [Good (Raw)] 0.266667 [Good (Raw)] 0.415823 [Good (Raw)] 2019-12-20 01:18:15.000 1.044139 [Good (Raw)] 0.000000 [Good (Raw)] 0.000000 [Good (Raw)] 2019-12-20 01:18:16.000 -1.857952 [Good (Raw)] -0.266667 [Good (Raw)] -0.415823 [Good (Raw)] 2019-12-20 01:18:17.000 1.783723 [Good (Raw)] -0.533333 [Good (Raw)] -0.813473 [Good (Raw)] 2019-12-20 01:18:18.000 -1.095435 [Good (Raw)] -0.800000 [Good (Raw)] -1.175570 [Good (Raw)] 2019-12-20 01:18:19.000 -1.178567 [Good (Raw)] -1.066667 [Good (Raw)] -1.486290 [Good (Raw)] 2019-12-20 01:18:20.000 -1.548359 [Good (Raw)] -1.333333 [Good (Raw)] -1.732051 [Good (Raw)] 2019-12-20 01:18:21.000 -0.438983 [Good (Raw)] -1.600000 [Good (Raw)] -1.902113 [Good (Raw)] 2019-12-20 01:18:22.000 -0.785842 [Good (Raw)] -1.866667 [Good (Raw)] -1.989044 [Good (Raw)] 2019-12-20 01:18:23.000 1.419149 [Good (Raw)] -1.866667 [Good (Raw)] -1.989044 [Good (Raw)] 2019-12-20 01:18:24.000 1.049357 [Good (Raw)] -1.600000 [Good (Raw)] -1.902113 [Good (Raw)] 2019-12-20 01:18:25.000 -1.932999 [Good (Raw)] -1.333333 [Good (Raw)] -1.732051 [Good (Raw)] 2019-12-20 01:18:26.000 1.720142 [Good (Raw)] -1.066667 [Good (Raw)] -1.486290 [Good (Raw)] 2019-12-20 01:18:27.000 -1.170482 [Good (Raw)] -0.800000 [Good (Raw)] -1.175571 [Good (Raw)] 2019-12-20 01:18:28.000 -1.540274 [Good (Raw)] -0.533333 [Good (Raw)] -0.813473 [Good (Raw)] 2019-12-20 01:18:29.000 -0.430899 [Good (Raw)] -0.266667 [Good (Raw)] -0.415823 [Good (Raw)] 2019-12-20 01:18:30.000 -0.869489 [Good (Raw)] -0.000000 [Good (Raw)] -0.000000 [Good (Raw)] 2019-12-20 01:18:31.000 -1.630916 [Good (Raw)] 0.266667 [Good (Raw)] 0.415823 [Good (Raw)] 2019-12-20 01:18:32.000 1.999292 [Good (Raw)] 0.533333 [Good (Raw)] 0.813473 [Good (Raw)] 2019-12-20 01:18:33.000 -0.891333 [Good (Raw)] 0.800000 [Good (Raw)] 1.175570 [Good (Raw)] 2019-12-20 01:18:34.000 -1.238192 [Good (Raw)] 1.066667 [Good (Raw)] 1.486290 [Good (Raw)] 2019-12-20 01:18:35.000 -0.220548 [Good (Raw)] 1.333333 [Good (Raw)] 1.732051 [Good (Raw)] 2019-12-20 01:18:36.000 -0.590339 [Good (Raw)] 1.600000 [Good (Raw)] 1.902113 [Good (Raw)] 2019-12-20 01:18:37.000 0.519036 [Good (Raw)] 1.866667 [Good (Raw)] 1.989044 [Good (Raw)] 2019-12-20 01:18:38.000 0.172177 [Good (Raw)] 1.866667 [Good (Raw)] 1.989044 [Good (Raw)] 2019-12-20 01:18:39.000 -0.589250 [Good (Raw)] 1.600000 [Good (Raw)] 1.902113 [Good (Raw)] 2019-12-20 01:18:40.000 -0.959042 [Good (Raw)] 1.333333 [Good (Raw)] 1.732051 [Good (Raw)] 2019-12-20 01:18:41.000 0.425527 [Good (Raw)] 1.066667 [Good (Raw)] 1.486290 [Good (Raw)] 2019-12-20 01:18:42.000 0.078668 [Good (Raw)] 0.800000 [Good (Raw)] 1.175571 [Good (Raw)] 2019-12-20 01:18:43.000 1.188043 [Good (Raw)] 0.533333 [Good (Raw)] 0.813473 [Good (Raw)]
Read Historical Data at Specific Times
You can ask the server to retrieve data at specific times. If the server does not have an archived value for that specific time, an interpolated (or extrapolated) value is returned. Use the readAtTime
function to retrieve data each minute for the last 10 minutes.
timesToReturn = datetime('now')-minutes(10):minutes(1):datetime('now'); dataRegular = readAtTime(uaClient,simNodes,timesToReturn)
dataRegular = 1-by-3 OPC UA Data object array: Timestamp Random Triangle Sinusoid ----------------------- -------------------------- -------------------------- -------------------------- 2019-12-20 01:08:44.000 -0.083361 [Good (Raw)] 0.266667 [Good (Raw)] 0.415823 [Good (Raw)] 2019-12-20 01:09:44.000 0.043744 [Good (Raw)] 0.266667 [Good (Raw)] 0.415823 [Good (Raw)] 2019-12-20 01:10:44.000 1.199272 [Good (Raw)] 0.266667 [Good (Raw)] 0.415823 [Good (Raw)] 2019-12-20 01:11:44.000 1.259184 [Good (Raw)] 0.266667 [Good (Raw)] 0.415823 [Good (Raw)] 2019-12-20 01:12:44.000 0.193783 [Good (Raw)] 0.266667 [Good (Raw)] 0.415823 [Good (Raw)] 2019-12-20 01:13:44.000 -1.585967 [Good (Raw)] 0.266667 [Good (Raw)] 0.415823 [Good (Raw)] 2019-12-20 01:14:44.000 1.073438 [Good (Raw)] 0.266667 [Good (Raw)] 0.415823 [Good (Raw)] 2019-12-20 01:15:44.000 0.099768 [Good (Raw)] 0.266667 [Good (Raw)] 0.415823 [Good (Raw)] 2019-12-20 01:16:44.000 -1.368735 [Good (Raw)] 0.266667 [Good (Raw)] 0.415823 [Good (Raw)] 2019-12-20 01:17:44.000 1.791922 [Good (Raw)] 0.266667 [Good (Raw)] 0.415823 [Good (Raw)] 2019-12-20 01:18:44.000 0.818252 [Good (Raw)] 0.266667 [Good (Raw)] 0.415823 [Good (Raw)]
Read Processed Data from the Server
OPC UA Servers provide aggregate functions for returning preprocessed data to clients. This is most useful when you need to query data over a large period of time.
Query the AggregateFunctions
property of a connected client to find out what aggregate functions the server supports.
uaClient.AggregateFunctions
ans = 14×1 cell array {'Interpolative' } {'Average' } {'Minimum' } {'Maximum' } {'MinimumActualTime'} {'MaximumActualTime'} {'Range' } {'Count' } {'Start' } {'End' } {'Delta' } {'WorstQuality' } {'StartBound' } {'EndBound' }
Read the Average value for each 30 second period over the last 10 minutes.
dataAverage = readProcessed(uaClient,simNodes,'Average',seconds(30),datetime('now')-minutes(10),datetime('now'))
dataAverage = 1-by-3 OPC UA Data object array: Timestamp Random Triangle Sinusoid ----------------------- --------------------------------- --------------------------------- --------------------------------- 2019-12-20 01:08:44.000 -0.008396 [Good (Calculated)] -0.000000 [Good (Calculated)] 0.000000 [Good (Calculated)] 2019-12-20 01:09:14.000 0.071422 [Good (Calculated)] -0.000000 [Good (Calculated)] -0.000000 [Good (Calculated)] 2019-12-20 01:09:44.000 0.034084 [Good (Calculated)] -0.000000 [Good (Calculated)] -0.000000 [Good (Calculated)] 2019-12-20 01:10:14.000 0.190256 [Good (Calculated)] -0.000000 [Good (Calculated)] 0.000000 [Good (Calculated)] 2019-12-20 01:10:44.000 0.088148 [Good (Calculated)] -0.000000 [Good (Calculated)] -0.000000 [Good (Calculated)] 2019-12-20 01:11:14.000 0.065122 [Good (Calculated)] 0.000000 [Good (Calculated)] -0.000000 [Good (Calculated)] 2019-12-20 01:11:44.000 -0.057444 [Good (Calculated)] 0.000000 [Good (Calculated)] 0.000000 [Good (Calculated)] 2019-12-20 01:12:14.000 -0.047782 [Good (Calculated)] 0.000000 [Good (Calculated)] -0.000000 [Good (Calculated)] 2019-12-20 01:12:44.000 0.253328 [Good (Calculated)] 0.000000 [Good (Calculated)] -0.000000 [Good (Calculated)] 2019-12-20 01:13:14.000 -0.018746 [Good (Calculated)] 0.000000 [Good (Calculated)] 0.000000 [Good (Calculated)] 2019-12-20 01:13:44.000 0.103775 [Good (Calculated)] 0.000000 [Good (Calculated)] -0.000000 [Good (Calculated)] 2019-12-20 01:14:14.000 0.010857 [Good (Calculated)] 0.000000 [Good (Calculated)] -0.000000 [Good (Calculated)] 2019-12-20 01:14:44.000 -0.370672 [Good (Calculated)] 0.000000 [Good (Calculated)] 0.000000 [Good (Calculated)] 2019-12-20 01:15:14.000 -0.198687 [Good (Calculated)] -0.000000 [Good (Calculated)] -0.000000 [Good (Calculated)] 2019-12-20 01:15:44.000 -0.025481 [Good (Calculated)] -0.000000 [Good (Calculated)] -0.000000 [Good (Calculated)] 2019-12-20 01:16:14.000 0.067565 [Good (Calculated)] -0.000000 [Good (Calculated)] 0.000000 [Good (Calculated)] 2019-12-20 01:16:44.000 0.085904 [Good (Calculated)] -0.000000 [Good (Calculated)] -0.000000 [Good (Calculated)] 2019-12-20 01:17:14.000 0.018061 [Good (Calculated)] -0.000000 [Good (Calculated)] -0.000000 [Good (Calculated)] 2019-12-20 01:17:44.000 -0.033414 [Good (Calculated)] -0.000000 [Good (Calculated)] 0.000000 [Good (Calculated)] 2019-12-20 01:18:14.000 -0.205573 [Good (Calculated)] -0.000000 [Good (Calculated)] -0.000000 [Good (Calculated)]
Read the Average value for each half second period over the last 5 seconds. Note how the quality of the data includes Good quality, and Bad quality where there is no data available to perform the calculation.
dataMixedQuality = readProcessed(uaClient,simNodes,'Average',seconds(0.5),datetime('now')-seconds(5),datetime('now'))
dataMixedQuality = 1-by-3 OPC UA Data object array: Timestamp Random Triangle Sinusoid ----------------------- --------------------------------- --------------------------------- --------------------------------- 2019-12-20 01:18:39.000 0.000000 [Bad:NoData (Raw)] 0.000000 [Bad:NoData (Raw)] 0.000000 [Bad:NoData (Raw)] 2019-12-20 01:18:39.500 -0.589250 [Good (Calculated)] 1.600000 [Good (Calculated)] 1.902113 [Good (Calculated)] 2019-12-20 01:18:40.000 0.000000 [Bad:NoData (Raw)] 0.000000 [Bad:NoData (Raw)] 0.000000 [Bad:NoData (Raw)] 2019-12-20 01:18:40.500 -0.959042 [Good (Calculated)] 1.333333 [Good (Calculated)] 1.732051 [Good (Calculated)] 2019-12-20 01:18:41.000 0.000000 [Bad:NoData (Raw)] 0.000000 [Bad:NoData (Raw)] 0.000000 [Bad:NoData (Raw)] 2019-12-20 01:18:41.500 0.425527 [Good (Calculated)] 1.066667 [Good (Calculated)] 1.486290 [Good (Calculated)] 2019-12-20 01:18:42.000 0.000000 [Bad:NoData (Raw)] 0.000000 [Bad:NoData (Raw)] 0.000000 [Bad:NoData (Raw)] 2019-12-20 01:18:42.500 0.078668 [Good (Calculated)] 0.800000 [Good (Calculated)] 1.175571 [Good (Calculated)] 2019-12-20 01:18:43.000 0.000000 [Bad:NoData (Raw)] 0.000000 [Bad:NoData (Raw)] 0.000000 [Bad:NoData (Raw)] 2019-12-20 01:18:43.500 1.188043 [Good (Calculated)] 0.533333 [Good (Calculated)] 0.813473 [Good (Calculated)]
Filter the quality of the data to return only the Good data.
dataGood = filterByQuality(dataMixedQuality,'good')
dataGood = 1-by-3 OPC UA Data object array: Timestamp Random Triangle Sinusoid ----------------------- --------------------------------- --------------------------------- --------------------------------- 2019-12-20 01:18:39.500 -0.589250 [Good (Calculated)] 1.600000 [Good (Calculated)] 1.902113 [Good (Calculated)] 2019-12-20 01:18:40.500 -0.959042 [Good (Calculated)] 1.333333 [Good (Calculated)] 1.732051 [Good (Calculated)] 2019-12-20 01:18:41.500 0.425527 [Good (Calculated)] 1.066667 [Good (Calculated)] 1.486290 [Good (Calculated)] 2019-12-20 01:18:42.500 0.078668 [Good (Calculated)] 0.800000 [Good (Calculated)] 1.175571 [Good (Calculated)] 2019-12-20 01:18:43.500 1.188043 [Good (Calculated)] 0.533333 [Good (Calculated)] 0.813473 [Good (Calculated)]
Disconnect from Server
When you have finished communicating with the server, disconnect the client from the server. This is also automatically performed when the client variable goes out of scope in MATLAB®.
disconnect(uaClient);