일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- JOIN DBMS별 차이점
- lock
- ssh 접속 실패 로그
- Jar 경로
- SCM
- OPC UA Client Write
- MS-SQL
- c# 강의
- Gradle Jar
- delete truncate 차이
- Xamarin
- ssh log
- OPC Write
- kafka listener
- Java 버전 여러개 사용
- OPC UA
- table용량
- OPC DA
- Gradle JDK Path
- c#
- Gradle 빌드 오류
- ssh 접속 로그
- CPU 사용량
- OPC UA Write
- 스마트공장
- mssql table 용량
- kafka
- OPC
- MSSQL
- springboot Gradle
- Today
- Total
IT’s Ha
[OPC] 4. C#을 통한 OPC UA Client 개발 본문
안녕하세요. 이번 포스팅은 OPC UA Client를 개발 포스팅을 진행하겠습니다.
이번 포스팅의 개발 환경은 C#을 통하여 개발하였고, .NET 7.0 그리고 Winform에서 구현하였습니다. 그리고 이전 포스팅에 대한 내용이 이어서 KepServer에 연결하여 테스트 하겠습니다.
2023.03.15 - [OPC] - [OPC] 3. OPC UA와 PLC 통신 예제
1. 프로젝트 생성
프로젝트 Winform으로 생성을 해주세요. 그리고 프로젝트 우클릭 후 Nuget패키지에서 OPCFoundation에서 제공하는 OPC.UA와 OPC.UA.Client를 설치 해주세요.
2. 화면 구성
디자인 파일에는 ListView를 넣어 LogTime과 Message 항목을 추가 하였습니다.
3. 소스 구현
이번 소스 예제는 Security를 제외하고 구현하였습니다. User 체크 그리고 인증서 체크가 없이 간단한 Client 프로그램을 작성하였습니다.
public partial class Form1 : Form
{
private Subscription _subscription;
public Form1()
{
InitializeComponent();
}
private async void Connect()
{
try
{
//연결 Url 설정 (KepServer - Ua Configration 에서 확인 가능)
string endpointUrl = "opc.tcp://localhost:49320";
//OPC UA Client 설정 시작
Opc.Ua.ApplicationConfiguration config = new Opc.Ua.ApplicationConfiguration()
{
ApplicationName = "OPCClientTest",
ApplicationUri = Utils.Format(@"urn:{0}:OPCClientTest", System.Net.Dns.GetHostName()),
ApplicationType = ApplicationType.Client,
SecurityConfiguration = new SecurityConfiguration
{
ApplicationCertificate = new CertificateIdentifier(),
TrustedPeerCertificates = new CertificateTrustList (),
RejectedCertificateStore = new CertificateStoreIdentifier(),
AutoAcceptUntrustedCertificates = true,
RejectSHA1SignedCertificates = false
},
TransportConfigurations = new TransportConfigurationCollection(),
TransportQuotas = new TransportQuotas { OperationTimeout = 15000 },
ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 },
TraceConfiguration = new TraceConfiguration(),
}
//연결 시작(Session 연결)
var selectedEndpoint = CoreClientUtils.SelectEndpoint(endpointUrl, useSecurity: false);
var endconf = new ConfiguredEndpoint(null, selectedEndpoint, EndpointConfiguration.Create(config));
var session = Session.Create(config, endconf, true, "session", 1000, null, null).GetAwaiter().GetResult();
//모니터링 설정
_subscription = new Subscription(session.DefaultSubscription)
{
PublishingEnabled = true,
PublishingInterval = 500,
};
// 모니터링 할 Item List
var list = new List<MonitoredItem> { };
// List 추가
list.Add(new MonitoredItem()
{
DisplayName = "Tag1",
StartNodeId = "ns=2;s=Channel.Device1.Tag1"
});
list.Add(new MonitoredItem()
{
DisplayName = "Tag2",
StartNodeId = "ns=2;s=Channel.Device1.Tag2"
});
list.Add(new MonitoredItem()
{
DisplayName = "Tag3",
StartNodeId = "ns=2;s=Channel.Device1.Tag3"
});
//각각의 Item에 Event추가
list.ForEach(i => i.Notification += new MonitoredItemNotificationEventHandler(OnNotification));
//Subscription에 List 추가
_subscription.AddItems(list);
//Session에 Subscription 추가
session.AddSubscription(_subscription);
//Subscription 생성
_subscription.Create();
}
catch(Exception ex)
{
}
}
//모니터링
private void OnNotification(MonitoredItem item, MonitoredItemNotificationEventArgs e)
{
try
{
MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
foreach (var value in item.DequeueValues())
{
this.Invoke(new MethodInvoker(delegate ()
{
//상태가 정상 일 경우
if (StatusCode.IsGood(value.StatusCode))
{
if (EventList.Items.Count > 100)
EventList.Items.RemoveAt(EventList.Items.Count - 1);
EventList.Items.Insert(0, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
EventList.Items[0].SubItems.Add("[Value] : " + value.Value.ToString() + ", ID:" + item.DisplayName);
}
//상태가 정상 아닐 경우
else
{
if (EventList.Items.Count > 100)
EventList.Items.RemoveAt(EventList.Items.Count - 1);
EventList.Items.Insert(0, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
EventList.Items[0].SubItems.Add("[STATUS] : " + value.StatusCode.ToString() + ", ID:" + item.DisplayName);
}
}));
}
}
catch (Exception ex)
{}
}
//Form Load 이벤트 추가
private void Form1_Load(object sender, EventArgs e)
{
Connect();
}
}
4. 결과
정상적으로 값을 받아오는 것을 확인 할 수 있습니다. 위는 Winform의 예제이지만 C#으로 구성되어있는 WFP나 ASP.NET등에서도 쉽게 적용이 가능합니다. 궁금하신 점이나 잘못된 점은 메일 또는 댓글에 남겨 주시면 수정 또는 답변 드리도록 하겠습니다. 감사합니다.
※ 2024-02-15 OnNotification 함수 문제로 수정
- private void OnNotification(onitoredItem item, MonitoredItemNotificationEventArgs e) ->
private void OnNotification(MonitoredItem item, MonitoredItemNotificationEventArgs e)
'OPC' 카테고리의 다른 글
[OPC] 5. C#을 통한 OPC UA Client 개발 - Write (1) | 2024.02.15 |
---|---|
[OPC] 3. OPC UA와 PLC 통신 예제 (7) | 2023.03.15 |
[OPC] 2. OPC UA와 OPC DA의 차이, PLC와 OPC통신 (0) | 2023.03.15 |
[OPC] 1. OPC UA 서버의 이해 (0) | 2023.03.08 |
[OPC]OPC (0) | 2023.02.15 |