Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
ninagestalt opened this issue Oct 1, 2024 · 2 comments
Open

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

ninagestalt opened this issue Oct 1, 2024 · 2 comments

Comments

@ninagestalt
Copy link

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?
@AndreasHeine
Copy link
Member

AndreasHeine commented Oct 1, 2024

guess your method should return a tuple instead of a list!?

see: https://github.com/FreeOpcUa/opcua-asyncio/blob/master/examples%2Fserver-extension-object-as-method-argument.py

@ninagestalt
Copy link
Author

@AndreasHeine I tried writing a client for this example but still get similar errors as before..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants