exponenta event banner

Визуализация и предварительная обработка данных OPC UA

В этом примере показано, как работать с объектами OPC UA Data.

Объекты данных OPC UA создаются при чтении исторических данных с сервера OPC UA. Объекты OPC UA Data позволяют сохранять, визуализировать и обрабатывать исторические данные перед преобразованием этих данных в типы данных Builtin для дальнейшей обработки в MATLAB.

Дополнительные сведения о создании объектов OPC UA Data см. в примере Чтение исторических данных сервера OPC UA.

Загрузить образец набора данных OPC UA

Загрузите образцы данных в рабочую область.

load demoUA_SampleData

Просмотр объектов данных OPC UA

Проверьте рабочую область, чтобы узнать, какие переменные были загружены.

whos
  Name            Size            Bytes  Class          Attributes

  dataSample      1x3              5926  opc.ua.Data              

Отображение сводки данных образца.

summary(dataSample)
1-by-3 OPC UA Data object:

     Name        Value            Start Timestamp           End Timestamp            Quality      
    ------  ----------------  -----------------------  -----------------------  ------------------
    Double  9 double values   2015-04-22 09:00:10.000  2015-04-22 09:01:30.000  3 unique qualities
    Float   12 single values  2015-04-22 09:00:02.000  2015-04-22 09:01:30.000  3 unique qualities
    Int32   12 int32 values   2015-04-22 09:00:02.000  2015-04-22 09:01:30.000  3 unique qualities

Объект данных содержит три набора данных. Первый элемент Double содержит 9 значений, второе и третье имеют по 12 значений.

Посмотрите, Float и Int32 наборы данных имеют одинаковую метку времени.

arrayHasSameTimestamp(dataSample(2:3))
ans =

   1

Отображение Float и Int32 наборы данных вместе. Поскольку все элементы имеют одинаковую временную метку, можно отобразить таблицу значений.

dataSample(2:3)
ans = 

1-by-2 OPC UA Data object array:

           Timestamp                      Float                            Int32                
    -----------------------  -------------------------------  --------------------------------  
    2015-04-22 09:00:02.000       10.000000 [Good (Raw)]                    10 [Good (Raw)]       
    2015-04-22 09:00:25.000       20.000000 [Good (Raw)]                    20 [Good (Raw)]       
    2015-04-22 09:00:28.000       25.000000 [Good (Raw)]                    25 [Good (Raw)]       
    2015-04-22 09:00:40.000       30.000000 [Good (Raw)]                    30 [Good (Raw)]       
    2015-04-22 09:00:42.000        0.000000 [Bad (Raw)]                      0 [Bad (Raw)]        
    2015-04-22 09:00:48.000        4.000000 [Good (Raw)]                    40 [Good (Raw)]       
    2015-04-22 09:00:52.000       50.000000 [Good (Raw)]                    50 [Good (Raw)]       
    2015-04-22 09:01:12.000       60.000000 [Good (Raw)]                    60 [Good (Raw)]       
    2015-04-22 09:01:17.000       70.000000 [Uncertain (Raw)]               70 [Uncertain (Raw)]  
    2015-04-22 09:01:23.000       70.000000 [Good (Raw)]                    70 [Good (Raw)]       
    2015-04-22 09:01:26.000       80.000000 [Good (Raw)]                    80 [Good (Raw)]       
    2015-04-22 09:01:30.000       90.000000 [Good (Raw)]                    90 [Good (Raw)]       

Изменение формата отображения даты

Получение текущего формата отображения даты с помощью opc.getDateDisplayFormat.

origFormat = opc.getDateDisplayFormat;

Измените формат отображения на стандартный формат даты в США и снова отобразите значение.

opc.setDateDisplayFormat('mm/dd/yyyy HH:MM AM');
dataSample(2:3)
ans = 

