Этот пример показывает вам, как считать исторические данные из сервера UA OPC. А именно, этот пример считывает данные из Быстрого запуска Основы OPC Исторический доступ к Серверу.
ПРЕДПОСЫЛКИ:
Вы создаете объекты клиента с помощью результатов запроса к Локальному Сервису Открытия с помощью opcuaserverinfo, или непосредственно с помощью имени хоста и номера порта сервера, с которым вы соединяетесь. В этом случае найдите сервер с именем, содержащим 'Быстрый запуск Исторический'.
serverList = opcuaserverinfo('localhost'); historicalServer = findDescription(serverList,'Quickstart Historical'); uaClient = opcua(historicalServer); connect(uaClient); uaClient.Status
ans = Connected
Быстрый запуск Исторический доступ к Серверу моделирует некоторые исторические данные для узлов в пространстве имен. Два набора данных обеспечиваются: Выборочные данные, которые являются небольшим набором данных и Динамическими данными, которые отличаются по размеру в зависимости от того, когда сервер был запущен. Задайте эти узлы с помощью функции opcuanode.
sampleNodeIds = {'1:Quickstarts.HistoricalAccessServer.Data.Sample.Double.txt';
'1:Quickstarts.HistoricalAccessServer.Data.Sample.Float.txt';
'1:Quickstarts.HistoricalAccessServer.Data.Sample.Int32.txt'};
sampleNodes = opcuanode(2,sampleNodeIds,uaClient)
dynamicNodeIds = strrep(sampleNodeIds,'Sample','Dynamic');
dynamicNodes = opcuanode(2,dynamicNodeIds,uaClient)
sampleNodes =
1x3 OPC UA Node array:
index Name NsInd Identifier NodeType Children
----- ------ ----- ----------------------------------------------------------- -------- --------
1 Double 2 1:Quickstarts.HistoricalAccessServer.Data.Sample.Double.txt Variable 2
2 Float 2 1:Quickstarts.HistoricalAccessServer.Data.Sample.Float.txt Variable 2
3 Int32 2 1:Quickstarts.HistoricalAccessServer.Data.Sample.Int32.txt Variable 2
dynamicNodes =
1x3 OPC UA Node array:
index Name NsInd Identifier NodeType Children
----- ------ ----- ------------------------------------------------------------ -------- --------
1 Double 2 1:Quickstarts.HistoricalAccessServer.Data.Dynamic.Double.txt Variable 2
2 Float 2 1:Quickstarts.HistoricalAccessServer.Data.Dynamic.Float.txt Variable 2
3 Int32 2 1:Quickstarts.HistoricalAccessServer.Data.Dynamic.Int32.txt Variable 2
Исторический доступ Быстрого запуска к серверу создает моделируемый архив данных с начала часа, что сервер был запущен ко времени начала сервера (для Динамических узлов). Чтобы предоставить спектры соответствующего времени, в которых можно получить данные, запросите сервер в течение времени начала.
Все серверы должны опубликовать узел ServerStatus, который включает информацию о времени начала сервера. Можно считать это значение непосредственно из Сервера OPC, с помощью функции getServerStatus. Вычислите запуск и время окончания истории, сохраненной сервером.
serverStatus = getServerStatus(uaClient) serverStartTime = serverStatus.StartTime; startHistory = dateshift(serverStartTime,'start','hour') endHistory = serverStartTime
serverStatus =
StartTime: 13-Apr-2016 12:06:15
CurrentTime: 13-Apr-2016 12:14:15
State: 'Running'
BuildInfo: [1×1 struct]
SecondsTillShutdown: 0
ShutdownReason: ''
startHistory =
13-Apr-2016 12:00:00
endHistory =
13-Apr-2016 12:06:15
Используйте функцию readHistorical, чтобы считать историю узла. Необходимо передать область значений времени, в которой можно считать исторические данные. Для выборочных данных сервера Быстрого запуска считайте первые 2 минуты данных.
dataSample = readHistory(uaClient,sampleNodes,startHistory,startHistory+minutes(2))
dataSample =
1-by-3 OPC UA Data object:
Name Value Start Timestamp End Timestamp Quality
------ ---------------- ----------------------- ----------------------- ------------------
Double 9 double values 2016-04-13 12:00:10.000 2016-04-13 12:01:30.000 3 unique qualities
Float 12 single values 2016-04-13 12:00:02.000 2016-04-13 12:01:30.000 3 unique qualities
Int32 12 int32 values 2016-04-13 12:00:02.000 2016-04-13 12:01:30.000 3 unique qualities
Можно попросить, чтобы сервер получил данные в конкретные моменты времени. Если сервер не имеет заархивированного значения в течение того определенного времени, интерполированный (или экстраполируемый), значение возвращено. Используйте функцию readAtTime, чтобы получать данные каждые 5 минут в течение двух часов.
timesToReturn = startHistory:minutes(5):endHistory; dataRegular = readAtTime(uaClient,dynamicNodes,timesToReturn)
dataRegular =
1-by-3 OPC UA Data object array:
Timestamp Double Float Int32
----------------------- ----------------------------------- ----------------------------------- ------------------------------------
2016-04-13 12:00:00.000 0.000000 [Good (Interpolated)] 0.000000 [Good (Interpolated)] 10 [Good (Interpolated)]
2016-04-13 12:05:00.000 30.000000 [Good (Raw)] 30.000000 [Good (Raw)] 30 [Good (Raw)]
Серверы UA OPC обеспечивают агрегатные функции для возврата предварительно обработанных данных клиентам. Это является самым полезным, когда необходимо запросить данные за большой промежуток времени.
Запросите свойство AggregateFunctions связанного клиента узнать, какие агрегатные функции сервер поддерживает.
uaClient.AggregateFunctions
ans =
'Interpolative'
'Average'
'TimeAverage'
'Total'
'Minimum'
'Maximum'
'MinimumActualTime'
'MaximumActualTime'
'Range'
'AnnotationCount'
'Count'
'NumberOfTransitions'
'Start'
'End'
'Delta'
'DurationGood'
'DurationBad'
'PercentGood'
'PercentBad'
'WorstQuality'
'TimeAverage2'
'Minimum2'
'Maximum2'
'Range2'
'WorstQuality2'
'Total2'
'MinimumActualTime2'
'MaximumActualTime2'
'DurationInStateZero'
'DurationInStateNonZero'
'StandardDeviationSample'
'StandardDeviationPopulation'
'VarianceSample'
'VariancePopulation'
'StartBound'
'EndBound'
'DeltaBounds'
Считайте Среднее значение в течение каждого 10-секундного периода более чем 2 минуты. Отметьте, как качество данных включает Хорошее качество, Плохое качество (где нет никаких доступных данных, чтобы выполнить вычисление), и Неопределенное качество (где недостаточные данные доступны, чтобы классифицировать его как Хороший).
dataAverage = readProcessed(uaClient,dynamicNodes,'Average',seconds(10),startHistory,startHistory+minutes(2))
dataAverage =
1-by-3 OPC UA Data object array:
Timestamp Double Float Int32
----------------------- ---------------------------------------------------- ---------------------------------------------------- ----------------------------------------------------
2016-04-13 12:00:00.000 NaN [Bad:NoData (Raw)] NaN [Bad:NoData (Raw)] NaN [Bad:NoData (Raw)]
2016-04-13 12:00:10.000 10.000000 [Good (Calculated)] 10.000000 [Good (Calculated)] 10.000000 [Good (Calculated)]
2016-04-13 12:00:20.000 20.000000 [Good (Calculated)] 20.000000 [Good (Calculated)] 20.000000 [Good (Calculated)]
2016-04-13 12:00:30.000 30.000000 [Good (Calculated)] 30.000000 [Good (Calculated)] 30.000000 [Good (Calculated)]
2016-04-13 12:00:40.000 NaN [Bad:NoData (Raw)] NaN [Bad:NoData (Raw)] NaN [Bad:NoData (Raw)]
2016-04-13 12:00:50.000 50.000000 [Good (Calculated)] 50.000000 [Good (Calculated)] 50.000000 [Good (Calculated)]
2016-04-13 12:01:00.000 60.000000 [Good (Calculated)] 60.000000 [Good (Calculated)] 60.000000 [Good (Calculated)]
2016-04-13 12:01:10.000 NaN [Bad:NoData (Raw)] NaN [Bad:NoData (Raw)] NaN [Bad:NoData (Raw)]
2016-04-13 12:01:20.000 80.000000 [Good (Calculated)] 80.000000 [Good (Calculated)] 80.000000 [Good (Calculated)]
2016-04-13 12:01:30.000 53.750000 [Uncertain:DataSubnormal (Calculated)] 53.750000 [Uncertain:DataSubnormal (Calculated)] 53.750000 [Uncertain:DataSubnormal (Calculated)]
2016-04-13 12:01:40.000 43.750000 [Uncertain:DataSubnormal (Calculated)] 43.750000 [Uncertain:DataSubnormal (Calculated)] 43.750000 [Uncertain:DataSubnormal (Calculated)]
2016-04-13 12:01:50.000 45.000000 [Uncertain:DataSubnormal (Calculated)] 45.000000 [Uncertain:DataSubnormal (Calculated)] 45.000000 [Uncertain:DataSubnormal (Calculated)]
Отфильтруйте качество данных, чтобы возвратить только Хорошие данные.
dataGood = filterByQuality(dataAverage,'good')
dataGood =
1-by-3 OPC UA Data object array:
Timestamp Double Float Int32
----------------------- --------------------------------- --------------------------------- ---------------------------------
2016-04-13 12:00:10.000 10.000000 [Good (Calculated)] 10.000000 [Good (Calculated)] 10.000000 [Good (Calculated)]
2016-04-13 12:00:20.000 20.000000 [Good (Calculated)] 20.000000 [Good (Calculated)] 20.000000 [Good (Calculated)]
2016-04-13 12:00:30.000 30.000000 [Good (Calculated)] 30.000000 [Good (Calculated)] 30.000000 [Good (Calculated)]
2016-04-13 12:00:50.000 50.000000 [Good (Calculated)] 50.000000 [Good (Calculated)] 50.000000 [Good (Calculated)]
2016-04-13 12:01:00.000 60.000000 [Good (Calculated)] 60.000000 [Good (Calculated)] 60.000000 [Good (Calculated)]
2016-04-13 12:01:20.000 80.000000 [Good (Calculated)] 80.000000 [Good (Calculated)] 80.000000 [Good (Calculated)]
Когда вы закончите связываться с сервером, отключите клиент от сервера. Это также автоматически выполняется, когда клиентская переменная выходит из осциллографа в MATLAB®.
disconnect(uaClient);