Back to top

OPC Client 예제 (Softing Opc Ua Client)

작성날짜 2024/12/02

이 글에서는 OPC 서버로는 Kep ServerEX6를 사용하고 클라이언트는 Softing OPC UA package를 사용한다.


OPC 서버 설정


PLC 통신 및 장비 설정은 되어 있다 치고 OPC 서버 태그 설정부터 해보자.


article_img_3_rte_image_1.png


article_img_0_rte_image_3.png


article_img_1_rte_image_6.png


위에서부터 bool, word(uint16), sbyte[]형태의 데이터를 받게 된다.


주소 설정


각 태그를 편하게 접근하기 위해 정적 클래스로 선언해주자.


 public static class PlcNodeAddress
 {
     #region PLC Node String
     public const string SignalTest = "ns=2;s=S7-1500.Tester.Signal Test";
     public const string TestValue = "ns=2;s=S7-1500.Tester.Test Value";
     public const string TestString = "ns=2;s=S7-1500.Tester.Test String";
    #endregion
}


PLC 연결


PLC 연결은 설정 객체 생성, UaApplication 생성, Session 생성, 연결의 순서를 거친다.


// 설정 생성
ApplicationConfiguration configuration = CreateAplicationConfiguration();
// Application 생성
m_application = UaApplication.Create(configuration).Result;
// Session 생성
m_session = CreateSession("UaBinaryNoSecuritySession", ServerUrl, MessageSecurityMode.None, SecurityPolicy.None, MessageEncoding.Binary, new UserIdentity());
// 연결
await m_session.ConnectAsync(false, true);


// 설정 생성
// Softing에서 제공해주는 기본 설정 메소드
private ApplicationConfiguration CreateAplicationConfiguration()
{
    Debugger.Report("Creating ApplicationConfiguration for current UaApplication...");
    ApplicationConfiguration configuration = new ApplicationConfiguration();

    configuration.ApplicationName = "UA Sample Client";
    configuration.ApplicationType = ApplicationType.Client;
    configuration.ApplicationUri = $"urn:{Utils.GetHostName()}:OPCFoundation:SampleClient";
    configuration.TransportConfigurations = new TransportConfigurationCollection();
    configuration.TransportQuotas = new TransportQuotas { OperationTimeout = 150000 };
    configuration.ClientConfiguration = new ClientConfiguration();

    ClientToolkitConfiguration clientTkConfiguration = new ClientToolkitConfiguration();
    clientTkConfiguration.DiscoveryOperationTimeout = 10000;
    configuration.UpdateExtension<ClientToolkitConfiguration>(new System.Xml.XmlQualifiedName("ClientToolkitConfiguration"), clientTkConfiguration);

    configuration.TraceConfiguration = new TraceConfiguration()
    {
        OutputFilePath = @"%CommonApplicationData%\Softing\OpcUaNetStandardToolkit\logs\SampleClient.log",
        TraceMasks = 519
    };

    configuration.SecurityConfiguration = new SecurityConfiguration
    {
        ApplicationCertificate = new CertificateIdentifier
        {
            StoreType = CertificateStoreType.Directory,
            StorePath = @"%CommonApplicationData%\Softing\OpcUaNetStandardToolkit\pki\own"
        },
        TrustedPeerCertificates = new CertificateTrustList
        {
            StoreType = CertificateStoreType.Directory,
            StorePath = @"%CommonApplicationData%\Softing\OpcUaNetStandardToolkit\pki\trusted",
        },
        TrustedIssuerCertificates = new CertificateTrustList
        {
            StoreType = CertificateStoreType.Directory,
            StorePath = @"%CommonApplicationData%\Softing\OpcUaNetStandardToolkit\pki\issuer",
        },
        RejectedCertificateStore = new CertificateTrustList
        {
            StoreType = CertificateStoreType.Directory,
            StorePath = @"%CommonApplicationData%\Softing\OpcUaNetStandardToolkit\pki\rejected",
        },
        AutoAcceptUntrustedCertificates = true
    };

    return configuration;
}


// 세션 생성
private ClientSession? CreateSession(string sessionName, string serverUrl, MessageSecurityMode securityMode, SecurityPolicy securityPolicy, MessageEncoding messageEncoding, UserIdentity userId)
{
    try
    {
        Debugger.Report($"Creating the OPC session {sessionName}...");
        // Create the Session object.
        ClientSession session = m_application.CreateSession(serverUrl, securityMode, securityPolicy, messageEncoding, userId);

        session.SessionName = sessionName;
        return session;
    }
    catch (Exception ex)
    {
        Debugger.Report(ex.Message, DebugType.Defualt);
        return null;
    }
}


통신 예제


읽어 오기


public async Task<bool> ReadSignalTest()
{
    if (m_session == null)
    {
        return;
    }

    try
    {
        NodeId nodeToRead = new NodeId(PlcNodeAddress.SignalTest);
        DataValue value = await m_session.ReadValueAsync(nodeToRead).ConfigureAwait(false);
        if (value.Value != null)
        {
            return (bool)node.GetValue(typeof(bool));
        }
    }
    catch (Exception ex)
    {
        Debugger.Report(ex.Message, DebugType.PLC_Communication);
    }
retrun false;
}


// word의 경우
DataValue value = await m_session.ReadValueAsync(nodeToRead).ConfigureAwait(false);
(UInt16)node.GetValue(typeof(UInt16));


// byte array의 경우
DataValue node = await m_session.ReadValueAsync(nodeToRead).ConfigureAwait(false);​
var received = (sbyte[])node.GetValue(typeof(sbyte[]));
var byteArr = (byte[])(Array)received;
var result = Encoding.UTF8.GetString(byteArr);

byte array는 sbyte array로 받아서 byte array로 캐스트 후 인코딩을 해줘야 string을 얻을 수 있다.



An unhandled error has occurred. Reload 🗙