Skip to content

Example of opc-ua methods with access to nodes #1551

@ninagestalt

Description

@ninagestalt

Goal

Create an opc-ua method that has access to the nodes. My main goal is to return a list of nodes (e..g all nodes in one folder) with one server call, instead of one for each node.

What I've tried

I found this example of opc-ua methods that does work for me:
https://github.com/ifak-prototypes/opcua_examples/tree/main/src/MethodsServerSimple

But I want to access the nodes.

Minimal non-working example

I created a minimal non-working example of a server that exposes two nodes (Node1, Node2) and a method sum().

from opcua import ua, Server

def sum_method(parent):
    val1 = node1.get_value()
    val2 = node2.get_value()
    return [ua.Variant(val1 + val2, ua.VariantType.Double)]

if __name__ == "__main__":
    server = Server()
    server.set_endpoint("opc.tcp://0.0.0.0:4840/freeopcua/server/")
    uri = "http://example.opcua.server"
    idx = server.register_namespace(uri)

    objects = server.get_objects_node()
    
    # Add two nodes with initial values
    node1 = objects.add_variable(idx, "Node1", 5.5)
    node2 = objects.add_variable(idx, "Node2", 10.5)
    node1.set_writable()
    node2.set_writable()

    # Add a method to sum the two nodes
    objects.add_method(idx, "sum", sum_method, [], [ua.VariantType.Double])

    # Start the server
    server.start()
    try:
        input("Server is running. Press Enter to stop...")
    finally:
        server.stop()

and the client code to call the method:

from opcua import Client

if __name__ == "__main__":
    client = Client("opc.tcp://localhost:4840/freeopcua/server/")

    try:
        # Connect to the server
        client.connect()
        print("Client connected")

        # Access the root node and browse to the Objects node
        objects_node = client.get_objects_node()

        # Find the method node by browsing or by known ID/path
        sum_method = objects_node.get_child(["0:MyObject", "0:sum"])

        # Call the method, no input arguments
        result = sum_method.call()
        print(f"The sum of the two node values is: {result}")

    finally:
        # Close the connection
        client.disconnect()
        print("Client disconnected")

and the error:

opcua.ua.uaerrors._auto.BadNoMatch: "The requested operation has no match to return."(BadNoMatch)

My questions

  • How can I fix my error? Or...
  • Is there a better way to get multiple node values with one server call (or less)?
  • Are there examples (showing both server and client code) for this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions