Main Content

Visualize and Preprocess OPC HDA Data

This example shows you how to work with OPC HDA Data objects.

You create OPC HDA Data objects when you read data from an OPC Historical Data Access (HDA) server. OPC HDA Data objects allow you to store, visualize, and manipulate historical data before converting that data to built-in data types for further processing in MATLAB.

For more information on generating OPC HDA Data objects, see the example Acquire Data from an OPC Historical Data Access Server.

Load Sample OPC HDA Data

Load the sample data into the workspace.

load opcdemoHDAData

Display OPC HDA Data Objects

Examine the workspace to see the loaded variables.

whos
  Name              Size            Bytes  Class           Attributes

  hdaDataSmall      1x2               252  opc.hda.Data              
  hdaDataVis        1x2              8984  opc.hda.Data              

Display a summary of the data contained in hdaDataVis.

hdaDataVis
hdaDataVis = 

1-by-2 OPC HDA Data object:

        ItemID            Value          Start TimeStamp       End TimeStamp            Quality        
    --------------  -----------------  -------------------  -------------------  ----------------------
    Example.Item.1  361 double values  2010-05-12 08:15:00  2010-05-12 09:15:00  1 unique quality [Raw]
    Example.Item.2  11 double values   2010-05-12 08:30:00  2010-05-12 09:30:00  2 unique qualities

The data object contains two items. The first element Example.Item.1 contains 361 values and one unique quality, while the second has 11 values and two unique qualities.

Examine the second element in more detail using the showValues function.

opc.setDateDisplayFormat('yyyy-mm-dd HH:MM:SS');
showValues(hdaDataVis(2))
OPC HDA Data object for item Example.Item.2:

         TIMESTAMP           VALUE           QUALITY
    ===================  =============  =================
    2010-05-12 08:30:00      -0.500000  Raw (Good)       
    2010-05-12 08:36:00      -0.250000  Raw (Good)       
    2010-05-12 08:42:00       0.000000  Raw (Good)       
    2010-05-12 08:48:00       0.250000  Raw (Good)       
    2010-05-12 08:54:00       0.500000  Calculated (Good)
    2010-05-12 09:00:00       0.500000  Calculated (Good)
    2010-05-12 09:06:00       0.400000  Calculated (Good)
    2010-05-12 09:12:00       0.300000  Raw (Good)       
    2010-05-12 09:18:00       0.200000  Raw (Good)       
    2010-05-12 09:24:00       0.100000  Raw (Good)       
    2010-05-12 09:30:00       0.000000  Raw (Good)       

Change the Date Display Format

Get the current date display format using opc.getDateDisplayFormat.

origFormat = opc.getDateDisplayFormat;

Change the display format to standard US date format and display the value again.

opc.setDateDisplayFormat('mm/dd/yyyy HH:MM am');
showValues(hdaDataVis(2))
OPC HDA Data object for item Example.Item.2:

          TIMESTAMP            VALUE           QUALITY
    =====================  =============  =================
    05/12/2010  8:30 AM        -0.500000  Raw (Good)       
    05/12/2010  8:36 AM        -0.250000  Raw (Good)       
    05/12/2010  8:42 AM         0.000000  Raw (Good)       
    05/12/2010  8:48 AM         0.250000  Raw (Good)       
    05/12/2010  8:54 AM         0.500000  Calculated (Good)
    05/12/2010  9:00 AM         0.500000  Calculated (Good)
    05/12/2010  9:06 AM         0.400000  Calculated (Good)
    05/12/2010  9:12 AM         0.300000  Raw (Good)       
    05/12/2010  9:18 AM         0.200000  Raw (Good)       
    05/12/2010  9:24 AM         0.100000  Raw (Good)       
    05/12/2010  9:30 AM         0.000000  Raw (Good)       

Reset the display format to the original value.

opc.setDateDisplayFormat(origFormat);

Visualize OPC HDA Data

Visualize OPC HDA Data using the plot and stairs functions on the data object.

axH1 = subplot(2,1,1);
plot(hdaDataVis);
title('Plot of hdaDataVis data');
axH2 = subplot(2,1,2);
stairs(hdaDataVis);
title('Stairstep plot of hdaDataVis data');
legend show

Resample OPC HDA Data

Examine a small data set. This data set is intentionally small to show the concept of resampling.

hdaDataSmall
hdaDataSmall = 

1-by-2 OPC HDA Data object:

        ItemID            Value         Start TimeStamp       End TimeStamp            Quality        
    ---------------  ---------------  -------------------  -------------------  ----------------------
    Example.ItemR.1  5 double values  2010-06-01 09:30:00  2010-06-01 09:31:00  1 unique quality [Raw]
    Example.ItemR.2  3 double values  2010-06-01 09:30:00  2010-06-01 09:31:00  1 unique quality [Raw]

Display the data from each item individually. You cannot display the items in one table because their time stamps are not the same.

