Professional OPC
Development Tools

logos

A way to subscribe multi-items node that may change (add, delete, update each one) and get the list of change

More
11 May 2015 07:41 - 11 May 2015 08:09 #3111 by g.aino
Thank you for your reply,
the Vendor of server side has assured us that this function is supplied.
Thinking about this problem I found another workaround, since we're in contact with the vendor we can try to ask him if it's possible to supply a special node with the update list of AIS items. In this case we can subscrive this node and intercept every new entry or items deleting simply comparing with previous state.
I hope this work fine otherwise is hard work to find other partner with suitable functionality\specs .
Thank you
Last edit: 11 May 2015 08:09 by g.aino.

Please Log in or Create an account to join the conversation.

More
10 May 2015 17:04 #3105 by support
Dear Sir,

OPC UA, in general, allows to subscribe to events arising from changes in server's address space. But that only works if 1) the UA server supports it, and 2) the UA client supports it.

Unfortunately, QuickOPC dos not support it. And, I am not sure whether your server does - you will need to check with the vendor.

The EasyAEClient is for OPC "Classic" specs, therefore if you have an OPC UA server, it won't help you; in addition, normally the OPC-A&E clients do not report their address space changes through this interface anyway, its purpose is different.

The only workaround to his would be to periodically call the "browse" methods on parts of the address space you want to monitor, compare the old and new nodes, and act upon the differences. Obviously this is quite inefficient compared to change-based reporting. Whether or not such inefficiency would be acceptable, depends on the concrete application at hand.

Best regards
The following user(s) said Thank You: g.aino

Please Log in or Create an account to join the conversation.

More
08 May 2015 14:11 - 08 May 2015 14:12 #3103 by g.aino
Wainting your kindly reply ...

I found a pobable way that consist to use the "EasyAEClient" class but, for me, not enough documented.
public static void Main()
{
	using (var easyAEClient = new EasyAEClient())
	{
		var eventHandler = new EventHandler<EasyAENotificationEventArgs>(easyAEClient_Notification);
		easyAEClient.Notification += eventHandler;
 
		int handle = easyAEClient.SubscribeEvents("", "OPCLabs.KitEventServer.2", 1000);
 
		Console.WriteLine("Processing event notifications for 1 minute...");
		Thread.Sleep(60 * 1000);
 
		easyAEClient.UnsubscribeEvents(handle);
	}
}
 
// Notification event handler
static void easyAEClient_Notification([NotNull] object sender, [NotNull] EasyAENotificationEventArgs e)
{
	if (e.Event != null) 
		Console.WriteLine(e.Event.Message);
}

what kind of information I can supply to the second parameter of SubscribeEvents() method?

To satisfy our needed to got informations without subscribe we use "EasyUAClient" that we initialize with the following code:
public static EasyUAClient EasyUAClientInstance = new EasyUAClient()
{
	Isolated = true,
	IsolatedParameters =
	{
		Session =
		{
			CertificateAcceptancePolicy = { AcceptAnyCertificate = true, AllowUserAcceptCertificate = false },
			EndpointSelectionPolicy =
			{
				AllowedMessageSecurityModes = UAMessageSecurityModes.SecurityNone,
				EnforceSameSite = true
			},
			UserIdentity =
			{
				// Valori di default sovrascritti dopo
				UserNameTokenInfo = { UserName = "gst", Password = "pw" }
			},
			SelectBestEndpoint = true,
			// Valori di default sovrascritti dopo
			SessionConnectTimeout = 20000
		},
	}
};
 
/*
	serverURLAddress = opc.tcp://test.domainServer.com
	port = 4123
*/
 
private static bool InstanziateEasyUAClient(string serverURLAddress, int port,
											int sessionConnectTimeout, int threadRefreshMillisec,
											string userName, string password)
{
	bool ok = false;
	int millisectoHoldOPCUAConnection = threadRefreshMillisec;
	try
	{
		#region Assegnazione Parametri da configurazione
		EasyUAClientInstance.IsolatedParameters.Session.UserIdentity.UserNameTokenInfo
			= new UserNameTokenInfo()
			{
				UserName = userName,
				Password = password
			};
		// Segue parametro: Tempo entro il quale NON VERRA' FATTO LogOut e si manterrà la connessione (aumentato del 60%)
		millisectoHoldOPCUAConnection = millisectoHoldOPCUAConnection + (int)Math.Ceiling(millisectoHoldOPCUAConnection * 0.6);
		EasyUAClientInstance.IsolatedParameters.Session.HoldPeriod = millisectoHoldOPCUAConnection;
		if (sessionConnectTimeout > 0)
		{
			EasyUAClientInstance.IsolatedParameters.Session.SessionTimeout = sessionConnectTimeout;
		}
		m_ServerURLEasyUAClient = string.Format("{0}:{1}", serverURLAddress, port);
		#endregion
 
		// Event Handler di tutto quel che accade nell'interazione col Server OPC UA
		EasyUAClient.LogEntry += EasyUAClient_LogEntry;
		ok = true;
	}
	catch (Exception ex)
	{
		ok = false;
		m_logger.Error("InstanziateEasyUAClient() '{0}'\r\n" +
						"Other info: serverURLAddress= '{1}', OPCUA SessionTimeOut = '{2}', OPCUA HoldPeriod = '{3}'\r\n{4}\r\n",
						ex.Message, serverURLAddress + ":" + port, sessionConnectTimeout, millisectoHoldOPCUAConnection, ex.StackTrace);
	}
	return ok;
}
 
