using Aurora.Api; using Aurora.Util.HislogPlus; using Hermes; using Opc.Ua; using Opc.Ua.Client; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace AuroraLaser.Trumpf { public class TrumpfCore : ILaser { private readonly Logger log = new Logger("TrumpfCore"); private Session _session = null; private Subscription _subscription = null; private string strServerAddress = @"opc.tcp://172.29.3.1:4840"; private string strID = "060"; private string strPW = "060a342"; public int Open(LaserConfig Config) { if(!CreateSession()) { log.I("Session Create Fail"); return E2.ABORTED; } if(!CreateSubScription()) { } ExplorerNodes(new NodeId("ns=2;s=Device")); // 세션 double keepAliveInterval = _session.SessionTimeout * 0.8; // 모니터링 설정 _subscription = new Subscription(_session.DefaultSubscription) { PublishingEnabled = true, PublishingInterval = 50, // TruDisk 2021 최소값은 50ms }; return E1.OK; } private bool CreateSubScription() { if (_subscription != null) { if(_session.RemoveSubscription(_subscription)) _subscription = null; } // 모니터링 설정 _subscription = new Subscription(_session.DefaultSubscription) { PublishingEnabled = true, PublishingInterval = 50, // TruDisk 2021 최소값은 50ms }; var listRead = new List { }; listRead.Add(new MonitoredItem() { DisplayName = "Word 03", StartNodeId = "ns=2;s=Activation.MPI-Slot01.Input.Word03", // 단위는 ms, 100ms씩 증가, 0은 Server에서 가능한 가장 빠른 Interval(100ms)로 Sampling SamplingInterval = 100, }); listRead.Add(new MonitoredItem() { DisplayName = "Word 03", StartNodeId = "ns=2;s=PDCounter.OperatingHours", // 단위는 ms, 100ms씩 증가, 0은 Server에서 가능한 가장 빠른 Interval(100ms)로 Sampling SamplingInterval = 2000, }); listRead.ForEach(i => i.Notification += new MonitoredItemNotificationEventHandler(OnNotificationRead)); // Subscription에 List 추가 _subscription.AddItems(listRead); // Session에 Subscription 추가 _session.AddSubscription(_subscription); // Subscription 생성 _subscription.Create(); return true; } private string retMonitoring; private void OnNotificationRead(MonitoredItem item, MonitoredItemNotificationEventArgs e) { try { MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification; foreach (var value in item.DequeueValues()) { // 상태가 정상일 경우 if (StatusCode.IsGood(value.StatusCode)) { retMonitoring = value.Value.ToString(); } } } catch (Exception ex) { throw ex; } } private bool CreateSession() { var config = new ApplicationConfiguration() { ApplicationName = "TrumpfOpcUaClient", ApplicationType = ApplicationType.Client, SecurityConfiguration = new SecurityConfiguration { ApplicationCertificate = new CertificateIdentifier(), AutoAcceptUntrustedCertificates = true }, TransportQuotas = new TransportQuotas { OperationTimeout = 15000 }, ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 } }; config.Validate(ApplicationType.Client); var selectedEndpoint = CoreClientUtils.SelectEndpoint(strServerAddress, useSecurity: true); var endpoint = new ConfiguredEndpoint(null, selectedEndpoint, EndpointConfiguration.Create(config)); var userIdentity = new UserIdentity(strID, strPW); _session = Session.Create(config, endpoint, false, "TrumpfLaserSession", 60000, userIdentity, null).Result; _session.KeepAlive += SessionKeepAlive; if (_session is null) return false; return true; } private void SessionKeepAlive(ISession session, KeepAliveEventArgs e) { if (ServiceResult.IsBad(e.Status)) { session.CloseAsync().Wait(); } } public void DisConnect() { if (_session != null && _session.Connected) { _session.CloseAsync(); _session = null; } } public void ExplorerNodes(NodeId startNode) { // 노드 트리 탐색 시작 BrowseTree(_session, startNode, 0); } private void BrowseTree(Session session, NodeId nodeId, int level) { ReferenceDescriptionCollection references; byte[] continuationPoint; session.Browse(null, null, nodeId, 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Object | (uint)NodeClass.Variable, out continuationPoint, out references); foreach (var rd in references) { // 들여쓰기와 함께 출력 string log = $"{new string(' ', level * 2)} >> {rd.DisplayName.Text} (NodeId: {rd.NodeId})"; Debug.WriteLine(log); if (!rd.NodeId.IsAbsolute) { BrowseTree(session, ExpandedNodeId.ToNodeId(rd.NodeId, session.NamespaceUris), level + 1); } } } public bool GetConnected() => _session.Connected; public string GetControlMode() { throw new NotImplementedException(); } public bool GetControlModeSetStatus() { throw new NotImplementedException(); } public string GetData(int nTarget) { throw new NotImplementedException(); } public bool GetEmissionStatus() { throw new NotImplementedException(); } public bool GetInitCommunication() { throw new NotImplementedException(); } public bool GetLaserError() { throw new NotImplementedException(); } public bool GetLaserReady() { throw new NotImplementedException(); } public bool GetLaserResetSetBitStatus() { throw new NotImplementedException(); } public bool GetLaserStartSetBitStatus() { throw new NotImplementedException(); } public bool GetPilotLaserSetBitStatus() { throw new NotImplementedException(); } public bool GetPilotLaserStatus() { throw new NotImplementedException(); } public string GetPowerCenter() { throw new NotImplementedException(); } public string GetPowerRing() { throw new NotImplementedException(); } public bool GetStartLaserSetBitStatus() { throw new NotImplementedException(); } public bool GetWariningStatus() { throw new NotImplementedException(); } public int LaserOff() { int setValue = 5; var writeValue = new WriteValue { NodeId = new NodeId("programNo..."), AttributeId = Attributes.Value, Value = new DataValue { Value = setValue, StatusCode = StatusCodes.Good, ServerTimestamp = DateTime.MinValue, SourceTimestamp = DateTime.MinValue } }; var writeValues = new WriteValueCollection { writeValue }; StatusCodeCollection results; DiagnosticInfoCollection diagnosticInfos; _session.Write(null, writeValues, out results, out diagnosticInfos); var ret = results[0]; return E1.OK; } public int LaserOn() { try { var value = _session.ReadValue(new NodeId("ns=2;s=PulseData.PulsePowerNominal")); var timeout = _session.SessionTimeout; return 0; } catch (Exception) { return 0; } } public int PilotLaserOff() { throw new NotImplementedException(); } public int PilotLaserOn() { throw new NotImplementedException(); } public int SetData(int nTarget, int value) { throw new NotImplementedException(); } } }