Completed
Pull Request — master (#188)
by Olivier
03:33
created

event_obj_from_event_fields()   A

Complexity

Conditions 3

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
dl 0
loc 8
rs 9.4285
c 1
b 0
f 0
1
from opcua import ua
2
3
4
class EventResult(object):
5
    """
6
    To be sent to clients for every events from server
7
    """
8
9
    def __init__(self):
10
        self.server_handle = None
11
12
    def __str__(self):
13
        return "EventResult({})".format([str(k) + ":" + str(v) for k, v in self.__dict__.items()])
14
    __repr__ = __str__
15
16
    def get_event_props_as_fields_dict(self):
17
        """
18
        convert all properties of the EventResult class to a dict of variants
19
        """
20
        field_vars = {}
21
        for key, value in vars(self).items():
22
            if not key.startswith("__") and key is not "server_handle":
23
                field_vars[key] = ua.Variant(value)
24
        return field_vars
25
26
27
def event_obj_from_event_fields(select_clauses, fields):
28
    result = EventResult()
29
    for idx, sattr in enumerate(select_clauses):
30
        if len(sattr.BrowsePath) == 0:
31
            setattr(result, sattr.AttributeId.name, fields[idx].Value)
32
        else:
33
            setattr(result, sattr.BrowsePath[0].Name, fields[idx].Value)
34
    return result
35
36
37
def get_filter_from_event_type(eventtype):
38
    evfilter = ua.EventFilter()
39
    evfilter.SelectClauses = select_clauses_from_evtype(eventtype)
40
    evfilter.WhereClause = where_clause_from_evtype(eventtype)
41
    return evfilter
42
43
44
def select_clauses_from_evtype(evtype):
45
    clauses = []
46
    for prop in get_event_properties_from_type_node(evtype):
47
        op = ua.SimpleAttributeOperand()
48
        op.TypeDefinitionId = evtype.nodeid
49
        op.AttributeId = ua.AttributeIds.Value
50
        op.BrowsePath = [prop.get_browse_name()]
51
        clauses.append(op)
52
    return clauses
53
54
55
def where_clause_from_evtype(evtype):
56
    cf = ua.ContentFilter()
57
    el = ua.ContentFilterElement()
58
    # operands can be ElementOperand, LiteralOperand, AttributeOperand, SimpleAttribute
59
    op = ua.SimpleAttributeOperand()
60
    op.TypeDefinitionId = evtype.nodeid
61
    op.BrowsePath.append(ua.QualifiedName("EventType", 0))
62
    op.AttributeId = ua.AttributeIds.Value
63
    el.FilterOperands.append(op)
64
    for subtypeid in [st.nodeid for st in get_node_subtypes(evtype)]:
65
        op = ua.LiteralOperand()
66
        op.Value = ua.Variant(subtypeid)
67
        el.FilterOperands.append(op)
68
    el.FilterOperator = ua.FilterOperator.InList
69
70
    cf.Elements.append(el)
71
    return cf
72
73
74
def get_node_subtypes(node, nodes=None):
75
    if nodes is None:
76
        nodes = [node]
77
    for child in node.get_children(refs=ua.ObjectIds.HasSubtype):
78
        nodes.append(child)
79
        get_node_subtypes(child, nodes)
80
    return nodes
81
82
83
def get_event_properties_from_type_node(node):
84
    properties = []
85
    curr_node = node
86
87
    while True:
88
        properties.extend(curr_node.get_properties())
89
90
        if curr_node.nodeid.Identifier == ua.ObjectIds.BaseEventType:
91
            break
92
93
        parents = curr_node.get_referenced_nodes(refs=ua.ObjectIds.HasSubtype, direction=ua.BrowseDirection.Inverse, includesubtypes=False)
94
        if len(parents) != 1:  # Something went wrong
95
            return None
96
        curr_node = parents[0]
97
98
    return properties
99