Professional OPC
Development Tools

logos

Online Forums

Technical support is provided through Support Forums below. Anybody can view them; you need to Register/Login to our site (see links in upper right corner) in order to Post questions. You do not have to be a licensed user of our product.

Please read Rules for forum posts before reporting your issue or asking a question. OPC Labs team is actively monitoring the forums, and replies as soon as possible. Various technical information can also be found in our Knowledge Base. For your convenience, we have also assembled a Frequently Asked Questions page.

Do not use the Contact page for technical issues.

Variable Array Element Live Mapping in OpcUA

More
08 Feb 2017 08:41 #4936 by support
I tried to work with this and understand what it is doing. However, even their own (weird) code for browse path translation returns QueryTooComplex. For now, I have not seen the translation working with the path from the same starting node ID as used in your Live Binding project to the same problematic "array" element, so there is nothing to comment on.

Best regards

Please Log in or Create an account to join the conversation.

More
07 Feb 2017 16:33 #4935 by bmts
Hello,
I got answer from the Siemens Support.
They send me recommendation: "check the behaviour with this OPC client first. Please use the following link: support.industry.siemens.com/cs/ww/en/view/109737901".

...I downloaded it ... set up autologin to my PLC, then I modified "NodeTreeView_BeforeSelect"(UAclientForm.cs) function and added click event "Translate_array_element_click" (UAclientForm.cs)

"Translate_array_element_click":
this function try to translate some relative paths. Here you can see that tranlation of arrayElement node works but not correctly : translation result is Good but Translated node has mistake because contains 2 square brackets( ns=3;s="DATA"."ArrUDT_Counters"[[0]]).
In other translation you can see that translation with correct NodeID works.

"NodeTreeView_BeforeSelect":
I tried translate paths when you click on item in NodeTree, but Here is something wrong by the calling.

Summary:
The path translation partialy work.
I will conntact Siemens support again.
Attachments:

Please Log in or Create an account to join the conversation.

More
27 Jan 2017 15:19 #4907 by support
Hello.

ad a) You do not map the whole array anywhere. I had something like this in mind:
public class DT_DATA : DisplayData
    {
...
        [UAData]
        [UANode(BrowsePath = ".ArrUDT_Counters", NodeId = "nsu=http://www.siemens.com/simatic-s7-opcua;ns=3;s=\"DATA\".\"ArrUDT_Counters\"")]
        public object[] ArrUDT_CountersObject
        {
            get
            {
                ...
            }
            set
            {
                ...
            }
        }
 

But I I did not realize that this is not an array of simple type (like Integer or so), but rather an array of structured type element. So the above works in principle, but you receive an array of OPC UA ExtensionObject-s, which are not of direct use.

ad b) Unfortunately that is not possible in the current version. Making note to possibly support it in the future.

ad c) This would be possible if knew the browse path that the server expects, for the array elements (if there is any - I doubt that). But we do not have/know this browse path.

Best regards

Please Log in or Create an account to join the conversation.

More
27 Jan 2017 09:52 #4903 by bmts
That are not good news for me. I suppose that the communication about this, with Siemens, take a lot of time. I will contact the support and I will see.

Question:
workaround a)
I tried mapp whole array, but it not work as I want. Can you check code in attachment and tell me what is wrong?

workaround b)
When I set the template attribute, the nodeID will be crated, but it take "." from BrowseName and due to it is not correct. It is posible remove "." From BrowsePath?

c) It is possibe to define BrowsePath (in my code with some heuristic rule) in order to get the node path which is correct for mapper?
Attachments:

Please Log in or Create an account to join the conversation.

More
26 Jan 2017 11:09 #4895 by support
I have investigated the issue, and as far as I can tell, the responsibility lies on the server side.

The error (BadNoMatch) comes, as expected, from the TranslateBrowsePathsToNodeIds service of the server. I have checked the browse path we pass in, and I could not find any problem with it. It is the same path as for the "parent" object, with one more element at the end. The element has the right name (e.g. "0"), is in the right namespace (it happens to be namespace index 3), and the reference type id we use it "Aggregates", which is one of the reference types we have used when we obtained the browse name. I have experimented with hard-coding a much wider reference type (any hierarchical type), but it did not help.

I suggest that you contact the server vendor with these findings and ask them for explanation. I will be willing to cooperate in case a deeper technical data/discussion is needed.

Possible workarounds:

a) Do not map the nodes that the server creates for elements of the array. Just map the parent node (the whole array).

b) It might be possible (although normally it is not recommended in Live Mapping) to use NodeID instead of a browse path. Have a look at the NodeId argument of the UANodeIdAttribute, or (more flexible) UANodeIdTemplate attribute (opclabs.doc-that.com/files/onlinedocs/QuickOpc/Latest/User%2...%20Node%20Id%20Resolution.html ). The NodeID of the array element nodes in this server appears to be constructed by adding the index in brackets (e.g. "[0]"). So (not tested) the template string on the mapped class may be something like "$(ParentNodeID)[$(BrowseName)]". However the parent Node ID must somehow be known, so you may end up specifying it by an attribute (on the parent property level) as well.

Best regards

Please Log in or Create an account to join the conversation.

More
26 Jan 2017 07:08 #4894 by support
Great, thank you. I was able to build the project, connect, and reproduce the problem. I will inform you here when we know more.

Regards

