Reading and Writing complex structures|OPC UA Implementation: Stacks, Tools, and Samples|Forum|OPC Foundation

Avatar
Search
Forum Scope


Match



Forum Options



Minimum search word length is 3 characters - maximum search word length is 84 characters
Lost password?
sp_Feed sp_PrintTopic sp_TopicIcon
Reading and Writing complex structures
Avatar
Glenn Bettens
Member
Members
Forum Posts: 7
Member Since:
03/21/2018
sp_UserOfflineSmall Offline
1
04/06/2018 - 05:08
sp_Permalink sp_Print

Dear,

 

I have been struggling with this 'concept' a bit and therefor hope to get an answer / guideline from this forum.

I need to read a large amount of data from an OPC UA Server everytime a test on a machine ends.

This data will be made available in an 'array' of complex types. 

- fpv_curve (Node Class = Object, Node Id = ns=4;.fpv_curve)

   - fpv_curve[1] (Node Class = Object, Node Id = ns=4;.fpv_curve[1])

   - fpv_curve[2] (Node Class = Object, Node Id = ns=4;.fpv_curve[2])

   - fpv_curve[3] (Node Class = Object, Node Id = ns=4;.fpv_curve[3])

   - ...

The fpv_curve[X] has a number of variables with the actual values I need.

 

Now I am wondering how can I can ask the OPC UA Server to give me fpv_curve[X] to fpv_curve[Y] with all the values included. 

I'm thinking for getting a datastream from the OPC UA Server and start reading (and serializing) the data until a certain point.

 

At the moment I made a 'program' where I create a list with 'ReadValueId' for all the different values I want to read from the fpv_curves but this takes to long and is not maintainable.

 

So my question to you is, is there a way where I can 1) Read a 'complex' type (as in a fpv_curve struct) and 2) Can I read a array from index X till Y with the 'complex' type?

 

Thanks in advance!

If there are question or if you which more information, feel free.

 

Kind regards,

 

Glenn

Avatar
Randy Armstrong
Admin
Forum Posts: 1564
Member Since:
05/30/2017
sp_UserOfflineSmall Offline
2
04/06/2018 - 12:56
sp_Permalink sp_Print

Have you considered a subtype of TemporaryFileTransferType (see Part 5 Appendix C).

Avatar
Glenn Bettens
Member
Members
Forum Posts: 7
Member Since:
03/21/2018
sp_UserOfflineSmall Offline
3
04/09/2018 - 01:03
sp_Permalink sp_Print

Dear Randy, 

Thank you for your reply.

I just read the Appendix C, but I don't quite follow what is described there.

So what this article suggest is that I make a method on the OPC UA Server that allows me to create a file structure of an address, in my case the array of objects, to stream this over to the client?

Can this also work when we don't 'control' the way the UA Server is made? Since we only have a .NET Client API to connect to a UA Server. We don't have a API to create a OPC UA Server. (we use the UA Server from the Supplier of the PLC)

Is there a code example for this (Appendix Part 5.C) on Github?

 

I did some testing myself to figure out a way to read the requested data.

At this moment, I'm creating a List of <ReadValueId> that I send to the UA Server. The server responds with a list of DataValue.

