How to make opcua more efficient in python?

i’m currently writing a python skript which interacts with a PLC via OPC UA.

The communication with OPC UA seems very slow.
I measured the time for writing 5 values to the PLC with time.perf_counter() which results in 20ms.

Eventually im trying to write/read up to 100 variables in one cycle.
This would result in a cyclic time of 2sec.

The PLC ist connected to the PC via a switch.

The 5 variables I tested:
_node are Node objects;
statusword is in ushort(hex);
the others are int

opc.set_value(self.statusword_node,  get_statusnumber(self.statusword))
opc.set_value(self.actualspeed_node, self.actualspeed)
opc.set_value(self.errorcode_node,   self.errorcode)
opc.set_value(self.motorcurrent_node,self.motorcurrent)
opc.set_value(self.motortorque_node, self.motortorque)

opc is an object from my OpcClient class.
set_value is the follwing function:

def set_value(node: Node, value) -> None:
    '''sets value to node object'''
    node.set_value(get_uadatatype(value))

the function get_uadatatype() returns the value as a uadatatype:

def get_uadatatype(value) -> ua.DataValue:
    '''checks the type of value and converts it into a ua.DataValue type'''
    if isinstance(value, bool):
        return ua.DataValue(ua.Variant(value, ua.VariantType.Boolean))

    elif isinstance(value, int) or isinstance(value, np.uint16):
        return ua.DataValue(ua.Variant(value, ua.VariantType.Int16))

    elif isinstance(value, float):
        return ua.DataValue(ua.Variant(value, ua.VariantType.Float))

    else:
        loginfo(f"Please import convert function for {type(value)}")
        raise ValueError

Which part of the programm slows it down?
Or is it just impossible to write values faster with opc?

Thanks for your help:)

What slows you down is the network. Each set_value, does a network request/response with the server.

To speed things up you need to do a batch write:

nodes = [ 
    self.statusword_node,
    self.actualspeed_node,
    ...
]
values = [
    get_statusnumber(self.statusword),
    self.actualspeed,
    ...
]

opc.set_values(nodes, values)

Leave a Comment