OPCFoundation / UA-.NETStandard

OPC Unified Architecture .NET Standard
Other
1.95k stars 945 forks source link

how to provide struct array #456

Closed JanEggers closed 6 years ago

JanEggers commented 6 years ago

Hi there I used your Reference Server as a starting point but now im stuck.

I need to provide an array of complex data, how am I supposed to do that?

I found this:

https://github.com/OPCFoundation/UA-.NETStandard/blob/c8ee59a40e1a31a7c3926ec8cd6df1b412348c69/SampleApplications/Workshop/Reference/Server/ReferenceNodeManager.cs#L251-L257

I tried DataTypeIds.Structure which seems to work?! (using DataTypeIds.ObjectNode freezes the program) but how can I provide the layout of each element in the array? And how can I actually set a value? Currently I just create an ExtensionObject[]. because that is what your data generator does.

but how can i create an object at index 0?

Is this the right method? https://github.com/OPCFoundation/UA-.NETStandard/blob/c8ee59a40e1a31a7c3926ec8cd6df1b412348c69/SampleApplications/Workshop/Reference/Server/ReferenceNodeManager.cs#L1425

I also found ArrayItemState but i didnt find any samples or docs on how to use it.

AlinMoldovean commented 6 years ago

Hello @JanEggers ,

First, you need to define your custom structured types, so you can create instances of those types in your server application. One option is to use the ModelCompiler tool, like ReferenceServer sample from the Legacy UA .NET Stack does. If you need to create an array with values of different types, you should use Variant

`BaseDataVariableState variantArrayVar =CreateVariable(arraysFolder, staticArrays + "Variant", "Variant", BuiltInType.Variant, ValueRanks.OneDimension);

                Quickstarts.Reference.DataType1 value1 = new Quickstarts.Reference.DataType1();
                value1.Int32Field = 1;
                value1.FloatField = 2;

                variantArrayVar.Value = new Variant[] {
                    "stringvalue",
                    new Variant(value1),
                    (float)123,
                    250 };

                variables.Add(variantArrayVar);`
JanEggers commented 6 years ago

that looks amazing!

so I just need to create classes that implement IEncodeable!

how can i create a variable of that type? the create variable methods seems to need a parent state and so on. or should i just create a single variant and set the value like in your sample?

JanEggers commented 6 years ago

I just tried

var state  = CreateVariable(parent , parent + "Variant", "Variant", BuiltInType.Variant, ValueRanks.Scalar);
state.Value = new Variant(new AlertSymbol()
{
       AlertState = EAlertState.Active,
       Priority = EPriority.Warning,
});

that seems to work but in the reference client i just see a byte array but no structure of that object.

JanEggers commented 6 years ago

I also tried this pattern:

https://github.com/OPCFoundation/UA-.NETStandard/blob/c8ee59a40e1a31a7c3926ec8cd6df1b412348c69/SampleApplications/Samples/Opc.Ua.Sample/Boiler/BoilerNodeManager.cs#L104-L124

that creates the object node but im not able to see either encoded bytes like with the variant nor the properties with seperate values

AlinMoldovean commented 6 years ago

@JanEggers ,

The UA Client should implement a procedure for decoding custom structured types. Please have a look at #243 and #444