1-by-2 OPC UA Data object array:

         Timestamp                    Float                            Int32                
    -------------------  -------------------------------  --------------------------------  
    04/22/2015  9:00 AM       10.000000 [Good (Raw)]                    10 [Good (Raw)]       
    04/22/2015  9:00 AM       20.000000 [Good (Raw)]                    20 [Good (Raw)]       
    04/22/2015  9:00 AM       25.000000 [Good (Raw)]                    25 [Good (Raw)]       
    04/22/2015  9:00 AM       30.000000 [Good (Raw)]                    30 [Good (Raw)]       
    04/22/2015  9:00 AM        0.000000 [Bad (Raw)]                      0 [Bad (Raw)]        
    04/22/2015  9:00 AM        4.000000 [Good (Raw)]                    40 [Good (Raw)]       
    04/22/2015  9:00 AM       50.000000 [Good (Raw)]                    50 [Good (Raw)]       
    04/22/2015  9:01 AM       60.000000 [Good (Raw)]                    60 [Good (Raw)]       
    04/22/2015  9:01 AM       70.000000 [Uncertain (Raw)]               70 [Uncertain (Raw)]  
    04/22/2015  9:01 AM       70.000000 [Good (Raw)]                    70 [Good (Raw)]       
    04/22/2015  9:01 AM       80.000000 [Good (Raw)]                    80 [Good (Raw)]       
    04/22/2015  9:01 AM       90.000000 [Good (Raw)]                    90 [Good (Raw)]       

Восстановите формат отображения по умолчанию.

opc.setDateDisplayFormat('default')
ans =

yyyy-mm-dd HH:MM:SS.FFF

Сбросьте формат отображения до исходного значения.

opc.setDateDisplayFormat(origFormat);

Визуализация данных OPC UA

Визуализация данных OPC UA с помощью plot или stairs методы для объекта данных.

axH1 = subplot(2,1,1);
plot(dataSample);
title('Plot of sample data');
axH2 = subplot(2,1,2);
stairs(dataSample);
title('Stairstep plot of sample data');
legend('Location', 'NorthWest')

Повторная выборка данных OPC UA

Данные в dataSample набор имеет различные метки времени.

arrayHasSameTimestamp(dataSample)
ans =

   0

Попытка преобразовать данные в двойной массив. Преобразование завершится ошибкой.

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

Пересечение временных меток данных приводит к уменьшению набора данных, содержащего общие временные метки из всех элементов.

dataIntersect = tsintersect(dataSample)
dataIntersect = 

1-by-3 OPC UA Data object array:

           Timestamp                   Double                      Float                        Int32             
    -----------------------  --------------------------  --------------------------  ---------------------------  
    2015-04-22 09:00:40.000       40.000000 [Bad (Raw)]        30.000000 [Good (Raw)]               30 [Good (Raw)]  
    2015-04-22 09:01:30.000       90.000000 [Good (Raw)]       90.000000 [Good (Raw)]               90 [Good (Raw)]  

Преобразование объекта данных в двойной массив.

vals = double(dataIntersect)
vals =

    40    30    30
    90    90    90

Использовать tsunion возвращает объединение временных рядов в объекте Data. Новые значения интерполируются с использованием предоставленного метода (или линейной интерполяции, если метод не предоставлен). Для этих новых значений устанавливается качество «Интерполировано».

dataUnion = tsunion(dataSample)
dataUnion = 

1-by-3 OPC UA Data object array:

           Timestamp                               Double                                       Float                                Int32                  
    -----------------------  --------------------------------------------------  -----------------------------------  ------------------------------------  
    2015-04-22 03:00:02.000        2.000000 [Uncertain:Subnormal (Interpolated)]       10.000000 [Good (Raw)]                        10 [Good (Raw)]           
    2015-04-22 03:00:10.000       10.000000 [Good (Raw)]                               13.478261 [Good (Interpolated)]               13 [Good (Interpolated)]  
    2015-04-22 03:00:20.000       20.000000 [Good (Raw)]                               17.826086 [Good (Interpolated)]               18 [Good (Interpolated)]  
    2015-04-22 03:00:25.000       25.000000 [Good (Interpolated)]                      20.000000 [Good (Raw)]                        20 [Good (Raw)]           
    2015-04-22 03:00:28.000       28.000000 [Good (Interpolated)]                      25.000000 [Good (Raw)]                        25 [Good (Raw)]           
    2015-04-22 03:00:30.000       30.000000 [Good (Raw)]                               25.833334 [Good (Interpolated)]               26 [Good (Interpolated)]  
    2015-04-22 03:00:40.000       40.000000 [Bad (Raw)]                                30.000000 [Good (Raw)]                        30 [Good (Raw)]           
    2015-04-22 03:00:42.000       42.000000 [Good (Interpolated)]                       0.000000 [Bad (Raw)]                          0 [Bad (Raw)]            
    2015-04-22 03:00:48.000       48.000000 [Good (Interpolated)]                       4.000000 [Good (Raw)]                        40 [Good (Raw)]           
    2015-04-22 03:00:50.000       50.000000 [Good (Raw)]                               27.000000 [Good (Interpolated)]               45 [Good (Interpolated)]  
    2015-04-22 03:00:52.000       52.000000 [Good (Interpolated)]                      50.000000 [Good (Raw)]                        50 [Good (Raw)]           
    2015-04-22 03:01:00.000       60.000000 [Good (Raw)]                               54.000000 [Good (Interpolated)]               54 [Good (Interpolated)]  
    2015-04-22 03:01:10.000       70.000000 [Uncertain (Raw)]                          59.000000 [Good (Interpolated)]               59 [Good (Interpolated)]  
    2015-04-22 03:01:12.000       72.000000 [Good (Interpolated)]                      60.000000 [Good (Raw)]                        60 [Good (Raw)]           
    2015-04-22 03:01:17.000       77.000000 [Good (Interpolated)]                      70.000000 [Uncertain (Raw)]                   70 [Uncertain (Raw)]      
    2015-04-22 03:01:20.000       80.000000 [Good (Raw)]                               70.000000 [Good (Interpolated)]               70 [Good (Interpolated)]  
    2015-04-22 03:01:23.000       83.000000 [Good (Interpolated)]                      70.000000 [Good (Raw)]                        70 [Good (Raw)]           
    2015-04-22 03:01:26.000       86.000000 [Good (Interpolated)]                      80.000000 [Good (Raw)]                        80 [Good (Raw)]           
    2015-04-22 03:01:30.000       90.000000 [Good (Raw)]                               90.000000 [Good (Raw)]                        90 [Good (Raw)]           

