TranslateBrowsePathsToNodeIds() OPC-UA метод с помощью Simatic ProcessHistorian
Я пытаюсь позвонить TranslateBrowsePathsToNodeIds
метод (определенный в View Service Set стандарта OPC-UA) с использованием клиента OPC-UA против Simatic ProcessHistorian (Simatic PCS 7 версия 8.1).
Когда я просматриваю сервер с помощью Sample Client из UA-.NET, я вижу два узла в разделе " Корни объектов":
- сервер
- История процесса {7a3ea44f-b495-414c-84f9-7498095d43bd}
За Server
узел метод работает нормально, но я не могу понять, как получить узлы вниз по дереву, начиная с Process Historian {7a3ea44f-b495-414c-84f9-7498095d43bd}
(которая на самом деле модель данных).
Код выглядит так (C#):
var startNodeId = new NodeId(Objects.ObjectsFolder);
var browsePaths = new BrowsePathCollection
{
new BrowsePath
{
RelativePath = RelativePath.Parse(relativePath, session.TypeTree, session.NamespaceUris, session.NamespaceUris),
StartingNode = startNodeId
}
};
var responseHeader = session.TranslateBrowsePathsToNodeIds(
null,
browsePaths,
out var results,
out var diagnosticInfos);
Результирующий код состояния BadNoMatch
,
relativePath
параметр 3:Process Historian {7a3ea44f-b495-414c-84f9-7498095d43bd}
(значение, которое Sample Client отображает как BrowseName для этого узла). Я пытался также без 3:
namespaceId префикс без разницы.
Если я попытаюсь использовать NodeId из Process Historian {7a3ea44f-b495-414c-84f9-7498095d43bd}
узел как startNodeId
параметр, результирующий StatusCode BadNodeIdUnknown
,
Этот же код хорошо работает с другими серверами OPC-UA, такими как KEPServerEX или Aspen InfoPlus21. Я не уверен, должен ли код быть другим или ProcessHistorian просто не поддерживает его. Любая помощь приветствуется.
РЕДАКТИРОВАТЬ: Как @AndrewCullen указал, что есть несколько способов, как получить RelativePath
пример. Я проверил код в UA-.NET и попытался также создать RelativePath
используя его конструктор, который контролирует каждый аспект объекта:
var qn = new QualifiedName("Process Historian {7a3ea44f-b495-414c-84f9-7498095d43bd}", 3);
var rp = new RelativePath(null, false, true, qn);
browsePaths.AddRange(relativePaths.Select(relativePath => new BrowsePath
{
RelativePath = rp,
StartingNode = startNodeId
}));
Согласно OPC UA Часть 04 - Услуги (глава 7.26), когда referenceTypeId
не указан (первый аргумент RelativePath
конструктор), тогда все ссылки включаются, а параметр includeSubtypes игнорируется. Так что эта конструкция должна быть наиболее универсальной (если я правильно понимаю). Но ни один из этих подходов не был успешным.
EDIT2:
Прикрепление атрибутов узла представления для узла Process Historian:
И что мне действительно нужно, это перевести Browse Path для тегов. Атрибуты одного тега-образца приведены на следующем рисунке.
Так что мне нужно будет решить путь, как: 3:Process Historian {7a3ea44f-b495-414c-84f9-7498095d43bd}/3:CMC/3:OSS1/3:OSS1_OSS1/3:ZAKLADAC/POC_VRSTEV.V
на его NodeId. Может быть еще одна загвоздка - косая черта в названии - мне нужно как-то избежать этого?
Edit3:
Также подано в качестве вопроса на GitHub OPCFoundation
2 ответа
Итак, окончательный результат заключается в том, что Proces Historian НЕ ПОДДЕРЖИВАЕТ TranslateBrowsePathsToNodeIds
(несмотря на это работает на Server
узел).
В конце концов я нашел документацию (гл. 3.9.5), что Process Historian поддерживает только следующие функции из View Service Set
:
Browse
BrowseNext
который соответствует View Basic
ConformanceUnit of View Services, подробно описано в OPC UA Часть 7. Профили
Я обнаружил, что RelativePath.Parse следует строковому формату, найденному в Части 4 - Приложение A.2 Служб.
Попробуйте поставить префикс перед косой чертой, например, "/3:Process Historian {7a3ea44f-b495-414c-84f9-7498095d43bd}"
пс. я вижу, что если вы укажете "3:", сервер будет считать, что вы имели в виду "0:"
имп. Используйте версию Parse с единственной строкой аргументов, ITypeTable. Вам не нужно переводить пространства имен в этом случае.
ppps: у большинства имен, которые я вижу, нет пробелов. Интересно, почему?
Попробуйте прочитать объект сервера?
var browsePaths = new [] { new BrowsePath { StartingNode= ObjectIds.ObjectsFolder, RelativePath=RelativePath.Parse("/0:Server/0:ServerStatus", session.TypeTree) } };
session.TranslateBrowsePathsToNodeIds(null, browsePaths, out BrowsePathResultCollection results1, out DiagnosticInfoCollection infos1);
Console.WriteLine($"Expecting 'i=2256', read {results1[0].Targets[0].TargetId}");