// using  the   EasyUAClientInstance:
 
	UANodeId nodeId = new UANodeId(CommonNamespaceURIString, strNodeIdIdentifier); 
// Where:   CommonNamespaceURIString="http://domainServer.com/UAComServer/"
//          strNodeIdIdentifier = "IMO1234567/Meteorology/Wind/Angle";
    UANodeElementCollection nodeElementCollection = EasyUAClientInstance.BrowseDataNodes(MainUAEndpointDescriptor, nodeId);
// Where:    MainUAEndpointDescriptor="opc.tcp://test.domainServer.com:4123"
 
	UANodeElementCollection nodeElementCollection = EasyUAClientInstance.BrowseDataNodes(MainUAEndpointDescriptor, nodeId);

Summarizing:
1. EasyAEClient is the way for our goals?
2. What parameter pass to SubscribeEvents() method?

Wainting your kindly replies
Thank you
Last edit: 08 May 2015 14:12 by g.aino.

Please Log in or Create an account to join the conversation.

More
08 May 2015 07:36 #3101 by g.aino
Concerning this topic,
is there a way to intercept Addition \ Deleting nodes ? In other words can I set an events handler and a callback to any add or delete nodes from server side information tree? If so I can filter for 'AIS' nodes changing (node\items added) and build subscription on this, it's a way that I can follow?

Thank you in advance

Please Log in or Create an account to join the conversation.

More
07 May 2015 09:50 - 07 May 2015 13:18 #3097 by g.aino
We are happily user of your pachage software EasyUAClient ver 5.32, we build a Wndows service written in c# famework 4.5, this service is a Client infrastructure that reads information from a Server.
Now we use subscrition for reading single value information but now the situation become more complex.

Actually we handle changing in subscribed information values by a the Event change handler like in the following code:
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.AddressSpace;
using OpcLabs.EasyOpc.UA.OperationModel;
 
//... etc
bool okSubscription = StartSubscribe(strNodeIdIdentifier, Heading_ItemChanged);
// ... etc
 
private static bool StartSubscribe(string strNodeIdIdentifier, EasyUAMonitoredItemChangedEventHandler callBackMethodHandler)
{
	bool ok = true;
	UANodeId nodeId = new UANodeId("http://urlAddress.com/UAComServer/", "IMO1234567/NavigationalData/AIS");
	object state = null;
	int[] handleArray = OPCUACore.EasyUAClientInstance.SubscribeMultipleMonitoredItems(new[]
        {
            new EasyUAMonitoredItemArguments(callBackMethodHandler, 
                                            state, 
                                            "opc.tcp:ServerUrlAddress.com:4321", 
                                            nodeId, 
                                            m_configParams.MillisecSampleInterval) 
        });
	return ok;
}
// This is an Example of Event Handler for change
private static void Heading_ItemChanged(object sender, EasyUAMonitoredItemChangedEventArgs e)
{            
    // ...
    try
    {
        if (e.Exception != null)
        {
            // An error to log
        }
        else
        {
            // some previous operation
            UAAttributeData item = e.AttributeData;
            fullInfoItemValue = e.AttributeData.ToString();
            itemValue = e.AttributeData.Value.ToString();
            lastUpdateUTC = e.AttributeData.SourceTimestamp;
 
            if (!string.IsNullOrEmpty(itemValue)
                && Monitor.TryEnter(ShipData.Instance.nauticalInfo, new TimeSpan(0, 0, 2)))
            {
                try
                {
                    ShipData.Instance.nauticalInfo.heading.SetValue(double.Parse(itemValue), m_configParams.SourceName, lastUpdateUTC);
                }
                catch (Exception ex)
                {
                    // Error to log
                }
                finally
                {
                    Monitor.Exit(ShipData.Instance.nauticalInfo);
                }
            }            
        }
    }
    catch (Exception ex)
    {
        // Error to log
    }
}

But now (see the following image from UA Expert client)

we need to read information from a node ,'AIS', with an undefined number of items (named like "M999999999"). This items may change ie some of them may be deleted other may be added and some items may have an update. Each item, like you can see in the image, have many information that can be single value variables or objects variables.
Actually we have "easly" implemented all we need to read 'AIS' informations but without subscription but, like you can understand, with the subscription the situation is more complex.

Your software may support this type of need?

Here the steps that for me must be satisfied:
1. How we can intercept events like: add, delete, update of items under 'AIS' node;
2. After intercept the events type of previous step, is there a way to have a list of items added, deleted or updated (I'm referring to the items named like 'M999999999')?
3. For each item in the list of (for example) added can I get the "UANodeElementCollection" so I can reuse my query methods that we've already implemented before the subscription?

I've just browsed the C# sample code but I just found two example that not match our need. All your informations are very very appreciated!
Thank you in advance!
Last edit: 07 May 2015 13:18 by g.aino.

Please Log in or Create an account to join the conversation.

Moderators: support
Time to create page: 0.213 seconds

      

 Recommend this on Google