Passed
Push — master ( 3b4362...51826f )
by Olivier
04:24
created

call_method_full()   A

Complexity

Conditions 4

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
c 1
b 0
f 0
dl 0
loc 16
ccs 8
cts 8
cp 1
crap 4
rs 9.2
1
"""
2
High level method related functions
3
"""
4
5 1
from opcua import ua
6 1
from opcua.common import node
7
8
9 1
def call_method(parent, methodid, *args):
10
    """
11
    Call an OPC-UA method. methodid is browse name of child method or the
12
    nodeid of method as a NodeId object
13
    arguments are variants or python object convertible to variants.
14
    which may be of different types
15
    returns a list of values or a single value depending on the output of the method
16
    """
17 1
    result = call_method_full(parent, methodid, *args)
18
19 1
    if len(result.OutputArguments) == 0:
20 1
        return None
21 1
    elif len(result.OutputArguments) == 1:
22 1
        return result.OutputArguments[0]
23
    else:
24 1
        return result.OutputArguments
25
26
27 1
def call_method_full(parent, methodid, *args):
28
    """
29
    Call an OPC-UA method. methodid is browse name of child method or the
30
    nodeid of method as a NodeId object
31
    arguments are variants or python object convertible to variants.
32
    which may be of different types
33
    returns a CallMethodResult object with converted OutputArguments
34
    """
35 1
    if isinstance(methodid, (str, ua.uatypes.QualifiedName)):
36 1
        methodid = parent.get_child(methodid).nodeid
37 1
    elif isinstance(methodid, node.Node):
38 1
        methodid = methodid.nodeid
39
40 1
    result = _call_method(parent.server, parent.nodeid, methodid, to_variant(*args))
41 1
    result.OutputArguments = [var.Value for var in result.OutputArguments]
42 1
    return result
43
44 1
def _call_method(server, parentnodeid, methodid, arguments):
45 1
    request = ua.CallMethodRequest()
46 1
    request.ObjectId = parentnodeid
47 1
    request.MethodId = methodid
48 1
    request.InputArguments = arguments
49 1
    methodstocall = [request]
50 1
    results = server.call(methodstocall)
51 1
    res = results[0]
52 1
    res.StatusCode.check()
53 1
    return res
54
55
56 1
def uamethod(func):
57
    """
58
    Method decorator to automatically convert
59
    arguments and output to and from variants
60
    """
61 1
    def wrapper(parent, *args):
62 1
        if isinstance(parent, ua.NodeId):
63 1
            result = func(parent, *[arg.Value for arg in args])
64
        else:
65
            self = parent
66
            parent = args[0]
67
            args = args[1:]
68
            result = func(self, parent, *[arg.Value for arg in args])
69 1
        if result is None:
70 1
            return []
71 1
        elif isinstance(result, ua.CallMethodResult):
72 1
            result.OutputArguments = to_variant(*result.OutputArguments)
73 1
            return result
74 1
        elif isinstance(result, ua.StatusCode):
75 1
            return result
76 1
        elif isinstance(result, tuple):
77 1
            return to_variant(*result)
78
        else:
79 1
            return to_variant(result)
80 1
    return wrapper
81
82
83 1
def to_variant(*args):
84 1
    uaargs = []
85 1
    for arg in args:
86 1
        if not isinstance(arg, ua.Variant):
87 1
            arg = ua.Variant(arg)
88 1
        uaargs.append(arg)
89
    return uaargs
90