12:51, EEST
July 22, 2014
Please forgive my ignorance regarding the details of OPC UA. I have typically worked with OPC DA and on top of that I usually used toolkit which hid most of the low level implementation.
I have managed to use the Client Tutorial documentation to create a very minimalistic client (for the purpose of learning) which connects to my server (a Kepware Server) navigates down a couple nodes (a folder called “Station01”, a sub-folder called “FareGates”) to some leaf nodes (called “FG01”, “FG02” and “FG03”). Lastly the client reads the Value attribute from one of the leaf nodes. This work fine.
When I use the getNodeId() function at the leaf node, I get something like “ns=2;s=Station01.FareGates.FG01.State”. This is similar (but not identical) to the OPC DA tag convention that I am typically used to which is the notation that I would like to use in such things as configuration files.
So, ideally, I would like to be able to “get to a node” by using the string returned by getNodeId(). I found that the following code seems to work:
client.readAttribute(NodeId.decode(“ns=2;s=Station01.FareGates.FG04.State”,Attributes.Value).getValue();
However, NodeId.decode() is listed as deprecated. What is the new way of doing this to replace the deprecation?
Any help to point me in the right direction would be greatly appreciated.
13:14, EEST
December 21, 2011
In UA things work a bit different than in DA. Generally speaking you cannot assume that the Identifier is a string, it is very common that they are numeric and can also be a GUID or an opaque byte array. In addition to the Identifier, you should also persist the NamespaceUri of the Node, which you can translate to the appropiate NamespaceIndex upon connection. NamespaceIndexes can change so this is why it’s safer to persist the NamespaceUri instead. Any configuration files you have should have both the NamespaceUri(s) you’re working with as well as the Identifiers, which may or may not be strings.
But assuming that you work with unchanging NamespaceUris, you can use the method pair toString/parseNodeId in NodeId.
For getting the NamespaceUri for a NamespaceIndex, use client.getNamespaceTable().getUri(int index), this way you can avoid mixing namespaces if the NamespaceIndexes change on the server.
14:01, EEST
July 22, 2014
Thanks for the quick answer. The NodeId.parseNodeId() seems to work fine (at least in my particular case).
As for the rest of your very informative answer…
In cases where nodeIds are not string then how would one get a specific OPC UA tag node (without navigating to it)? Would you be forced to use whatever NodeIds the server provides or is there some way to translate between the human readable tag notation (i.e. similar to the tag notation of OPC DA)? I mean from a configuration point of view if I use an OPC Server, like Kepware (I have not yet gotten far enough to create one using your SDK), to create a structure such as a “Stations” folder, a “Fare Gates” sub-folder, and some leaf nodes representing my fare gate devices (or a sub folder for each device with a bunch of leaf signals) then, ideally, I want to be able to refer to these tags by something like “Stations.FareGates.FG01.State” as opposed to some arbitrary nodeId assigned by the server.
I guess I could browse the OPC Server on startup and create a dictionary between the node Display Names (including the entire hierarchical parental Display Names to create a pseudo OPC DA tag) and the corresponding server node Ids but this seems to me like functionality that should already exist. Otherwise I could need to parse the tag and compare Display Names at each level to determine which node to navigate to until I reach the leaf.
It seems that OPC UA somewhat obfuscates access to tags by introducing this concept of nodes. If I recall OPC DA (or at least some client implementations there of) does a similar thing with subscriptions (i.e. subscribed tags have client handles which used to update data) but the toolkits generally converted this back to a OPC DA tag, value and timestamp notation so that the user only used the OPC DA tag notation (and the client handles were all transparent to the user).
6:12, EEST
December 21, 2011
Yes, this part is very different in UA than in DA. I will try to explain and stay informative
In OPC UA there is no concept of a tag and no similar tag notation. DisplayNames of Nodes are not guaranteed to be unique in the server, so generally speaking a mapping of DisplayName to NodeId will not yield one-to-one relationships. UA servers with tags running into the tens or hundreds of millions are not unheard of, even if they’re not very common (yet), which is another problem with creating such a dictionary. But yes, where the server implementation has unique DisplayNames and the number of Nodes is very small this can be a viable logic, especially if you connect via UaGateway or other wrapper to OPC DA servers. And of course, if you write the server you can also decide how NodeIds are assigned, so you can use string NodeIds that contain a DA-like tag path.
The way the UA spec sees this is as the NodeId being just some set of information you can use like a handle, while a similar idea to the tag notation is provided by BrowseNames of Nodes and the TypeDefinition of each Node. So in your example, assuming there is a StationsType defined, you could use TranslateBrowsePathToNodeIds method to get a list of the State objects of all the fare gates easily, including their types. The configuration interface never needs to show the NodeId’s to the user.
I’m sure this very short explanation did not explain everything, the type system and browsing mechanisms of OPC UA are very powerful but also quite a bit different from OPC DA’s simple tag hierarchy. We of course aim to make the SDK as easy to use as possible, but we cannot assume anything about other clients and servers than what is being dictated by the specification, so this is why there’s no silver bullet in the SDK for this.
15:48, EEST
July 22, 2014
Thanks for the answer. It was informative.
I understand that the OPC UA specs treat the data differently so there may not be the concept of a OPC DA tag but from a user stand point there still exists a OPC DA tag like concept because this is how many of the OPC UA Servers are configured. For example, when configuring a Kepware OPC UA server, you still have a hierarchy in which your signals exist. In such a implementation, a unique signal is typically referred to by providing its complete path in the address space separated by slashes (to mimic Windows/Linux file system’s folder notations) or separated by dots (to mimic an OPC DA tag notation).
I understand that because of the way OPC UA works, it can get at data in many other ways besides the classic OPC DA tag notation but I don’t see the concept of the OPC DA tag notation going away any time soon because it mimics the way that data is added to most OPC UA Servers. Of course, this does not mean that the OPC DA tag notation has to be used to actually store the information but I believe there will always be a need for some sort of a translation function which can use something similar to the OPC DA tag notation (which basically indicates the location of the signal in the OPC Server configuration) and translate it to whatever the server is using to actually store the data (in this case nodes).
If it would not be too much trouble, could you post a quick example of how to use the TranslateBrowsePathToNodeId() function. As I said, the JavaDoc is great at documenting functions but simple examples are usually worth a 1000 words of explanation.
7:16, EEST
December 21, 2011
I posted a simple example of using TranslateBrowsePathsToNodeIds here: http://forum.prosysopc.com/for…..erex/#p908
15:17, EEST
June 2, 2019
Hi There,
I am a beginner in OPCUA.
As a student Project, i need to develop an Android Application, which would communicate with a Raspberry PI which has a OPCUA Server(coded in Objective C).
My motive now, is to make changes to the nodes through the APP itself and not through hardcoding.
First and foremost, how will i be able to see the list of available nodes on my application?
Also, if i make changes to any particular node, where it will get reflected in the server?
Please let me know.
10:31, EEST
April 3, 2012
Hi and Welcome to OPC UA,
I recommend starting with the tutorials that come with the SDK zip. Additionally you will need to learn OPC UA. Personally I would recommend just reading the specification (https://opcfoundation.org/developer-tools/specifications-unified-architecture, at least Parts 1,3 and 4). Then look at the SampleConsoleClient sample that comes with the SDK, that should answer most of the questions.
P.S. If the specification feels too heavy to read, this documentation from our partners could be useful http://documentation.unified-a…..ntals.html (it is for C++ SDK, but it explains the basic concepts quite well).
23:56, EEST
June 2, 2019
Well thanks for the link. As i am new to OOP, it is a touch difficult to use the methods and figure out.
I am not able to use the correct method to list out all the nodes present in the server.
To give a brief about the code,
ApplicationDescription applicationDescription = new ApplicationDescription();
applicationDescription.setApplicationName(new LocalizedText(“AndroidClient”, Locale.ENGLISH));
applicationDescription.setApplicationUri(“urn:localhost:AndroidClient”);
applicationDescription.setProductUri(“urn:localhost:AndroidClient”);
applicationDescription.setApplicationType(ApplicationType.Client);
KeyPair myClientApplicationInstanceCertificate = ExampleKeys.getCert(getApplicationContext(), applicationDescription);
// Create Client
Client myClient = Client.createClientApplication(myClientApplicationInstanceCertificate);
EndpointDescription[] endpoints = myClient.discoverEndpoints(“opc.tcp://192.168.4.1:4840”) //connect to my server
// Filter out all but opc.tcp protocol endpoints
endpoints = EndpointUtil.selectByProtocol(endpoints, “opc.tcp”);
// Filter out all but Signed & Encrypted endpoints
endpoints = EndpointUtil.selectByMessageSecurityMode(endpoints, MessageSecurityMode.None);
// Filter out all but Basic256Sha256 cryption endpoints
endpoints = EndpointUtil.selectBySecurityPolicy(endpoints, SecurityPolicy.NONE);
// Sort endpoints by security level. The lowest level at the beginning, the highest at the end of the array
endpoints = EndpointUtil.sortBySecurityLevel(endpoints);
// Choose one endpoint.
EndpointDescription endpoint = endpoints[endpoints.length – 1];
SessionChannel mySession = myClient.createSessionChannel(endpoint);
mySession.activate();
—
I am not finding any method to get the list of nodes present in the server.
This is for a purpose of developing a client application on android. So, i plan to have a list of all nodes present.
Please guide me here.
10:17, EEST
April 3, 2012
Hi,
As I said, please look at the tutorial and the samples that come with the SDK zip. Basically the code you have shown is not something you should be doing, or well even be aware of as that is very low level functions which are basically what the SDK uses internally. Basically we don’t instruct to do that at all! i.e. you have looked at the wrong place.
Your code is somewhat equivalent what would be in the (old) opc foundation stack examples, which is a very low level communication implementation the SDK uses (and which in practice does not exist anymore in SDK version 4.x or well I wont go into details, please see the release notes + migration guide if you wish to know more about that).
The SDK does all that for you via the UaClient class (well you will need to set the ApplicationIdentity and ApplicationDescription as part of it). Please check the SampleConsoleClient example from the SDK zip you downloaded (version 4.0.2).
Most Users Ever Online: 1919
Currently Online:
12 Guest(s)
Currently Browsing this Page:
1 Guest(s)
Top Posters:
Heikki Tahvanainen: 402
hbrackel: 144
rocket science: 88
pramanj: 86
Francesco Zambon: 83
Ibrahim: 78
Sabari: 62
kapsl: 57
gjevremovic: 49
Xavier: 43
Member Stats:
Guest Posters: 0
Members: 736
Moderators: 7
Admins: 1
Forum Stats:
Groups: 3
Forums: 15
Topics: 1524
Posts: 6450
Newest Members:
kristiewinkle8, rust, christamcdowall, redaahern07571, nigelbdhmp, travistimmons, AnnelCib, dalenegettinger, howardkennerley, ThomassnismModerators: Jouni Aro: 1026, Pyry: 1, Petri: 0, Bjarne Boström: 1026, Jimmy Ni: 26, Matti Siponen: 346, Lusetti: 0
Administrators: admin: 1