freeopcua调用方法输入args | Python解析数组到inputargs列表

时间:2017-09-01 15:12:48

标签: python python-3.x opc-ua

为了测试这个,你需要freeopcua库。 我想为用户提供服务器上可用的方法列表。用户可以检测存在哪些方法。 (通过枚举)

所有这些函数都有可变数量的输入参数和输出参数。

现在使用freeopcua你可以调用类似

的方法
node.call_method("2:myMethod1", 1,2,3,4)

然而,我所拥有的是[1,2,3,4]。 (这就是我得到的用户输入) 是否有办法解析这个,以便它适合作为myMethod参数?

运行问题的最小代码(不是我的所有代码,但它会让我知道我想去的地方:

myServer.py:(只需要在这里没有问题的方法)

from opcua import Server, ua, uamethod
from enum import Enum


class methods(Enum):
    add = "add"
    multi = "more"
    person = "notInt"


class myServer(Server):
    def __init__(self):
        Server.__init__(self)
        self.set_endpoint("opc.tcp://0.0.0.0:4840/freeopcua/server/")
        self.set_server_name("FreeOpcUa Example Server")
        uri = "http://examples.freeopcua.github.io"
        self.idx = self.register_namespace(uri)


        # Automatically creates server methods of the methods I promise to offer
        for mymethod in methods:
            args = self.methodCreator(mymethod)
            args[1]
            self.nodes.objects.add_method(args[0], args[1], args[2], args[3], args[4])

        self.start()

    def methodCreator(self, method_type):
        inargs = None
        outargs = None
        method = None

        if method_type == methods.add:
            inargs = []
            inarg = ua.Argument()
            inarg.Name = "first_number"
            inargs.append(inarg)
            inarg = ua.Argument()
            inarg.Name = "second_number"
            inargs.append(inarg)
            method = self.multi
            return [2, method_type.value, method, inargs, outargs]

        elif method_type == methods.multi:
            inargs = []
            inarg = ua.Argument()
            inarg.Name = "first_number"
            inargs.append(inarg)
            inarg = ua.Argument()
            inarg.Name = "second_number"
            inargs.append(inarg)
            inarg = ua.Argument()
            inarg.Name = "third_number"
            inargs.append(inarg)
            method = self.add
            return [2, method_type.value, method, inargs, outargs]

        elif method_type == methods.person:
            inargs = []
            inarg = ua.Argument()
            inarg.Name = "Name"
            inargs.append(inarg)
            inarg = ua.Argument()
            inarg.Name = "Age"
            inargs.append(inarg)
            inarg = ua.Argument()
            inarg.Name = "Surname"
            inargs.append(inarg)
            inarg = ua.Argument()
            inarg.Name = "Job"
            inargs.append(inarg)
            method = self.person
            return [2, method_type.value, method, inargs, outargs]

    @uamethod
    def add(self, parent, x, y):
        print(x+y)

    @uamethod
    def multi(self, parentm, x, y, z):
        print(x*y*z)

    @uamethod
    def person(self, parent, name, age, surname, job):
        print("I'm %s %s I'm %s years old and I do %s" % (name, surname, age, job))    

现在文件全部是关于:

myClient.py

from stack.server import myServer, methods
from opcua import Client

class myClient(Client):
    def call_functions(self):
        print("Implemented methods:")
        values = []
        for method in methods:
            print(method.value)
            values.append(method.value)
        #In my real code I check input but here I'll trust the user
        method = input("Select a method please: \n")

        objects = self.nodes.objects
        inarguments = objects.get_child(["2:" + method, "0:InputArguments"]).get_value()
        inargs = []
        for argument in inarguments:
            inargs.append(input("%s: " % argument.Name))
        # I disabled some methods to make sure I just need to show one case
        if method == 'notInt':
            print("Desired")
            objects.call_method("2:" + method, inargs[0], inargs[1], inargs[2], inargs[3])
            print("error")
            objects.call_method("2:" + method, inargs) # This is the line that wont work

server = myServer()
with myClient("opc.tcp://localhost:4840/freeopcua/server/") as client:
    client.call_functions()
server.stop()

所以,当我想调用方法泛型如:

objects.call_method("2:" + method, inargs) 

对于'notInt'而言,它会像我一样具有所需的输出:

objects.call_method("2:" + method, inargs[0], inargs[1], inargs[2], inargs[3])

有没有办法在python中将这个从数组解析为输入参数列表,由?这样我可以保持我的通用方法来调用每个方法?或者在freeopcua中有一种方法可以获得所需的效果(请记住,我使用参数名称来询问用户的输入,所以只需要将列表作为输入而不是溶剂)

1 个答案:

答案 0 :(得分:0)

我已经搜过了一下。昨天在与一些朋友的会面中,我讨论了这个问题。他们对*args提出了一个观点,我应该调查该路径是否有效。确实如此。为了解决我的问题,我只需要在我的客户端响应列表前添加一个*,就像在共享链接中所承诺的那样,将其解包并将其作为所有单个参数而不是1个列表对象发送到服务器。我的搜索关键字前几天错了。无论如何只需在de myClient.py

中解决这个问题
from stack.server import myServer, methods
from opcua import Client

class myClient(Client):
    def call_functions(self):
        print("Implemented methods:")
        values = []
        for method in methods:
            print(method.value)
            values.append(method.value)
        #In my real code I check input but here I'll trust the user
        method = input("Select a method please: \n")

        objects = self.nodes.objects
        inarguments = objects.get_child(["2:" + method, "0:InputArguments"]).get_value()
        inargs = []
        for argument in inarguments:
            inargs.append(input("%s: " % argument.Name))
        # I disabled some methods to make sure I just need to show one case
        if method == 'notInt':
            print("Desired")
            objects.call_method("2:" + method, inargs[0], inargs[1], inargs[2], inargs[3])
            print("error")
            objects.call_method("2:" + method, *inargs) # This will now work

server = myServer()
with myClient("opc.tcp://localhost:4840/freeopcua/server/") as client:
    client.call_functions()
server.stop()

现在我需要做的就是删除枚举,以便客户端向服务器请求这个,然后我有一个客户端,对于我添加到opcua-server的任何函数都是通用的,我的客户端代码将能够询问哪些是可用,选择一个并询问参数而无需其他代码。得爱蟒蛇!