Please Log in or Create an account to join the conversation.

More
25 Jan 2017 04:31 #4886 by bmts
hello
Answer on Q1:
Yes, the problem is only with nodes which are “ArrayElement”
(node that has reference on parentNode and this node has ValueDataType.Rank = 1)

Answer on Q2:
YES. In attachment is DemoApplication with set up IP,Port, LogIn,Password

Answer on Q3:
No Becouse Q2

Regards
Attachments:

Please Log in or Create an account to join the conversation.

More
24 Jan 2017 12:59 #4884 by support
Hello, and thank you.

Explanations:

E1. There are essentially three things that happen in a sequence, and each of them may be responsible for the issue:

1. During browsing in the dialog, we construct the browse path based on a starting node, by adding elements to the browse path as the user delves deeper. There is some ambiguity and heuristic in how the browse elements are constructed, so theoretically there can be some issue.

2. When you call some operation on a node that has no NodeID in its descriptor but has a browse path, the UABrowsePath constructed as described above needs to be transformed back to the structures that the server understands. This can theoretically also go wrong, although it is quite unlikely in my view.

3. The browse path from the previous step is then passed to the server fo translation to a Node ID. This is the step where the error actually comes from - the server does not understand some part of the browse path. What we pass in may be correct, but the server may still fail to translate it - either as their design decision, or because of a bug.

We will try to determine where in the above three parts the problem may be.


Information:

I1.

The following is not a problem right now, but be aware that what UABrowsePath.ToString() returns, and also what is displayed in the browse dialog, is *not* a full string representation of the actual browse path; this is also why there is "(*)" next to it in the browse dialog, to mark that is not the actual (full) browse path.

This is done so because the actual unambiguous string representation is, for any reasonable browse path, *very* long. Main reason for it is that each browse path element contains a browse name, which UA qualified name, meaning that it has a namespace + the actual name, and the namespace is a URI which already is usually quite long; and then there is a namespace with each element.

You will understand this quite nice if you explore the UABrowsePath elements in the debugger. In your modified UADocExample, you are passing the actual UABrowsePath object to the UANodeDescriptor, therefore there is no conversion to/from string, and it is not an issue. But it *might* be an issue when you later go back to Live Mapping - in there, the properly qualified browse names must be used, so you need to watch out for that, and not rely blindly what the browse dialog shows.

I2. Just as a note, which does not affect what we are discussing here, you have a minor bug in the example, where the statements following the invocation of the browse dialog are not between { and }, and therefore e.g. the browse path is taken over even if the user has Cancel-ed the dialog.



Questions:

Q1. Do I understand it correctly that roughly the same things work well with other nodes. I.e. that the problem is only with what you call "array" nodes?

Q2. Will you be able to provide us either with the (demo version of the) server, or an endpoint of it accessible over Internet that we can connect to? (can be firewalled to allow access only from our IP). This would allow us to investigate the issue without further losing your time.

Q3. Will you be willing to make Wireshark log of the communication between the client and the server? (This is less preferred than the option above, because the analysis is more difficult on our side, and it would not allow us to freely play with it and try out some solutions).

Regards

Please Log in or Create an account to join the conversation.

More
23 Jan 2017 16:43 #4874 by bmts
I am sorry. I in the previous attachment was missing the last picture with error code. The pictures are now in attachment.

I want to say, that I am using only BrowsePath in my .NET LiveMapping Model. And because I have problem with mapping variable which is element in Array, I tried to use your example application. In this application I change Subbscribe and Read function where I passed BrowsePath instead of NodeDescriptor.
The result is that Subscribe and Read function throw exception (when is use the BrowsePath which is created by UaDataDialog)

Exception:
OPC-UA service result - An error specific to OPC-UA service occurred.
---- SERVICE RESULT ----
StatusCode: {BadNoMatch} = 0x806F0000 (2154758144)
Attachments:

Please Log in or Create an account to join the conversation.

More
23 Jan 2017 15:43 #4873 by support
I am sorry, but what error are you getting? In which step in the recording do you believe something is wrong? I could not find it.

Before you answer this, I will also describe how it is supposed to work. You may already know it, but just to be sure.

The UANodeDescriptor can contain either the NodeID, or the BrowsePath, or both.
If it contains both, the developer is responsible for making sure that the NodeID actually referes to the same node as the BrowsePath. This is because the EasyUAClient may select either the NodeID, or BrowsePath, depending on the situation.

Why is done in this way?

NodeID are generally what OPC UA works with - for purposes of reading, writing, subscriptions etc., that's how nodes are identified, and are efficient: The OPC servers are programmed in such a way.

But NodeID does not give you any idea of where you are in the address space. Imagine following thing: The user uses the browsing dialog, starts from the Objects folder, and goes several levels deeper and select a node there. This gives us a NodeID, primarily. If we then wanted the user to return to the browse dialog and see the same tree as before, we would be lost. There is no general and guaranteed way to tell where the previously selected NodeID is in the address space (sometimes there is - but not always). Having BrowsePath helps to restore the state of the browsing dialog.

In addition, browse path are useful with object/variables of repeating structure (I suppose that may be your use case too).

If you only specify BrowsePath in the UANodeDescriptor, for most usages the component will first translate it to a NodeID (which requires an extra call to the server).

Best regards

Please Log in or Create an account to join the conversation.

Moderators: support
Time to create page: 0.078 seconds