1
votes

I have an example where a method is being added to the server space. The example is set up to take two input values and add them together.

Code example
from opcua import Server, ua, uamethod, instantiate
import time
from opcua.ua import NodeId, NodeIdType

@uamethod
def add_func(self, a, b):
    print("Adding parameters:\n", a, "\tand\t", b)
    return a + b

if __name__ == "__main__":

    # setup server
    server = Server()
    server.set_endpoint("opc.tcp://localhost:4840") #alternative: 
    server.set_endpoint("opc.tcp://0.0.0.0:4840")
    server.set_server_name("Server example")
    server.set_security_policy([ua.SecurityPolicyType.NoSecurity])
    uri = "http://example.uri.de"
    idx = server.register_namespace(uri)
    
    # get Objects node, this is where we should adress our custom stuff to
    objects = server.get_objects_node() # alternative: root_node = server.get_root_node()
    
    # add structure to the namespace (idx) below the Objects node
    myobj = objects.add_object(idx, "MyObject")

    # add variables, type can be defined by assigning a value or ua Variant Type definition
    var1 = myobj.add_variable(idx, "var1", 321, ua.VariantType.Int64)
    var2 = myobj.add_variable(idx, "var2", 123, ua.VariantType.Int64)

    # set variables writable for clients (e.g. UaExpert)
    var1.set_writable()
    var2.set_writable()

    # set input arguments for method
    input_arg1 = ua.Argument() # create new argument
    input_arg1.Name = "a" # name for argument
    input_arg1.DataType = ua.NodeId(ua.ObjectIds.Int64) # data type
    input_arg1.ValueRank = -1 # value rank to be treated a scalar number
    input_arg1.Description = ua.LocalizedText("First integer a") # add description text

    input_arg2 = ua.Argument()
    input_arg2.Name = "b"
    input_arg2.DataType = ua.NodeId(ua.ObjectIds.Int64)
    input_arg2.ValueRank = -1
    input_arg2.Description = ua.LocalizedText("Second integer b")

    # set output arguments
    output_arg = ua.Argument()
    output_arg.Name = "Result"
    output_arg.DataType = ua.NodeId(ua.ObjectIds.Int64)
    output_arg.ValueRank = -1
    output_arg.Description = ua.LocalizedText("Sum")

    print(var1.nodeid)
    print(var2.nodeid)

    # add method to namespace
    mymethod = myobj.add_method(idx, "MyAddFunction", add_func, [input_arg1, input_arg2], [output_arg])

    server.start()

The change I want to make is to remove the input arguments and automatically take var1 & var2 as input when calling MyAddFunction. I use UaExpert to call this method. UaExpert when calling MyAddFunction

I've tried to pass the variables by using their NodeID like this:

mymethod = myobj.add_method(idx, "MyAddFunction", add_func, [var1.nodeid, var1.nodeid], [output_arg])

and get following error message: opcua.ua.uaerrors._base.UaError: NodeId: Could not guess type of NodeId, set NodeIdType

Is the type not defined when creating the variables? What changes have to made for the method to take var1 & var2 as input argument? is there a way to assign these values to the created input arguments (input_arg1 & input_arg2)?

Thank you in advance! regards Nando