opc-uaopen62541

Adding method without input arguments in Open62541


I've been working for a long time with Python and the FreeOPCUA Stack, but I wanted to go into more low-level stuff, so I wanted to try the Open62541 Stack. My C skills are a bit rusted, but I understand the concepts and syntax.

I am trying to create a method node without an input argument. Once called, the method should call a function and return as output the function's output. In Python, the arguments are passed into the add_method as a list. In C, it should be a string or an array of strings.

How should I write it in order to have just a function call, without inputs?

I was following the docs at https://www.open62541.org/doc/1.0/tutorial_server_method.html, but the two examples take input arguments (even the hello world), and since then I am stuck.


Solution

  • I was actually doing something silly and compiling it wrong. Input arguments size can be set to zero and the reference to the input argument can be set to NULL.

    My method definition follows:

    static UA_StatusCode
    enableRobotMethodCallback(UA_Server *server,
                             const UA_NodeId *sessionId, void *sessionHandle,
                             const UA_NodeId *methodId, void *methodContext,
                             const UA_NodeId *objectId, void *objectContext,
                             size_t inputSize, const UA_Variant *input,
                             size_t outputSize, UA_Variant *output) {
        UA_String tmp = UA_STRING_ALLOC(enableRobot());
        UA_Variant_setScalarCopy(output, &tmp, &UA_TYPES[UA_TYPES_STRING]);
        UA_String_clear(&tmp);
        return UA_STATUSCODE_GOOD;
    }
    
    static void
    addEnableRobotMethod(UA_Server *server) {
        UA_Argument outputArgument;
        UA_Argument_init(&outputArgument);
        outputArgument.description = UA_LOCALIZEDTEXT("en-US", "A String");
        outputArgument.name = UA_STRING("MyOutput");
        outputArgument.dataType = UA_TYPES[UA_TYPES_STRING].typeId;
        outputArgument.valueRank = UA_VALUERANK_SCALAR;
    
        UA_MethodAttributes enableRobot = UA_MethodAttributes_default;
        enableRobot.description = UA_LOCALIZEDTEXT("en-US","Enable Robot");
        enableRobot.displayName = UA_LOCALIZEDTEXT("en-US","Enable Robot");
        enableRobot.executable = true;
        enableRobot.userExecutable = true;
        UA_Server_addMethodNode(server, UA_NODEID_NUMERIC(1,20),
                                UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
                                UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
                                UA_QUALIFIEDNAME(1, "Enable Robot"),
                                enableRobot, &enableRobotMethodCallback,
                                0, NULL, 1, &outputArgument, NULL, NULL);
    }