Page 1 of 1

Event handling

Posted: 10 Jul 2014, 17:28
by perezjo
Hello.
My model has analog and digital signals and my purpose is to generate an event with each digital signal. For a test, I have created an Event (TransitionEventType) and declared the server as event notifier and one of the digital signals as event source. This is my firing event routine:

Code: Select all

OpcUa_StatusCode XXXProvider_FireChangeEvent(OpcUa_UInt32 identifier)
{
    UaServer_Event     *pEvent = OpcUa_Null;
    OpcUa_NodeId        eventTypeId;
    OpcUa_ByteString    bsEventId;
    OpcUa_Variant       value;
	OpcUa_NodeId        nodeId, sourceNodeId;
	OpcUa_Variable*		pVariable;


OpcUa_InitializeStatus(OpcUa_Module_Server, "XXXProvider_FireChangeEvent");

    OpcUa_NodeId_Initialize(&eventTypeId);
    OpcUa_ByteString_Initialize(&bsEventId);
    OpcUa_Variant_Initialize(&value);

	eventTypeId.NamespaceIndex = 0;
	eventTypeId.Identifier.Numeric = OpcUaId_ProgramTransitionEventType;

	pEvent = UaServer_Events_CreateEvent(&eventTypeId);

	UaServer_Events_CreateEventId(0, &bsEventId);

    /* Set event fields of BaseEventType */
    UaServer_Events_SetEventId(pEvent, &bsEventId);
    UaServer_Events_SetEventType(pEvent, &eventTypeId);

	nodeId.IdentifierType = OpcUa_IdentifierType_Numeric;
    nodeId.NamespaceIndex = g_UaProviderXXX_uNamespaceIndex1;
	nodeId.Identifier.Numeric = XXX_Objects_XXX;
	sourceNodeId.IdentifierType = OpcUa_IdentifierType_Numeric;
	sourceNodeId.NamespaceIndex = g_UaProviderXXX_uNamespaceIndex1;
	sourceNodeId.Identifier.Numeric = identifier;
		

    UaServer_Events_SetSourceNode(pEvent, &nodeId);
    UaServer_Events_SetSourceName(pEvent, "XXX");

    UaServer_Events_SetTime(pEvent, OpcUa_DateTime_UtcNow());
    UaServer_Events_SetReceiveTime(pEvent, OpcUa_DateTime_UtcNow());
    UaServer_Events_SetLocalTime(pEvent, OpcUa_DateTime_UtcNow());
    
    UaServer_GetNode(&g_pXXXProvider->AddressSpace, &sourceNodeId, (OpcUa_BaseNode**)&pVariable);
    if (pVariable != OpcUa_Null)
    {
    	if (OpcUa_Variable_GetValue(pVariable)->Value.Boolean == OpcUa_False)
    	{
    		UaServer_Events_SetMessage(pEvent, "en", "var was set to OFF");
    	}
    	else
    	{
    		UaServer_Events_SetMessage(pEvent, "en", "var was set to ON");
    	}
    }
    UaServer_Events_SetSeverity(pEvent, 500);

	uStatus = UaServer_Events_FireEvent(pEvent);

    UaServer_Events_DeleteEvent(&pEvent);
    OpcUa_ByteString_Clear(&bsEventId);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

OpcUa_FinishErrorHandling;
}
This piece of code is executed when a digital change of state is received. As a result, I got that the event was generated in UaExpert with the change of state of all the signals, not only with the signal defined as event source. Why? Is it necessary to define all the signals as event source if I only have a single event notifier?
What's the function of the created event object? Do I need to create an object for each digital signals which will generate events? Which will be the best way to implement my issue?
Thanks in advance.

Re: Event handling

Posted: 11 Jul 2014, 09:38
by Support Team
Hello,

depending on your model and underlying data source there are different ways to make the changes available via OPC UA. The documentation http://documentation.unified-automation ... #areas_sec might help to get an idea about the concept behind EventSources, EventNotifiers and their relations.

Subscribing to the Server object will lead to receiving every event that is created in the server. For filtering the received events you basically have two options:

1. Use the Area/Notifier/Source concept:
Define one EventNotifier for every signal you have. Then subscribing to the according EventNotifier would only deliver the events for that signal. If you have many signals, this might be unpractical as there would need to be as many EventNotifiers.

2. Use the UA filtering mechanism:
When subscribing for events, you can set a filter defining which events to receive and which not. This is currently not supported by UaExpert, but will be in some future version; also there are other UA clients around that are able to do that. As an example, you could set the signal as event source and filter for it using the UA filter (WhereClause). Another way would be to create a new event type (http://documentation.unified-automation ... e_type_sec) with a new EventField representing the according signal of the underlying system and then filter for that.

Best regards,
Unified Automation Support Team

Re: Event handling

Posted: 11 Jul 2014, 13:06
by perezjo
Hello,

Thanks for your fast answer. For the first implementation I'm not going to filter any event (it will be considered for next iterations). The idea is to have a single notifier (the Server) and multiple signals as event source, but not necessarily defined (UaServer_Events_RegisterEventSource). Is this correct?

Another question. What are Event Nodes used for? I mean nodes created by UaModeler. They are not used in the above firing event routine and I get events in UaExpert. So, do I need then? None, at least one or one per event source signal?

Thank you so much.

Re: Event handling

Posted: 14 Jul 2014, 10:00
by Support Team
Hello,

for the SDK to be able to filter the events correctly, you should always register all event sources that are used with UaServer_Events_RegisterEventSource().

If you want to avoid creating many nodes, you might also define a new event type with a new EventField that identifies the signal which triggered the event. This way you don't have to create a new event source for every possible signal.

For your new question: which nodes do you mean? If you create a new event type, it will be added to the type tree below Types/EventTypes/BaseEventType/... . For alarms, it is possible to have the alarm instance represented as nodes in the address space. Please refer to the UA specification for details on this.

Best regards,
Unified Automation Support Team