Постройте график данных с маркерами, чтобы показать, как работают методы.

subplot(2,1,1);
plot(dataSample, 'Marker','.');
hold all
plot(dataIntersect, 'Marker','o', 'LineStyle','none');
title('Intersection of time series in Data object');
subplot(2,1,2);
plot(dataSample, 'Marker','.');
hold all
plot(dataUnion, 'Marker','o', 'LineStyle','--');
title('Union of time series in Data object');

Выполните повторную выборку небольшого набора данных на указанных шагах времени.

newTS = dataSample(1).Timestamp(1):seconds(5):dataSample(1).Timestamp(end);
dataResampled = resample(dataSample,newTS)
figure;
plot(dataSample);
hold all
plot(dataResampled, 'Marker','x', 'Linestyle','none');
dataResampled = 

1-by-3 OPC UA Data object array:

           Timestamp                       Double                                Float                                Int32                  
    -----------------------  -----------------------------------  -----------------------------------  ------------------------------------  
    2015-04-22 03:00:10.000       10.000000 [Good (Raw)]                13.478261 [Good (Interpolated)]               13 [Good (Interpolated)]  
    2015-04-22 03:00:15.000       15.000000 [Good (Interpolated)]       15.652174 [Good (Interpolated)]               16 [Good (Interpolated)]  
    2015-04-22 03:00:20.000       20.000000 [Good (Raw)]                17.826086 [Good (Interpolated)]               18 [Good (Interpolated)]  
    2015-04-22 03:00:25.000       25.000000 [Good (Interpolated)]       20.000000 [Good (Raw)]                        20 [Good (Raw)]           
    2015-04-22 03:00:30.000       30.000000 [Good (Raw)]                25.833334 [Good (Interpolated)]               26 [Good (Interpolated)]  
    2015-04-22 03:00:35.000       35.000000 [Good (Interpolated)]       27.916666 [Good (Interpolated)]               28 [Good (Interpolated)]  
    2015-04-22 03:00:40.000       40.000000 [Bad (Raw)]                 30.000000 [Good (Raw)]                        30 [Good (Raw)]           
    2015-04-22 03:00:45.000       45.000000 [Good (Interpolated)]        2.000000 [Good (Interpolated)]               20 [Good (Interpolated)]  
    2015-04-22 03:00:50.000       50.000000 [Good (Raw)]                27.000000 [Good (Interpolated)]               45 [Good (Interpolated)]  
    2015-04-22 03:00:55.000       55.000000 [Good (Interpolated)]       51.500000 [Good (Interpolated)]               52 [Good (Interpolated)]  
    2015-04-22 03:01:00.000       60.000000 [Good (Raw)]                54.000000 [Good (Interpolated)]               54 [Good (Interpolated)]  
    2015-04-22 03:01:05.000       65.000000 [Good (Interpolated)]       56.500000 [Good (Interpolated)]               57 [Good (Interpolated)]  
    2015-04-22 03:01:10.000       70.000000 [Uncertain (Raw)]           59.000000 [Good (Interpolated)]               59 [Good (Interpolated)]  
    2015-04-22 03:01:15.000       75.000000 [Good (Interpolated)]       66.000000 [Good (Interpolated)]               66 [Good (Interpolated)]  
    2015-04-22 03:01:20.000       80.000000 [Good (Raw)]                70.000000 [Good (Interpolated)]               70 [Good (Interpolated)]  
    2015-04-22 03:01:25.000       85.000000 [Good (Interpolated)]       76.666664 [Good (Interpolated)]               77 [Good (Interpolated)]  
    2015-04-22 03:01:30.000       90.000000 [Good (Raw)]                90.000000 [Good (Raw)]                        90 [Good (Raw)]           

