OPCFoundation / UA-.NETStandard

OPC Unified Architecture .NET Standard
Other
1.97k stars 950 forks source link

Reading ComplexTypes from Server #2825

Open JessevGool opened 3 weeks ago

JessevGool commented 3 weeks ago

Type of issue

Current Behavior

Currently failing to decode the ExtensionObject into the expected UDT using the following code

 var session = Session.Create(config, new ConfiguredEndpoint(null, selectedEndpoint, EndpointConfiguration.Create(config)), false, "", 60000, null, null).GetAwaiter().GetResult();

 var complexTypeSystem = InitializeComplexTypeSystem(session);
 foreach (var type in complexTypeSystem.GetDefinedTypes())
 {
     Console.WriteLine($"Type Loaded: {type}");
 }
 var result = session.ReadValue("ns=3;s=\"H35dispenser\".\"ID\".\"ElectricalVersion\"");
 Console.WriteLine(result);
 if (result.Value is ExtensionObject extObject)
 {
     Console.WriteLine(extObject.Body.ToString());

     var customType = extObject.Body as UDT_SemVer;
     if (customType != null)
     {
         Console.WriteLine($"Successfully read custom UDT: {customType}");
     }
     else
     {
         Console.WriteLine("Failed to decode ExtensionObject into the expected UDT.");
     }
 }
 else
 {
     Console.WriteLine("The result is not an ExtensionObject.");
 }

I have the defined the UDT_SemVer as follows:

 [DataContract(Namespace = "http://www.siemens.com/simatic-s7-opcua")]
 public class UDT_SemVer : IEncodeable, IJsonEncodeable
 {
     #region Constructors
     public UDT_SemVer()
     {
         Initialize();
     }

     [OnDeserializing]
     private void Initialize(StreamingContext context)
     {
         Initialize();
     }

     private void Initialize()
     {
         Major = 0;
         Minor = 0;
         Patch = 0;
     }
     #endregion

     #region Public Properties
     [DataMember(Name = "Major", IsRequired = true, Order = 1)]
     public byte Major { get; set; }

     [DataMember(Name = "Minor", IsRequired = true, Order = 2)]
     public byte Minor { get; set; }

     [DataMember(Name = "Patch", IsRequired = true, Order = 3)]
     public byte Patch { get; set; }
     #endregion

     #region IEncodeable Members
     public ExpandedNodeId TypeId => new ExpandedNodeId("nsu=http://www.siemens.com/simatic-s7-opcua;s=DT_\"UDT_SemVer\"");

     public ExpandedNodeId BinaryEncodingId => new ExpandedNodeId("nsu=http://www.siemens.com/simatic-s7-opcua;s=TE_\"UDT_SemVer\"");

     public ExpandedNodeId XmlEncodingId => new ExpandedNodeId(0);

     public void Encode(IEncoder encoder)
     {

         encoder.WriteByte("Major", Major);
         encoder.WriteByte("Minor", Minor);
         encoder.WriteByte("Patch", Patch);
     }

     public void Decode(IDecoder decoder)
     {
         Major = decoder.ReadByte("Major");
         Minor = decoder.ReadByte("Minor");
         Patch = decoder.ReadByte("Patch");
     }

     public bool IsEqual(IEncodeable encodeable)
     {
         if (encodeable is UDT_SemVer other)
         {
             return Major == other.Major && Minor == other.Minor && Patch == other.Patch;
         }
         return false;
     }

     public void EncodeJson(IJsonEncoder encoder)
     {
         encoder.WriteByte("Major", Major);
         encoder.WriteByte("Minor", Minor);
         encoder.WriteByte("Patch", Patch);
     }

     public void DecodeJson(IJsonDecoder decoder)
     {
         Major = decoder.ReadByte("Major");
         Minor = decoder.ReadByte("Minor");
         Patch = decoder.ReadByte("Patch");
     }

     public object Clone()
     {
         return (UDT_SemVer)this.MemberwiseClone();
     }

     public XmlQualifiedName XmlEncodingNamespace => new XmlQualifiedName("http://www.siemens.com/simatic-s7-opcua");

     public ExpandedNodeId JsonEncodingId => throw new NotImplementedException();
     #endregion
 }

The structure looks as follows on the PLC: image

And the type that got loaded from the complexTypeSystem = Opc.Ua.ComplexTypes.simatic-s7-opcua.3.UDT_SemVer

I hope this is enough info in order to help me out

Expected Behavior

I expect the extObject.Body to be able to be cast to a UDT_SemVer

Steps To Reproduce

No response

Environment

- OS: Windows 10
- Environment: Visual Studio 2022
- Runtime: .NET 8.0 LTS
- Nuget Version: Latest Stable
- Component: Opc.Ua.Client.ComplexTypes
- Server: Custom Server

Anything else?

No response