showValues(hdaDataSmall(1))
showValues(hdaDataSmall(2))
OPC HDA Data object for item Example.ItemR.1:

         TIMESTAMP           VALUE       QUALITY
    ===================  =============  ==========
    2010-06-01 09:30:00       0.000000  Raw (Good)
    2010-06-01 09:30:15       1.000000  Raw (Good)
    2010-06-01 09:30:30       2.000000  Raw (Good)
    2010-06-01 09:30:45       1.000000  Raw (Good)
    2010-06-01 09:31:00       0.000000  Raw (Good)


OPC HDA Data object for item Example.ItemR.2:

         TIMESTAMP           VALUE       QUALITY
    ===================  =============  ==========
    2010-06-01 09:30:00       1.000000  Raw (Good)
    2010-06-01 09:30:30       2.000000  Raw (Good)
    2010-06-01 09:31:00       3.000000  Raw (Good)

Attempt to convert the data to a double array. The conversion will fail.

try
    vals = double(hdaDataSmall);
catch exc
    disp(exc.message)
end
Conversion to double failed. All elements of the OPC HDA Data object must have the same time stamp.
Consider using 'TSUNION' or 'RESAMPLE' on the Data object.

The intersection of the items' time stamps results in a smaller, regularly sampled data set.

hdaDataIntersect = hdaDataSmall.tsintersect
hdaDataIntersect = 

1-by-2 OPC HDA Data object:

        ItemID            Value         Start TimeStamp       End TimeStamp            Quality        
    ---------------  ---------------  -------------------  -------------------  ----------------------
    Example.ItemR.1  3 double values  2010-06-01 09:30:00  2010-06-01 09:31:00  1 unique quality [Raw]
    Example.ItemR.2  3 double values  2010-06-01 09:30:00  2010-06-01 09:31:00  1 unique quality [Raw]

Use the showValues method to display all values.

Show these values together. You can do this because the time stamps are now regularly sampled.

showValues(hdaDataIntersect)
OPC HDA Data object array:

              TIMESTAMP  Example.ItemR.1  Example.ItemR.2  
    ===================  ===============  ===============  
    2010-06-01 09:30:00         0.000000         1.000000  
    2010-06-01 09:30:30         2.000000         2.000000  
    2010-06-01 09:31:00         0.000000         3.000000  

Convert the data object into a double array.

vals = double(hdaDataIntersect)
vals =

     0     1
     2     2
     0     3

Use tsunion to return the union of time series in a Data object. New values are interpolated using the method supplied (or linear interpolation if no method is supplied).

hdaDataUnion = hdaDataSmall.tsunion
showValues(hdaDataUnion)
hdaDataUnion = 

1-by-2 OPC HDA Data object:

        ItemID            Value         Start TimeStamp       End TimeStamp            Quality        
    ---------------  ---------------  -------------------  -------------------  ----------------------
    Example.ItemR.1  5 double values  2010-06-01 09:30:00  2010-06-01 09:31:00  1 unique quality [Raw]
    Example.ItemR.2  5 double values  2010-06-01 09:30:00  2010-06-01 09:31:00  2 unique qualities

Use the showValues method to display all values.

OPC HDA Data object array:

              TIMESTAMP  Example.ItemR.1  Example.ItemR.2  
    ===================  ===============  ===============  
    2010-06-01 09:30:00         0.000000         1.000000  
    2010-06-01 09:30:15         1.000000         1.500000  
    2010-06-01 09:30:30         2.000000         2.000000  
    2010-06-01 09:30:45         1.000000         2.500000  
    2010-06-01 09:31:00         0.000000         3.000000  

Note how the quality is set to "Interpolated" for those new values in Example.ItemR.2.

showValues(hdaDataUnion(2))
OPC HDA Data object for item Example.ItemR.2:

         TIMESTAMP           VALUE            QUALITY
    ===================  =============  ===================
    2010-06-01 09:30:00       1.000000  Raw (Good)         
    2010-06-01 09:30:15       1.500000  Interpolated (Good)
    2010-06-01 09:30:30       2.000000  Raw (Good)         
    2010-06-01 09:30:45       2.500000  Interpolated (Good)
    2010-06-01 09:31:00       3.000000  Raw (Good)         

Plot the data with markers to show how the methods work.

subplot(2,1,1);
plot(hdaDataSmall,'Marker','.');
hold all
plot(hdaDataIntersect,'Marker','o','LineStyle','none');
title('Intersection of time series in Data object');
subplot(2,1,2);
plot(hdaDataSmall,'Marker','.');
hold all
plot(hdaDataUnion,'Marker','o','LineStyle','none');
title('Union of time series in Data object');

Resample the small data set at specified time steps.

newTS = datenum(2010,6,1,9,30,[0:60]);
hdaDataResampled = resample(hdaDataSmall,newTS)
figure;
plot(hdaDataSmall);
hold all
stairs(hdaDataResampled);
hdaDataResampled = 

1-by-2 OPC HDA Data object:

        ItemID            Value          Start TimeStamp       End TimeStamp          Quality      
    ---------------  ----------------  -------------------  -------------------  ------------------
    Example.ItemR.1  61 double values  2010-06-01 09:30:00  2010-06-01 09:31:00  2 unique qualities
    Example.ItemR.2  61 double values  2010-06-01 09:30:00  2010-06-01 09:31:00  2 unique qualities

Use the showValues method to display all values.