OPC Client 예제 (Softing Opc Ua Client)
작성날짜 2024/12/02
이 글에서는 OPC 서버로는 Kep ServerEX6를 사용하고 클라이언트는 Softing OPC UA package를 사용한다.
OPC 서버 설정
PLC 통신 및 장비 설정은 되어 있다 치고 OPC 서버 태그 설정부터 해보자.
위에서부터 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을 얻을 수 있다.