2

I have the following code..

from opcua import ua, Client

try:
    # Connect to the server
    client = Client("opc.tcp://192.168.0.17:4840", timeout=5000)
    client.set_user('user')
    client.set_password('password')
    client.connect()

    # Call a method

    method = client.get_node("ns=4;i=7014")
    parent_obj = "ns=4;i=5002" # Nodeid of the object
    obj = client.get_node(parent_obj)
    out = obj.call_method(method, 0,0,0,0,0,0)
    print("Result: ", out)

except Exception as e:
    print("Error: ", e)

except KeyboardInterrupt:
    print("Programm stopped by user")

finally:
    # Disconnect from the server
    print("Closing...")
    client.disconnect()
    exit(0)

however the programm stops with an error of "One or more arguments are invalid". I have tried many different variation on passing the arguments on, but I can't seem to get it right. Can anyone help?

Method name:

Method name

Method description:

Method description

Method call:

Method call

I tried different ways of passing the arguments on, but can't seem to get it right.

kirba22
  • 53
  • 4
  • Please fix the indentation and show the full traceback. – Timus Mar 01 '23 at 12:25
  • traceback to a file is coming up empty. The error I get is "One or more arguments are invalid."(BadInvalidArgument) – kirba22 Mar 01 '23 at 12:31
  • That's because you explicitly trap and throw away the useful information with your bare `except`. See also https://stackoverflow.com/questions/54948548/what-is-wrong-with-using-a-bare-except – tripleee Mar 01 '23 at 12:43
  • So what kind of error catching should I do to get the neccesarry info? – kirba22 Mar 01 '23 at 13:12
  • Try changing the namespace index... In Screen Prints there is 3, "Write Tag"; so maybe your namespace index is 3. Most bullet proof method would be to know the namespace of your node & then load it in python (using Asyncua): `idx = obj.get_namespace_index("yoursite.org")` and then use that `idx` variable as namespace index, i.e. `method = client.get_node(f"ns={idx};i=7014")` – mggluscevic Mar 31 '23 at 08:21

1 Answers1

1

You must use the correct datatypes. The datatypes are a bit tricky and are most likly not fully support on python-opcua, which is deprecated. You must switch to asyncua and use the syncwrapper or go async.

from asyncua.sync import Client, ThreadLoop
from asyncua import ua

with ThreadLoop() as tloop:
       try:
           # Connect to the server
           client = Client("opc.tcp://192.168.0.17:4840", timeout=5000, tloop=tloop)
           client.set_user('user')
           client.set_password('password')
           client.connect()

           # load datatypes
           client.load_data_type_definitions()

           # prepare args 
           arg1 = ua.ScanData() 
           arg1.String = 'testdata'
           arg2 = 'URI' # Is string
           arg3 = ua.UInt16(0)
           arg4 = ua.UInt32(0)
           arg5 = ua.ByteString(b'')
           arg6 = ua.ByteString(b'')
           # Call a method

           method = client.get_node("ns=4;i=7014")
           parent_obj = "ns=4;i=5002" # Nodeid of the object
           obj = client.get_node(parent_obj)
           out = obj.call_method(method, arg1, arg2, arg3, arg4, arg5, arg6)
           print("Result: ", out)

       except Exception as e:
           print("Error: ", e)

       except KeyboardInterrupt:
           print("Programm stopped by user")

       finally:
           # Disconnect from the server
           print("Closing...")
           client.disconnect()
           exit(0)
      
Schroeder
  • 749
  • 4
  • 10
  • This also doesn't work as it breaks with a "Client object has no attribute "load type definition" – kirba22 Mar 01 '23 at 12:52
  • 1
    load_data_type_definitions() fixed that issue, also import ua was missing. The error which then comes is String object has no attribute "encode" – kirba22 Mar 01 '23 at 13:00
  • Stacktrace or where does the error comes from? – Schroeder Mar 01 '23 at 13:37
  • stacktrace `except Exception as e: /br print("Error: ", e) with open('traceback.txt', 'w') as file: file.write(traceback.format_exc())` delivers an empty file, but the error comes when calling the method out = ... – kirba22 Mar 01 '23 at 13:38
  • what are the values of arg1 = ua.ScanData() # Fill with the data arg2 = ua.CodeTypeDataType() # Fill with correct data – Schroeder Mar 01 '23 at 13:44
  • That's also the issue, I'm not sure what values to put there, right now they are empty, or better said, nothing has been changed in those code lines. See additional answer about values above. – kirba22 Mar 01 '23 at 13:54
  • See https://reference.opcfoundation.org/AutoID/v101/docs/6.5.3.8 and https://reference.opcfoundation.org/AutoID/v101/docs. I changed the example for a example. – Schroeder Mar 01 '23 at 14:00
  • Now the error "The value was out of range."(BadOutOfRange) is present. I'm still not sure what to fill in the both arguments in order for it to function. – kirba22 Mar 01 '23 at 14:08
  • BadOutOfRange means a value is not correct. So at least the opc ua datatypes are correct. Now you have to find the correct values. Sry can't help you there. See https://reference.opcfoundation.org/AutoID/v101/docs/6.5.3.8 for the correct parameters. – Schroeder Mar 01 '23 at 14:22
  • If it is basic data type, you can double click InputArguments in your explorer & then see data type for that Value. Here you have code names for types: https://github.com/FreeOpcUa/opcua-asyncio/blob/master/asyncua/ua/uatypes.py#L760 – mggluscevic Mar 31 '23 at 08:33