Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: How to filter events on subscription with where_clause #1568

Open
HaraldBrueggemann opened this issue Feb 7, 2024 · 2 comments
Open

Comments

@HaraldBrueggemann
Copy link

Hi,

I have a server which publishes events derived by BaseEventType. Each event is also prioritized by the "Severity" Attribute of the event.

In the client application I currently want to react on events filtered by the eventtype and the severity.

Currently i try to subscribe to the event with the following code example:

def subscribe(client: object, type_name: str, node: ua.Node, handler: object) -> None:
        _type_node = client.nodes.base_event_type.get_child([f"0:{type_name}"])

        _where_clause = ua.ContentFilter()
        _where_clause.Elements.append(__get_filter_element_type(_type_node.nodeid))
        _where_clause.Elements.append(__get_filter_element_severity(200))

        _event_filter = ua.EventFilter()
        _event_filter.SelectClauses.append(__get_attribute_operand_valueNodeId(client))
        _event_filter.WhereClause = _where_clause
        
        params = ua.CreateSubscriptionParameters()
        params.RequestedPublishingInterval = 100
        params.RequestedLifetimeCount = 300
        params.RequestedMaxKeepAliveCount = 100

        subscription = client.create_subscription(params, handler)
        event_handle = subscription.subscribe_events(evtypes=_type_node.nodeid, evfilter=_event_filter)


def __get_filter_element_type(type_node_id: ua.NodeId) -> ua.ContentFilterElement:
        el = ua.ContentFilterElement()

        el.FilterOperator = ua.FilterOperator.OfType        
        op = ua.LiteralOperand(Value=ua.Variant(type_node_id))
        el.FilterOperands.append(op)

        return el

def __get_filter_element_severity(severity: int) -> ua.ContentFilterElement:
        el = ua.ContentFilterElement()
        el.FilterOperator = ua.FilterOperator.GreaterThanOrEqual

        op = ua.SimpleAttributeOperand()
        op.BrowsePath.append(ua.QualifiedName("Severity", 0))
        op.AttributeId = ua.AttributeIds.Value
        op.TypeDefinitionId = ua.NodeId(ua.ObjectIds.BaseEventType)

        op2 = ua.LiteralOperand(Value=ua.Variant(severity))

        el.FilterOperands.append(op)
        el.FilterOperands.append(op2)

        return el

The above code works with only the first element in the ContentFilter list. All following entries in the list are ignored.
It looks like that an operator like and, or not... is missing in the contentfilter.

I can not find any example or code snippet for solving that problem. I only found examples with a single element in the contentfilter.

Am i totally doing it wrong? Any help is appreciated.

Thanks and Regards
Harald

Python-Version: 3.10.12
opcua-asyncio Version: master-branch

@schroeder-
Copy link
Contributor

First some server maynot support the complete eventfilter specification. So this could be an issue. Also we just send the Filter as you specify it to the server, so you need to read the OPC UA specification and follow it.
From the spec see https://reference.opcfoundation.org/Core/Part4/v104/docs/7.4.1 :

The filter is evaluated by evaluating the first entry in the element array starting with the first operand in the operand array. The operands of an element may contain References to sub-elements resulting in the evaluation continuing to the referenced elements in the element array.

@HaraldBrueggemann
Copy link
Author

Hi Schroeder,

thanks for your reply.

After reading the referenced link, my life is actually not easier.
I still can`t figure out, how to use multiple filter element connected by logical operands.
Therefore, I reworked my code to use only one filter element.

An example for filtering events by attributes, would be appreciated in the future.

Regards,
Harald

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants