我们在 CodeSys中 建立一个OPC UA服务端,并把相关变量通过OPC UA的方式暴露出来。然后,我们会通过第三方成熟且免费的UaExpert客户端,对服务端变量进行访问;最后,我们会以编程的方式,自己写代码实现对服务端变量的监视和控制。

OPC UA 服务端建立

为了测试,让我们编写一个简单程序:

PROGRAM PLC_PRG
VAR
    prod : INT;
    a : INT;
    b: INT;
END_VAR

prod := a * b;

a := a + 1;

符号配置

首先,右击Application,依次选择Add Object/Symbol Configuration:

建立符号配置1.PNG

在弹出的符号配置对话框中,勾选 Support OPC UA features:

建立符号配置2.PNG

确认后,在弹出的Symbol Configuration标签页中,把要通过 OPC UA监控的变量勾选上即可。

注意:对应新增加的变量,要先点击Build,才会在符号配置表中呈现。

建立符号配置3.PNG

如果改变符号配置的话,会在下一次 download 或者 online change 时被传输到目标机器中。

到此为止,我们已经基本完成了 OPC UA 服务器上配置。但是客户端大概率是没法连接的,因为服务器并没有自身安全证书。这个证书的机制类似于https证书,用于标识自己是谁和加密通信。

OPC UA 服务器证书

打开菜单 View,点击 Security Screen菜单项:
安全屏.PNG

Security Screen标签页中,点击刷新按钮,选中具体设备,找到OPC UA Server项,如果有标注 Not Available,则表示目标机器还没有相应的证书:

安全屏-OPCUA服务器证书1.PNG

在选中OPC UA Server项的前提下,点击其左上角的create a new certificate on the device按钮,即可在目标机器上创建一个新的证书:

安全屏-OPCUA服务器证书2.PNG

在完成相应的证书配置后,我们可以把服务端证书导出到本地进行备份,在将来需要时(比如给目标设备刷机),可以再将备份的证书导入到设备中。

使用UaExpert客户端

为了简单起见,我们先用成熟的第三方客户端 UaExpert 来连接服务器。 UaExpert 是一款可以免费使用的 OPC UA GUI客户端。

建立连接

UaExpert在第一次启动的时候,会提示我们生成客户端证书。在尝试连接的时候,客户端选择连接类型为Basic256Sha256 – Sign & Encrypt (uatcp-uasc-uabinary),表示安全类型为签名和加密。

但这里有两个问题:

  1. 服务端的证书,是自签名的,客户端并不认可。所以要让客户端信任服务端证书。在第一次连接服务器的时候,会弹出一个对话框提示证书校验错误,点击临时接受这个服务器证书即可。或者我们也可以把服务端证书安装到本地系统中。
  2. 客户端的证书,也是自签名的,服务端也不认可。所以也要手动把客户端证书添加到目标服务器设备上的受信证书中。具体操作办法参见下面的动画:

建立连接.操作动画

建立连接.操作动画.gif

监控变量

监控变量.操作动画.gif

使用C#编程

// 创建一个应用配置对象,用于设置应用名称、唯一标识、类型、证书和安全策略
using Opc.Ua;
using Opc.Ua.Client;
using Opc.Ua.Configuration;

ApplicationConfiguration config = await PrepareOpcUaAppConfigAsync();

// 创建一个应用实例对象,用于检查证书
var application = new ApplicationInstance(config);
bool check = await application.CheckApplicationInstanceCertificate(false, 2048);
Console.WriteLine($"证书验证结果:{check}");


Session session = await CreateSessionAsync(config);
Console.WriteLine($"会话已创建");

// 读取节点
while (true)
{
    DataValue value = await session.ReadValueAsync(nodeId: "ns=4;s=|var|CODESYS Control Win V3 x64.Application.PLC_PRG.prod");
    Console.WriteLine("{0}, {1}, {2}", value.Value, value.SourceTimestamp, value.StatusCode);
}

其中,准备应用实例的实现为:

/// 准备OPC UA App Config
static async Task<ApplicationConfiguration> PrepareOpcUaAppConfigAsync()
{
    var config = new ApplicationConfiguration()
    {
        ApplicationName = "MyClient",
        ApplicationUri = Utils.Format(@"urn:{0}:MyClient", System.Net.Dns.GetHostName()),
        ApplicationType = ApplicationType.Client,
        SecurityConfiguration = new SecurityConfiguration
        {
            ApplicationCertificate = new CertificateIdentifier { StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\MachineDefault", SubjectName = "MyClientSubjectName" },
            TrustedIssuerCertificates = new CertificateTrustList { StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\UA Certificate Authorities" },
            TrustedPeerCertificates = new CertificateTrustList { StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\UA Applications" },
            RejectedCertificateStore = new CertificateTrustList { StoreType = @"Directory", StorePath = @"%CommonApplicationData%\OPC Foundation\CertificateStores\RejectedCertificates" },
            AutoAcceptUntrustedCertificates = true,
            RejectSHA1SignedCertificates = false,
            MinimumCertificateKeySize = 1024,
            NonceLength = 32,
        },
        TransportConfigurations = new TransportConfigurationCollection(),
        TransportQuotas = new TransportQuotas { OperationTimeout = 15000 },
        ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 },
        TraceConfiguration = new TraceConfiguration()
    };

    // 验证应用配置对象
    await config.Validate(ApplicationType.Client);

    // 设置证书验证事件,用于自动接受不受信任的证书
    if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
    {
        config.CertificateValidator.CertificateValidation += (s, e) => { e.Accept = (e.Error.StatusCode == StatusCodes.BadCertificateUntrusted); };
    }

    return config;
}

创建session的实现为:

static async Task<Session> CreateSessionAsync(ApplicationConfiguration config)
{
    // 创建一个会话对象,用于连接到 OPC UA 服务器
    var discoveryUrl = "opc.tcp://DESKTOP-7PT7CEQ:4840";
    EndpointDescription epDescription = CoreClientUtils.SelectEndpoint(discoveryUrl, true);
    EndpointConfiguration epConfiguration = EndpointConfiguration.Create(config);
    ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, epDescription, epConfiguration);
    Session session = await Session.Create(config, endpoint, false, false, "DataCollector", 60000, new UserIdentity("teset-runtime", "123456"), null);

    return session;
}

标签: CoDeSys, PLC

添加新评论