The server respondsin about 1 second for 8000 DataValues, but I don't like the way that it's code (half static NodeId's) and the way the data returns to me (a list with flat values). There should be a better way to get the data (possibly streaming asynchronously) and to format/serialize the data in a useable structure.

 

Kind regards,

Glenn

Avatar
Randy Armstrong
Admin
Forum Posts: 1564
Member Since:
05/30/2017
sp_UserOfflineSmall Offline
4
04/09/2018 - 02:56
sp_Permalink sp_Print

There are better ways to model the data but they all require the server to do something.

If you can't change the server then your options are limited.

That said, if you have an array to read you can read the entire array with a single ReadValueId.

It is not clear why you need 8000.

Avatar
Glenn Bettens
Member
Members
Forum Posts: 7
Member Since:
03/21/2018
sp_UserOfflineSmall Offline
5
04/09/2018 - 04:04
sp_Permalink sp_Print

Dear Randy,

 

What I was trying to say was that I build a List of 8000 ReadValueId's and than I call the session.Read() and pass in this list.

In the background this will be 1 request of all these Id's that will be send to the OPC UA Server.

 

What I essentially hoped was that I can say:

session.read(4000, ns=4;.fpv_curve, FpvCurveType)

1st value being the amount of items to read

2nd value being the NodeId that contains the array

3rd value being the 'structure' to parse it in (and this structure should than also be available on the OPC UA Server)

 

Kind regards,

Glenn

Avatar
Zbynek Zahradnik
Member
Members
Forum Posts: 62
Member Since:
02/24/2014
sp_UserOfflineSmall Offline
6
04/09/2018 - 07:29
sp_Permalink sp_Print

Hello,

I am not sure if I understand what you want to achieve, but here is my bit.

If you have (maybe besides nodes that carry the individual elements) a node whose value is an array, then (assuming that the server supports it, but most do) you should be able to set the IndexRange property in the Opc.Ua.ReadValueId, and the server would return the specified sub-range of elements.

If the value of the element, or the whole array, is a "structure" that is not defined in the OPC specs and therefore does not have its encoder/decoder in the stack, you should be getting Opc.Ua.ExtensionObject in the value that you read. Is that the case?

Best regards

Zbynek

Avatar
Paul Hunkar
Cleveland, Ohio, USA
Moderator
Members

Moderators-Specifications

Moderators-Companion

Moderators-Implementation

Moderators-Certification

Moderators-COM
Forum Posts: 112
Member Since:
02/24/2014
sp_UserOfflineSmall Offline
7
04/09/2018 - 11:47
sp_Permalink sp_Print

My first question is, since the information model (data in the PLC) is controlled by the Server Vendor, do you have a more detailed description of what the Model is?  What does the data look like, are there ObjectType/VariableTypes that can be provided Having that information would allow a much clearer description of what is possible from the client side.   It would also be useful to know what functionality the Server contains (historical data)

Paul

Paul Hunkar - DSInteroperability

Avatar
Glenn Bettens
Member
Members
Forum Posts: 7
Member Since:
03/21/2018
sp_UserOfflineSmall Offline
8
04/09/2018 - 23:32
sp_Permalink sp_Print

Dear,

Thanks for your responses.

I will try to explain the situation as clear as possible, but keep in mind i'm new to the OPC UA way of thinking and don't have a lot of experience with it. If I have time i'm reading the documentation about OPC UA but since I'm project bound this goes slow. Also, I don't seem to be able to upload screenshots which would probably make it easier to show you the structure I have in the PLC.

We have a Beckhoff PLC with a UA Server installed on it (The Beckhoff UA Server). On the PLC there is a program that measures the force and position of a machine. Every X µs the PLC will measure the position and force and write it in a empty position in the following variable.

fpv_curve : ARRAY[1..128000] OF struct_fpv_curve_record ; 

The struct_fpv_curve_record is a STRUCT with some REAL values (for the position, force and other values) in it.

At the end of the machine test the PLC will provide a int value to determine the end position of the array. (To let me know what the last index is)

If I look in the OPC UA Server and browse the items I get the following types:

- fpv_curve

Node Class : Object

- fpv_curve[1]

Node Class : Object

- fpv_curve[1].Position

Node Class : Variable

- fpv_curve[1].Force

Node Class : Variable

So at this moment the value containing the array itself is also of the type Object. (Which I will discuss with our PLC programmer)

I hope this answers your question for more information @Paul Hunkar?

@zbynekz If I try to read a NodeId with NodeClass Object I get a value of Null.

 

Kind regards,

Glenn

Avatar
Zbynek Zahradnik
Member
Members
Forum Posts: 62
Member Since:
02/24/2014
sp_UserOfflineSmall Offline
9
04/10/2018 - 22:39
sp_Permalink sp_Print

It looks like that the server does not expose the array as a readable variable, and it does not expose its elements as readable variable either - only the individual properties of the individual elements. If this is the case, you won't be able to achieve what you want just by doing something on the client side.

Isn't there a setting on the server to make it expose the array as a variable? Or maybe a different way of declaring it in the PLC program?

OPC UA is capable of doing what you want, just fine - you just need to have the software (or its proper configuration) that actually implements it.

Regards

Avatar
Glenn Bettens
Member
Members
Forum Posts: 7
Member Since:
03/21/2018
sp_UserOfflineSmall Offline
10
04/11/2018 - 08:26
sp_Permalink sp_Print sp_EditHistory

Dear zbynekz,

You are a life saver!

Once I read the sentence with 'does not expose the array as a readable variable' I started looking into the PLC code. 

As said before, I'm using a Beckhoff PLC and there are apparently 2 attributes you need to use to expose your variables and with the Structure.

--> {attribute 'OPC.UA.DA' := '1'}

--> {attribute 'OPC.UA.DA.StructuredType' := '1'}

Once you enable these 2 attributes you can read the NodeId's as values. 

The problem I'm having now is that the PLC is not able to offer me the 128000 array. It's just to big. So I'll have to shorten it.

So I gues my problem is fixed. I can read the data in half a second. The only thing I need to know now is how to format the data i'm getting to a useable format. --> This is also fixed at the moment. I have to enable 'DecodeCustomDataTypes' in my client so that my client loads the custom structures. After that I can just read my StructureValue and map those values to a Custom Object I can use.

Thanks again for the help!

Avatar
Zbynek Zahradnik
Member
Members
Forum Posts: 62
Member Since:
02/24/2014
sp_UserOfflineSmall Offline
11
04/13/2018 - 02:50
sp_Permalink sp_Print

Good.

The PLC may still be able to give you a range from the whole array, if you set the IndexRange in ReadValueId. Have you tried that? The IndexRange should be e.g. "1000:2000".

I am curious, which client are you talking about/are using, when mentioning the ‘DecodeCustomDataTypes’ option?

Best regards

Avatar
Glenn Bettens
Member
Members
Forum Posts: 7
Member Since:
03/21/2018
sp_UserOfflineSmall Offline
12
04/15/2018 - 22:48
sp_Permalink sp_Print

Dear Zbynekz,

I am using the SOFTING OPC UA .NET toolkit for communication. (So client side)

And the IndexRange worked.

Thanks again!

Kind regards,

Glenn

Avatar
Denis Sangaletti
Member
Members
Forum Posts: 4
Member Since:
09/07/2023
sp_UserOfflineSmall Offline
13
09/07/2023 - 10:58
sp_Permalink sp_Print

hi I think I have a similar problem but I can not understand how to solve it with javascript

I need create a structure as follow:

object:

->"ordini" (array[0..10]) 

->->"ordini"[1].var1 (word)

->->"ordini"[1].var2 (int)

->->"ordini"[1].var3 (array[0..10])

->->-> "ordini"[1].var3[1].var1 (string)

->->-> "ordini"[1].var3[1].var2 (word)

->->-> "ordini"[1].var3[1].var3 (float)

 

->->"ordini"[2].var1 (word)

->->"ordini"[2].var2 (int)

->->"ordini"[2].var3 (array[0..10])

->->-> "ordini"[2].var3[1].var1 (string)

->->-> "ordini"[2].var3[1].var2 (word)

->->-> "ordini"[2].var3[1].var3 (float)

and so on

how can create it with javascript (i'm using opcua in nodered)

I start with 

function constructAlarmAddressSpace(server, addressSpace, eventObjects, done) {
  const opcua = coreServer.choreCompact.opcua;
  const LocalizedText = opcua.LocalizedText;
  const namespace = addressSpace.getOwnNamespace();
  const Variant = opcua.Variant;
  const DataType = opcua.DataType;
  const DataValue = opcua.DataValue;
  var flexServerInternals = this;
  const rootFolder = addressSpace.findNode("RootFolder");
  node.warn("construct new address space for OPC UA");
  const ordiniFolder = namespace.addFolder(rootFolder.objects, {
    "browseName": "ordini"
  });
  const ordine = namespace.addObject({
    organizedBy: ordiniFolder,
    browseName: "ordine"
  });
  const arrayOrdini = namespace.addObjectType({
    browseName: "ordini",
  })
  done();
}

many many thanks in advance. I ask help for my urgent work

Avatar
Randy Armstrong
Admin
Forum Posts: 1564
Member Since:
05/30/2017
sp_UserOfflineSmall Offline
14
09/07/2023 - 16:02
sp_Permalink sp_Print
Forum Timezone: America/Phoenix
Most Users Ever Online: 510
Currently Online:
Guest(s) 45
Currently Browsing this Page:
1 Guest(s)
Top Posters:
Forum Stats:
Groups: 2
Forums: 10
Topics: 1435
Posts: 4855