Completed
Pull Request — master (#494)
by Olivier
03:37
created

EventGenerator.__init__()   F

Complexity

Conditions 10

Size

Total Lines 48

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 102.1167

Importance

Changes 0
Metric Value
cc 10
c 0
b 0
f 0
dl 0
loc 48
ccs 1
cts 37
cp 0.027
crap 102.1167
rs 3.6

How to fix   Complexity   

Complexity

Complex classes like EventGenerator.__init__() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1 1
import logging
2 1
from datetime import datetime
3 1
import uuid
4
5 1
from opcua import ua
6 1
from opcua import Node
7 1
from opcua.common import events
8 1
from opcua.common import event_objects
9
10
11 1
class EventGenerator(object):
12
13
    """
14
    Create an event based on an event type. Per default is BaseEventType used.
15
    Object members are dynamically created from the base event type and send to
16
    client when evebt is triggered (see example code in source)
17
18
    Arguments to constructor are:
19
20
        server: The InternalSession object to use for query and event triggering
21
22
        source: The emiting source for the node, either an objectId, NodeId or a Node
23
24
        etype: The event type, either an objectId, a NodeId or a Node object
25
    """
26
27 1
    def __init__(self, isession, etype=None, source=ua.ObjectIds.Server):
28
        if not etype:
29
            etype = event_objects.BaseEvent()
30
31
        self.logger = logging.getLogger(__name__)
32
        self.isession = isession
33
        self.event = None
34
        node = None
35
36
        if isinstance(etype, event_objects.BaseEvent):
37
            self.event = etype
38
        elif isinstance(etype, Node):
39
            node = etype
40
        elif isinstance(etype, ua.NodeId):
41
            node = Node(self.isession, etype)
42
        else:
43
            node = Node(self.isession, ua.NodeId(etype))
44
45
        if node:
46
            self.event = events.get_event_obj_from_type_node(node)
47
48
        if isinstance(source, Node):
49
            pass
50
        elif isinstance(source, ua.NodeId):
51
            source = Node(isession, source)
52
        else:
53
            source = Node(isession, ua.NodeId(source))
54
55
        if self.event.SourceNode:
56
            if source.nodeid != self.event.SourceNode:
57
                self.logger.warning(
58
                    "Source NodeId: '%s' and event SourceNode: '%s' are not the same. Using '%s' as SourceNode",
59
                    str(source.nodeid), str(self.event.SourceNode), str(self.event.SourceNode))
60
                source = Node(self.isession, self.event.SourceNode)
61
62
        self.event.SourceNode = source.nodeid
63
        self.event.SourceName = source.get_browse_name().Name
64
65
        source.set_event_notifier([ua.EventNotifier.SubscribeToEvents])
66
        refs = []
67
        ref = ua.AddReferencesItem()
68
        ref.IsForward = True
69
        ref.ReferenceTypeId = ua.NodeId(ua.ObjectIds.GeneratesEvent)
70
        ref.SourceNodeId = source.nodeid
71
        ref.TargetNodeClass = ua.NodeClass.ObjectType
72
        ref.TargetNodeId = self.event.EventType
73
        refs.append(ref)
74
        results = self.isession.add_references(refs)
75
        # result.StatusCode.check()
76
77 1
    def __str__(self):
78
        return "EventGenerator(Type:{0}, Source:{1}, Time:{2}, Message: {3})".format(self.event.EventType,
79
                                                                                 self.event.SourceNode,
80
                                                                                 self.event.Time,
81
                                                                                 self.event.Message)
82 1
    __repr__ = __str__
83
84 1
    def trigger(self, time=None, message=None):
85
        """
86
        Trigger the event. This will send a notification to all subscribed clients
87
        """
88
        self.event.EventId = ua.Variant(uuid.uuid4().hex, ua.VariantType.ByteString)
89
        if time:
90
            self.event.Time = time
91
        else:
92
            self.event.Time = datetime.utcnow()
93
        self.event.ReceiveTime = datetime.utcnow()
94
        # FIXME: LocalTime is wrong but currently know better. For description s. Part 5 page 18
95
        self.event.LocalTime = datetime.utcnow()
96
        if message:
97
            self.event.Message = ua.LocalizedText(message)
98
        elif not self.event.Message:
99
            self.event.Message = ua.LocalizedText(Node(self.isession, self.event.SourceNode).get_browse_name().Text)
100
        self.isession.subscription_service.trigger_event(self.event)
101