Фильтрация данных по качеству

Найти только хорошие данные из второго элемента повторно отобранного набора данных

resampledGood = filterByQuality(dataResampled(2), 'good')
resampledGood = 

1-by-1 OPC UA Data object array:

           Timestamp                        Float                 
    -----------------------  -----------------------------------  
    2015-04-22 03:00:10.000       13.478261 [Good (Interpolated)]  
    2015-04-22 03:00:15.000       15.652174 [Good (Interpolated)]  
    2015-04-22 03:00:20.000       17.826086 [Good (Interpolated)]  
    2015-04-22 03:00:25.000       20.000000 [Good (Raw)]           
    2015-04-22 03:00:30.000       25.833334 [Good (Interpolated)]  
    2015-04-22 03:00:35.000       27.916666 [Good (Interpolated)]  
    2015-04-22 03:00:40.000       30.000000 [Good (Raw)]           
    2015-04-22 03:00:45.000        2.000000 [Good (Interpolated)]  
    2015-04-22 03:00:50.000       27.000000 [Good (Interpolated)]  
    2015-04-22 03:00:55.000       51.500000 [Good (Interpolated)]  
    2015-04-22 03:01:00.000       54.000000 [Good (Interpolated)]  
    2015-04-22 03:01:05.000       56.500000 [Good (Interpolated)]  
    2015-04-22 03:01:10.000       59.000000 [Good (Interpolated)]  
    2015-04-22 03:01:15.000       66.000000 [Good (Interpolated)]  
    2015-04-22 03:01:20.000       70.000000 [Good (Interpolated)]  
    2015-04-22 03:01:25.000       76.666664 [Good (Interpolated)]  
    2015-04-22 03:01:30.000       90.000000 [Good (Raw)]           

Фильтрация второго элемента повторно дискретизированных данных для возврата только интерполированных данных. Визуализация отфильтрованных данных с оригиналом.

resampledInterpolated = filterByQuality(dataResampled(2), 'Origin','interpolated')

figure;
plot(dataResampled(2))
hold on
plot(resampledGood, 'Marker', '+', 'Linestyle','none', 'DisplayName', 'Good');
plot(resampledInterpolated, 'Marker','x', 'Linestyle','none', 'DisplayName', 'Interpolated');
legend('Location', 'NorthWest')
resampledInterpolated = 

1-by-1 OPC UA Data object array:

           Timestamp                        Float                 
    -----------------------  -----------------------------------  
    2015-04-22 03:00:10.000       13.478261 [Good (Interpolated)]  
    2015-04-22 03:00:15.000       15.652174 [Good (Interpolated)]  
    2015-04-22 03:00:20.000       17.826086 [Good (Interpolated)]  
    2015-04-22 03:00:30.000       25.833334 [Good (Interpolated)]  
    2015-04-22 03:00:35.000       27.916666 [Good (Interpolated)]  
    2015-04-22 03:00:45.000        2.000000 [Good (Interpolated)]  
    2015-04-22 03:00:50.000       27.000000 [Good (Interpolated)]  
    2015-04-22 03:00:55.000       51.500000 [Good (Interpolated)]  
    2015-04-22 03:01:00.000       54.000000 [Good (Interpolated)]  
    2015-04-22 03:01:05.000       56.500000 [Good (Interpolated)]  
    2015-04-22 03:01:10.000       59.000000 [Good (Interpolated)]  
    2015-04-22 03:01:15.000       66.000000 [Good (Interpolated)]  
    2015-04-22 03:01:20.000       70.000000 [Good (Interpolated)]  
    2015-04-22 03:01:25.000       76.666664 [Good (Interpolated)]