common/Hardware/PLC/Siemens/Client/TestbenchAdapter/TestbenchAdapter.cs
2026-04-23 17:50:07 +02:00

241 lines
6.5 KiB
C#

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<Exception>();
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<object>() { Value }, new List<string>() { Register });
}
catch (Exception ex)
{
return ex.Message;
}
return "";
}
public void WriteValue(object Value, string Register)
{
var RetryLeft = 4;
var exs = new List<Exception>();
while (RetryLeft >= 1)
{
try
{
if (!mySession.Connected)
{
mySession.Reconnect();
}
myClientHelperAPI.WriteValues(new List<object>() { Value }, new List<string>() { 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();
}
}
}