2017-09-01 134 views
0

列表爲了測試這個,你將需要freeopcua庫。 我想向用戶提供服務器上可用方法的列表。用戶可以檢測哪些方法存在。 (通過枚舉)freeopcua調用方法輸入參數| Python解析數組到輸入列表

所有這些函數都有可變數量的輸入參數和輸出參數。

現在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]) 

是否有辦法蟒蛇得到這個從數組解析到輸入參數列表分隔,?所以我可以保留我的通用方法來調用每個方法?或在freeopcua是那裏得到所需的方式影響(記住,我使用的參數名,要求他輸入用戶所以才使得它需要一個列表作爲輸入不會是一個sollution)

+0

主要是這樣,我可以分發一個客戶端,甚至認爲服務器可以添加功能,而無需客戶端更新 –

+0

它主要是關於代碼收集。是的客戶端PC將需要更新的枚舉。然而在我的真實項目中,我製作了一個模塊,這些模塊可以承擔所有這些方法的功能,如果客戶端完全獨立於此對象而不是Enum –

回答

0

我已經查了一下。昨天在與一些朋友的會議上,我討論了這個問題。他們提出了一個關於*args的觀點,並且我應該調查該路徑是否有效。它確實如此。爲了解決我的問題,我只需要在我的客戶端響應列表的前面添加一個*,就像在共享鏈接中承諾的那樣,將它解包並將其作爲所有單個參數而不是1個列表對象發送到服務器。我的搜索關鍵字有一天是錯誤的。通過只是在做這在德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服務器,我的客戶端代碼將能夠詢問哪些是可用的,選擇一個並請求參數而不需要額外的代碼。得愛蟒蛇!