Dear Sir/Madam,
I am currently testing the .NET SDK and having been looking at implementing custom structured data types. I have some success implemeting such data types using the SDK and the Modeler. I was however hoping to implement a custom structured data type without using the Modeler (and the XML nodeset it produces).
I have looked at the Vector data type of the UaDemoServer example, but that also relies on the XML definition. Could you provide a simple example (such as the vector) that does not use an XML nodeset description, but instead implements the data type entirely in code? This would help considerably, especially regarding the manual generation of the type descriptions.
Thank you!
Oliver
Ex of custom structured data type defined completely in code
Moderator: uasdknet
-
- Jr. Member
- Posts: 3
- Joined: 30 Sep 2014, 14:18
- Support Team
- Hero Member
- Posts: 3070
- Joined: 18 Mar 2011, 15:09
Re: Ex of custom structured data type defined completely in
Hello,
For adding custom structures we distinguish between adding the nodes to the addressspace and adding a class for the new DataType including encode and decode methods.
Please see the Vector class in DemoNodeManager. You have to write this class by hand. The class must be inherited from IEncodeable and must use the [DataContract] and [DataMember] fields.
Instead of using the NodeSet XML file for adding the necessary nodes, you have to add
- the structure node
- the DataTypeEncoding nodes (Default Binary and Default XML)
- the DataTypeDescription nodes
- the DataTypeDictionary with the NamespaceUri property
- the correct references between the nodes (e.g. HasDescription, HasEncoding)
Furthermore you have to add reasonable values for the Variables:
- The value of the dictionary node. The DemoServer example contains a demoserver.bsd file. The value of the dictionary contains the content of this file.
- The value of the DataTypeDescription nodes. This value specifies where to find the description of the structure within the dictionary. For the Vector example the value of the DataTypeDescription for the binary dictionary is 'Vector'.
Creating Objects in the code is described in the documentation (http://documentation.unified-automation ... tep07.html). Creating Variables can be done equivalently using CreateVariable and CreateVariableSettings.
Best regards
Support Team
For adding custom structures we distinguish between adding the nodes to the addressspace and adding a class for the new DataType including encode and decode methods.
Please see the Vector class in DemoNodeManager. You have to write this class by hand. The class must be inherited from IEncodeable and must use the [DataContract] and [DataMember] fields.
Instead of using the NodeSet XML file for adding the necessary nodes, you have to add
- the structure node
- the DataTypeEncoding nodes (Default Binary and Default XML)
- the DataTypeDescription nodes
- the DataTypeDictionary with the NamespaceUri property
- the correct references between the nodes (e.g. HasDescription, HasEncoding)
Furthermore you have to add reasonable values for the Variables:
- The value of the dictionary node. The DemoServer example contains a demoserver.bsd file. The value of the dictionary contains the content of this file.
- The value of the DataTypeDescription nodes. This value specifies where to find the description of the structure within the dictionary. For the Vector example the value of the DataTypeDescription for the binary dictionary is 'Vector'.
Creating Objects in the code is described in the documentation (http://documentation.unified-automation ... tep07.html). Creating Variables can be done equivalently using CreateVariable and CreateVariableSettings.
Best regards
Support Team
-
- Jr. Member
- Posts: 3
- Joined: 30 Sep 2014, 14:18
Re: Ex of custom structured data type defined completely in
Thank you for the helpful explanation. I have now managed to implement a custom structure data type in code.
-
- Jr. Member
- Posts: 2
- Joined: 04 May 2016, 03:53
Re: Ex of custom structured data type defined completely in
Hi,
I am currently implementing .net OPC UA Server, I have created a method called Transfer, where it has argument which takes a Array of structures.
here I have created a custom datatype of type structure in XML where it has 2 definitions. one is a custom datatype of type enumeration and another one is UInt32. This is mapped to input Argument of the Transfer method However I am not able to see the same in the uaexpert client.
here is the xml structure...
<UADataType NodeId="ns=1;i=3001" BrowseName="1:WorkTypeEnum">
<DisplayName>WorkTypeEnum</DisplayName>
<References>
<Reference ReferenceType="HasSubtype" IsForward="false">i=29</Reference>
</References>
<Definition Name="1:EDDDataTypeEnum">
<Field Name="BOOLEAN" Value="0"/>
<Field Name="DOUBLE" Value="1"/>
<Field Name="FLOAT" Value="2"/>
<Field Name="INTEGER" Value="3"/>
<Field Name="UNSIGNED_INTEGER" Value="4"/>
<Field Name="DATE" Value="5"/>
<Field Name="DATE_AND_TIME" Value="6"/>
<Field Name="DURATION" Value="7"/>
<Field Name="TIME" Value="8"/>
<Field Name="TIME_VALUE" Value="8"/>
<Field Name="BIT_ENUMERATED" Value="9"/>
<Field Name="ENUMERATED" Value="10"/>
<Field Name="ASCII" Value="11"/>
<Field Name="BITSTRING" Value="12"/>
<Field Name="EUC" Value="13"/>
<Field Name="OCTET" Value="14"/>
<Field Name="PACKED_ASCII" Value="15"/>
<Field Name="PASSWORD" Value="16"/>
<Field Name="VISIBLE" Value="17"/>
</Definition>
</UADataType>
<UAVariable DataType="LocalizedText" ParentNodeId="ns=1;i=3001" ValueRank="1" NodeId="ns=1;i=6028" ArrayDimensions="3" BrowseName="EnumStrings">
<DisplayName>EnumStrings</DisplayName>
<References>
<Reference ReferenceType="HasModellingRule">i=78</Reference>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
</References>
<Value>
<uax:ListOfLocalizedText>
<uax:LocalizedText>
<uax:Text>BOOLEAN</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>DOUBLE</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>FLOAT</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>INTEGER</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>UNSIGNED_INTEGER</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>DATE</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>DATE_AND_TIME</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>DURATION</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>TIME</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>TIME_VALUE</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>BIT_ENUMERATED</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>ENUMERATED</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>ASCII</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>BITSTRING</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>EUC</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>OCTET</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>PACKED_ASCII</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>PASSWORD</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>VISIBLE</uax:Text>
</uax:LocalizedText>
</uax:ListOfLocalizedText>
</Value>
</UAVariable>
<UADataType NodeId="ns=1;i=3007" BrowseName="1:WorkTypeInfo">
<DisplayName>WorkTypeInfo</DisplayName>
<References>
<Reference ReferenceType="HasSubtype" IsForward="false">i=22</Reference>
</References>
<Definition Name="1:WorkTypeInfo">
<Field DataType="WorkTypeEnum" Name="workEnum"/>
<Field DataType="UInt32" Name="size"/>
</Definition>
</UADataType>
<UAMethod NodeId="ns=1;i=7001" BrowseName="1:Transfer">
<DisplayName>Transfer</DisplayName>
<References>
<Reference ReferenceType="HasProperty">ns=1;i=6001</Reference>
</References>
</UAMethod>
<UAVariable DataType="Argument" ParentNodeId="ns=1;i=7001" ValueRank="1" NodeId="ns=1;i=6001" ArrayDimensions="2" BrowseName="InputArguments">
<DisplayName>InputArguments</DisplayName>
<References>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
<Reference ReferenceType="HasProperty" IsForward="false">ns=1;i=7001</Reference>
</References>
<Value>
<uax:ListOfExtensionObject>
<uax:ExtensionObject>
<uax:TypeId>
<uax:Identifier>i=297</uax:Identifier>
</uax:TypeId>
<uax:Body>
<uax:Argument>
<uax:Name>RequestDataType</uax:Name>
<uax:DataType>
<uax:Identifier>ns=1;i=3007</uax:Identifier>
</uax:DataType>
<uax:ValueRank>1</uax:ValueRank>
<uax:ArrayDimensions>20</uax:ArrayDimensions>
<uax:Description/>
</uax:Argument>
</uax:Body>
</uax:ExtensionObject>
<uax:ExtensionObject>
<uax:TypeId>
<uax:Identifier>i=297</uax:Identifier>
</uax:TypeId>
<uax:Body>
<uax:Argument>
<uax:Name>ResponseDataType2</uax:Name>
<uax:DataType>
<uax:Identifier>ns=1;i=3007</uax:Identifier>
</uax:DataType>
<uax:ValueRank>1</uax:ValueRank>
<uax:ArrayDimensions></uax:ArrayDimensions>
<uax:Description/>
</uax:Argument>
</uax:Body>
</uax:ExtensionObject>
</uax:ListOfExtensionObject>
</Value>
</UAVariable>
I am currently implementing .net OPC UA Server, I have created a method called Transfer, where it has argument which takes a Array of structures.
here I have created a custom datatype of type structure in XML where it has 2 definitions. one is a custom datatype of type enumeration and another one is UInt32. This is mapped to input Argument of the Transfer method However I am not able to see the same in the uaexpert client.
here is the xml structure...
<UADataType NodeId="ns=1;i=3001" BrowseName="1:WorkTypeEnum">
<DisplayName>WorkTypeEnum</DisplayName>
<References>
<Reference ReferenceType="HasSubtype" IsForward="false">i=29</Reference>
</References>
<Definition Name="1:EDDDataTypeEnum">
<Field Name="BOOLEAN" Value="0"/>
<Field Name="DOUBLE" Value="1"/>
<Field Name="FLOAT" Value="2"/>
<Field Name="INTEGER" Value="3"/>
<Field Name="UNSIGNED_INTEGER" Value="4"/>
<Field Name="DATE" Value="5"/>
<Field Name="DATE_AND_TIME" Value="6"/>
<Field Name="DURATION" Value="7"/>
<Field Name="TIME" Value="8"/>
<Field Name="TIME_VALUE" Value="8"/>
<Field Name="BIT_ENUMERATED" Value="9"/>
<Field Name="ENUMERATED" Value="10"/>
<Field Name="ASCII" Value="11"/>
<Field Name="BITSTRING" Value="12"/>
<Field Name="EUC" Value="13"/>
<Field Name="OCTET" Value="14"/>
<Field Name="PACKED_ASCII" Value="15"/>
<Field Name="PASSWORD" Value="16"/>
<Field Name="VISIBLE" Value="17"/>
</Definition>
</UADataType>
<UAVariable DataType="LocalizedText" ParentNodeId="ns=1;i=3001" ValueRank="1" NodeId="ns=1;i=6028" ArrayDimensions="3" BrowseName="EnumStrings">
<DisplayName>EnumStrings</DisplayName>
<References>
<Reference ReferenceType="HasModellingRule">i=78</Reference>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
</References>
<Value>
<uax:ListOfLocalizedText>
<uax:LocalizedText>
<uax:Text>BOOLEAN</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>DOUBLE</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>FLOAT</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>INTEGER</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>UNSIGNED_INTEGER</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>DATE</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>DATE_AND_TIME</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>DURATION</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>TIME</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>TIME_VALUE</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>BIT_ENUMERATED</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>ENUMERATED</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>ASCII</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>BITSTRING</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>EUC</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>OCTET</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>PACKED_ASCII</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>PASSWORD</uax:Text>
</uax:LocalizedText>
<uax:LocalizedText>
<uax:Text>VISIBLE</uax:Text>
</uax:LocalizedText>
</uax:ListOfLocalizedText>
</Value>
</UAVariable>
<UADataType NodeId="ns=1;i=3007" BrowseName="1:WorkTypeInfo">
<DisplayName>WorkTypeInfo</DisplayName>
<References>
<Reference ReferenceType="HasSubtype" IsForward="false">i=22</Reference>
</References>
<Definition Name="1:WorkTypeInfo">
<Field DataType="WorkTypeEnum" Name="workEnum"/>
<Field DataType="UInt32" Name="size"/>
</Definition>
</UADataType>
<UAMethod NodeId="ns=1;i=7001" BrowseName="1:Transfer">
<DisplayName>Transfer</DisplayName>
<References>
<Reference ReferenceType="HasProperty">ns=1;i=6001</Reference>
</References>
</UAMethod>
<UAVariable DataType="Argument" ParentNodeId="ns=1;i=7001" ValueRank="1" NodeId="ns=1;i=6001" ArrayDimensions="2" BrowseName="InputArguments">
<DisplayName>InputArguments</DisplayName>
<References>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
<Reference ReferenceType="HasProperty" IsForward="false">ns=1;i=7001</Reference>
</References>
<Value>
<uax:ListOfExtensionObject>
<uax:ExtensionObject>
<uax:TypeId>
<uax:Identifier>i=297</uax:Identifier>
</uax:TypeId>
<uax:Body>
<uax:Argument>
<uax:Name>RequestDataType</uax:Name>
<uax:DataType>
<uax:Identifier>ns=1;i=3007</uax:Identifier>
</uax:DataType>
<uax:ValueRank>1</uax:ValueRank>
<uax:ArrayDimensions>20</uax:ArrayDimensions>
<uax:Description/>
</uax:Argument>
</uax:Body>
</uax:ExtensionObject>
<uax:ExtensionObject>
<uax:TypeId>
<uax:Identifier>i=297</uax:Identifier>
</uax:TypeId>
<uax:Body>
<uax:Argument>
<uax:Name>ResponseDataType2</uax:Name>
<uax:DataType>
<uax:Identifier>ns=1;i=3007</uax:Identifier>
</uax:DataType>
<uax:ValueRank>1</uax:ValueRank>
<uax:ArrayDimensions></uax:ArrayDimensions>
<uax:Description/>
</uax:Argument>
</uax:Body>
</uax:ExtensionObject>
</uax:ListOfExtensionObject>
</Value>
</UAVariable>
- Support Team
- Hero Member
- Posts: 3070
- Joined: 18 Mar 2011, 15:09
Re: Ex of custom structured data type defined completely in
We will not answer in this old thread. You can find your answer in http://forum.unified-automation.com/topic1838.html.
Best regards
Unified Automation Support Team
Unified Automation Support Team