using Opc.Ua; using Opc.Ua.Client; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; namespace Xylem.Common.Hardware.Plc.Siemens.Client.TestbenchAdapter { [Guid("C027D79A-7133-404A-8015-6F5D626B5FA1"), ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] public interface ITestbenchAdapter : IDisposable { void Disconnect(); void Connect(string url); dynamic ReadValueVar(string Register); void WriteValue(object Value, string Register); string WriteValueErrorMsg(object Value, string Register); } [Guid("A20D9680-7DFB-4CBD-AB88-7C7ACFE34D36"), ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] public interface ITestbenchAdapterEvents { void onErrorOccur(string description, string source); void onLog(string text, string source); } [Guid("01565BB8-477E-49FC-834B-5C99C16F2883"), ComVisible(true), ClassInterface(ClassInterfaceType.None), ComSourceInterfaces(typeof(ITestbenchAdapterEvents))] public class Vb6Testbench : ITestbenchAdapter { private Session mySession; private Subscription mySubscription; private UAClientHelperAPI myClientHelperAPI; private EndpointDescription mySelectedEndpoint; private string myUrl = ""; public Vb6Testbench() { myClientHelperAPI = new UAClientHelperAPI(); } [ComVisible(false)] public delegate void ErrorHandler(string description, string source); public event ErrorHandler onErrorOccur; [ComVisible(false)] public delegate void LogHandler(string text); public event LogHandler onLog; public void Setup(string url) { myUrl = url; } public void Disconnect() { if (mySession != null && !mySession.Disposed) { try { mySubscription.Delete(true); } catch { //ignore ; } myClientHelperAPI.Disconnect(); mySession = myClientHelperAPI.Session; } } public void Connect(string tmpurl) { Setup(tmpurl); if (tmpurl != "none") { EndpointDescriptionCollection endpoints = myClientHelperAPI.GetEndpoints(myUrl); foreach (var endpoint in endpoints) { if (mySession == null || mySession.Disposed) { try { myClientHelperAPI.KeepAliveNotification += new KeepAliveEventHandler(Notification_KeepAlive); //myClientHelperAPI.CertificateValidationNotification += new CertificateValidationEventHandler(Notification_ServerCertificate); myClientHelperAPI.Connect(endpoint, false, "", ""); mySession = myClientHelperAPI.Session; } catch (Exception ex) { onErrorOccur?.Invoke(ex.Message, ex.StackTrace); } } } } } private void Notification_KeepAlive(Session sender, KeepAliveEventArgs e) { try { // check for events from discarded sessions. if (!Object.ReferenceEquals(sender, mySession)) { return; } // check for disconnected session. if (ServiceResult.IsBad(e.Status)) { // try reconnecting using the existing session state mySession.Reconnect(); } } catch (Exception ex) { onErrorOccur?.Invoke(ex.Message, ex.StackTrace); } } public dynamic ReadValueVar(string Register) { var RetryLeft = 4; var exs = new List(); if (!mySession.Connected) { mySession.Reconnect(); } while (RetryLeft >= 1) { try { return myClientHelperAPI.ReadValue(Register); } catch (Exception ex) { exs.Add(ex); if (!mySession.Connected) { mySession.Reconnect(); } else { RetryLeft = 0; } } RetryLeft = RetryLeft--; } if (exs.Any()) { throw new AggregateException("Cannot Read Value from OPC", exs); } else { throw new ApplicationException("Cannot Read Value from OPC"); } } public string WriteValueErrorMsg(object Value, string Register) { try { if (!mySession.Connected) { mySession.Reconnect(); } myClientHelperAPI.WriteValues(new List() { Value }, new List() { Register }); } catch (Exception ex) { return ex.Message; } return ""; } public void WriteValue(object Value, string Register) { var RetryLeft = 4; var exs = new List(); while (RetryLeft >= 1) { try { if (!mySession.Connected) { mySession.Reconnect(); } myClientHelperAPI.WriteValues(new List() { Value }, new List() { Register }); break; } catch (Exception ex) { exs.Add(ex); } RetryLeft = RetryLeft--; } if (exs.Any()) { throw new AggregateException("writeValue to OPC failed", exs); } } public void Dispose() { Disconnect(); } } }