OPC UA获取特定数据类型的默认值

时间:2017-09-19 14:15:05

标签: c# .net github opc opc-ua

我正在使用GitHub上提供的Microsoft的OpenSource OPC UA SDK并使用它对客户端进行编程。 由于缺少文档,我很难将服务器已知的自定义数据类型导入我的客户端。我也需要它们用于几个方法调用,例如呼叫" ScanStart"使用特定类型的参数" ScanSettings"它仅由服务器提供。是否有可能以简单的方式获得具有默认值的这种(struct)数据类型? 有人知道如何提供一个例子吗? 我找到了要执行的操作的说明,但没有找到如何使用Microsoft SDK完成的操作:

所以客户必须这样做 - 读取DataTypeDictionaries并解析该值 - 浏览地址空间以将编码ID映射到结构信息 - 对于二进制编码的ExtensionObject:从TypeId中查找结构信息并解释。

祝你好运

1 个答案:

答案 0 :(得分:0)

下面是一个调用类型为" Vector"的参数的方法的示例,它是由UnifiedAutomation的演示服务器" UaCppServer"提供的自定义结构类型。

我首先使用UaExpert来发现DataTypeId,EncodingId,ObjectId,MethodId,以及猜测结构。

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Opc.Ua;
using Opc.Ua.Client;
using System.Security.Cryptography.X509Certificates;

namespace NetCoreConsoleClient
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine(".Net Core OPC UA Console Client sample");
            string endpointURL;
            if (args.Length == 0)
            {
                // use Unified Automation's UaCPPServer server 
                endpointURL = "opc.tcp://" + Utils.GetHostName() + ":48010";
            }
            else
            {
                endpointURL = args[0];
            }
            try
            {
                Task t = ConsoleSampleClient(endpointURL);
                t.Wait();
            }
            catch (Exception e)
            {
                Console.WriteLine("Exit due to Exception: {0}", e.Message);
            }
        }

        public static async Task ConsoleSampleClient(string endpointURL)
        {
            Console.WriteLine("1 - Create an Application Configuration.");
            Utils.SetTraceOutput(Utils.TraceOutput.DebugAndFile);
            var config = new ApplicationConfiguration()
            {
                ApplicationName = "UA Core Sample Client",
                ApplicationType = ApplicationType.Client,
                ApplicationUri = "urn:" + Utils.GetHostName() + ":OPCFoundation:CoreSampleClient",
                SecurityConfiguration = new SecurityConfiguration
                {
                    ApplicationCertificate = new CertificateIdentifier
                    {
                        StoreType = "X509Store",
                        StorePath = "CurrentUser\\UA_MachineDefault",
                        SubjectName = "UA Core Sample Client"
                    },
                    TrustedPeerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Applications",
                    },
                    TrustedIssuerCertificates = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/UA Certificate Authorities",
                    },
                    RejectedCertificateStore = new CertificateTrustList
                    {
                        StoreType = "Directory",
                        StorePath = "OPC Foundation/CertificateStores/RejectedCertificates",
                    },
                    NonceLength = 32,
                    AutoAcceptUntrustedCertificates = true
                },
                TransportConfigurations = new TransportConfigurationCollection(),
                TransportQuotas = new TransportQuotas { OperationTimeout = 15000 },
                ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 }
            };

            await config.Validate(ApplicationType.Client);

            bool haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (!haveAppCertificate)
            {
                Console.WriteLine("    INFO: Creating new application certificate: {0}", config.ApplicationName);

                X509Certificate2 certificate = CertificateFactory.CreateCertificate(
                    config.SecurityConfiguration.ApplicationCertificate.StoreType,
                    config.SecurityConfiguration.ApplicationCertificate.StorePath,
                    null,
                    config.ApplicationUri,
                    config.ApplicationName,
                    config.SecurityConfiguration.ApplicationCertificate.SubjectName,
                    null,
                    CertificateFactory.defaultKeySize,
                    DateTime.UtcNow - TimeSpan.FromDays(1),
                    CertificateFactory.defaultLifeTime,
                    CertificateFactory.defaultHashSize,
                    false,
                    null,
                    null
                    );

                config.SecurityConfiguration.ApplicationCertificate.Certificate = certificate;

            }

            haveAppCertificate = config.SecurityConfiguration.ApplicationCertificate.Certificate != null;

            if (haveAppCertificate)
            {
                config.ApplicationUri = Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate);

                if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
                {
                    config.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);
                }
            }
            else
            {
                Console.WriteLine("    WARN: missing application certificate, using unsecure connection.");
            }

            Console.WriteLine("2 - Discover endpoints of {0}.", endpointURL);
            var selectedEndpoint = CoreClientUtils.SelectEndpoint(endpointURL, haveAppCertificate);
            Console.WriteLine("    Selected endpoint uses: {0}",
                selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1));

            Console.WriteLine("3 - Create a session with OPC UA server.");
            var endpointConfiguration = EndpointConfiguration.Create(config);
            var endpoint = new ConfiguredEndpoint(null, selectedEndpoint, endpointConfiguration);
            var session = await Session.Create(config, endpoint, false, ".Net Core OPC UA Console Client", 60000, new UserIdentity(new AnonymousIdentityToken()), null);


            Console.WriteLine("4 - Call VectorAdd method with structure arguments.");
            EncodeableFactory.GlobalFactory.AddEncodeableType(typeof(Vector));
            var v1 = new Vector { X = 1.0, Y = 2.0, Z = 3.0 };
            var v2 = new Vector { X = 1.0, Y = 2.0, Z = 3.0 };
            var outArgs = session.Call(NodeId.Parse("ns=2;Demo.Method"), NodeId.Parse("ns=2;s=Demo.Method.VectorAdd"), new ExtensionObject(v1), new ExtensionObject(v2) );
            var result = ExtensionObject.ToEncodeable((ExtensionObject)outArgs[0]) as Vector;

            Console.WriteLine($"  {v1}");
            Console.WriteLine($"+ {v2}");
            Console.WriteLine(@"  ------------------");
            Console.WriteLine($"  {result}");

            Console.WriteLine("8 - Press any key to exit...");
            Console.ReadKey(true);
        }

        private static void CertificateValidator_CertificateValidation(CertificateValidator validator, CertificateValidationEventArgs e)
        {
            Console.WriteLine("Accepted Certificate: {0}", e.Certificate.Subject);
            e.Accept = (e.Error.StatusCode == StatusCodes.BadCertificateUntrusted);
        }

        public class Vector : EncodeableObject
        {
            public double X { get; set; }

            public double Y { get; set; }

            public double Z { get; set; }

            public override ExpandedNodeId TypeId => ExpandedNodeId.Parse("nsu=http://www.unifiedautomation.com/DemoServer/;i=3002");

            public override ExpandedNodeId BinaryEncodingId => ExpandedNodeId.Parse("nsu=http://www.unifiedautomation.com/DemoServer/;i=5054");

            public override ExpandedNodeId XmlEncodingId => NodeId.Null;

            public override void Encode(IEncoder encoder)
            {
                encoder.WriteDouble("X", this.X);
                encoder.WriteDouble("Y", this.Y);
                encoder.WriteDouble("Z", this.Z);
            }

            public override void Decode(IDecoder decoder)
            {
                this.X = decoder.ReadDouble("X");
                this.Y = decoder.ReadDouble("Y");
                this.Z = decoder.ReadDouble("Z");
            }

            public override string ToString() => $"{{ X={this.X}; Y={this.Y}; Z={this.Z}; }}";
        }
    }
}