Skip to content
Snippets Groups Projects
Select Git revision
  • 057e7a1b6b2429a4e96499aa3086b01db98714eb
  • main default protected
  • add-editorconfig
3 results

__init__.py

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    client.c 8.85 KiB
    /* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
     * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. */
    
    #include <open62541/client_config_default.h>
    #include <open62541/client_highlevel.h>
    #include <open62541/client_subscriptions.h>
    #include <open62541/plugin/log_stdout.h>
    
    #include <stdlib.h>
    
    #ifdef UA_ENABLE_SUBSCRIPTIONS
    static void
    handler_TheAnswerChanged(UA_Client *client, UA_UInt32 subId, void *subContext,
                             UA_UInt32 monId, void *monContext, UA_DataValue *value) {
        printf("The Answer has changed!\n");
    }
    #endif
    
    static UA_StatusCode
    nodeIter(UA_NodeId childId, UA_Boolean isInverse, UA_NodeId referenceTypeId, void *handle) {
        if(isInverse)
            return UA_STATUSCODE_GOOD;
        UA_NodeId *parent = (UA_NodeId *)handle;
        printf("%d, %d --- %d ---> NodeId %d, %d\n",
               parent->namespaceIndex, parent->identifier.numeric,
               referenceTypeId.identifier.numeric, childId.namespaceIndex,
               childId.identifier.numeric);
        return UA_STATUSCODE_GOOD;
    }
    
    int main(int argc, char *argv[]) {
        UA_Client *client = UA_Client_new();
        UA_ClientConfig_setDefault(UA_Client_getConfig(client));
    
        /* Listing endpoints */
        UA_EndpointDescription* endpointArray = NULL;
        size_t endpointArraySize = 0;
        UA_StatusCode retval = UA_Client_getEndpoints(client, "opc.tcp://localhost:4840",
                                                      &endpointArraySize, &endpointArray);
        if(retval != UA_STATUSCODE_GOOD) {
            UA_Array_delete(endpointArray, endpointArraySize, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
            UA_Client_delete(client);
            return EXIT_FAILURE;
        }
        printf("%i endpoints found\n", (int)endpointArraySize);
        for(size_t i=0;i<endpointArraySize;i++) {
            printf("URL of endpoint %i is %.*s\n", (int)i,
                   (int)endpointArray[i].endpointUrl.length,
                   endpointArray[i].endpointUrl.data);
        }
        UA_Array_delete(endpointArray,endpointArraySize, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
    
        /* Connect to a server */
        /* anonymous connect would be: retval = UA_Client_connect(client, "opc.tcp://localhost:4840"); */
        retval = UA_Client_connectUsername(client, "opc.tcp://localhost:4840", "user1", "password");
        if(retval != UA_STATUSCODE_GOOD) {
            UA_Client_delete(client);
            return EXIT_FAILURE;
        }
    
        /* Browse some objects */
        printf("Browsing nodes in objects folder:\n");
        UA_BrowseRequest bReq;
        UA_BrowseRequest_init(&bReq);
        bReq.requestedMaxReferencesPerNode = 0;
        bReq.nodesToBrowse = UA_BrowseDescription_new();
        bReq.nodesToBrowseSize = 1;
        bReq.nodesToBrowse[0].nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER); /* browse objects folder */
        bReq.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL; /* return everything */
        UA_BrowseResponse bResp = UA_Client_Service_browse(client, bReq);
        printf("%-9s %-16s %-16s %-16s\n", "NAMESPACE", "NODEID", "BROWSE NAME", "DISPLAY NAME");
        for(size_t i = 0; i < bResp.resultsSize; ++i) {
            for(size_t j = 0; j < bResp.results[i].referencesSize; ++j) {
                UA_ReferenceDescription *ref = &(bResp.results[i].references[j]);
                if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_NUMERIC) {
                    printf("%-9d %-16d %-16.*s %-16.*s\n", ref->nodeId.nodeId.namespaceIndex,
                           ref->nodeId.nodeId.identifier.numeric, (int)ref->browseName.name.length,
                           ref->browseName.name.data, (int)ref->displayName.text.length,
                           ref->displayName.text.data);
                } else if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_STRING) {
                    printf("%-9d %-16.*s %-16.*s %-16.*s\n", ref->nodeId.nodeId.namespaceIndex,
                           (int)ref->nodeId.nodeId.identifier.string.length,
                           ref->nodeId.nodeId.identifier.string.data,
                           (int)ref->browseName.name.length, ref->browseName.name.data,
                           (int)ref->displayName.text.length, ref->displayName.text.data);
                }
                /* TODO: distinguish further types */
            }
        }
        UA_BrowseRequest_clear(&bReq);
        UA_BrowseResponse_clear(&bResp);
    
        /* Same thing, this time using the node iterator... */
        UA_NodeId *parent = UA_NodeId_new();
        *parent = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
        UA_Client_forEachChildNodeCall(client, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
                                       nodeIter, (void *) parent);
        UA_NodeId_delete(parent);
    
    
    #ifdef UA_ENABLE_METHODCALLS
        /* Call a remote method */
        UA_Variant input;
        UA_Variant_init(&input);
        size_t outputSize;
        UA_Variant *output;
    
        char regname[100];
        int i;
    
        {
    
            /* Browse some objects */
            printf("Browsing nodes in objects folder:\n");
            UA_BrowseRequest bReq;
            UA_BrowseRequest_init(&bReq);
            bReq.requestedMaxReferencesPerNode = 0;
            bReq.nodesToBrowse = UA_BrowseDescription_new();
            bReq.nodesToBrowseSize = 1;
            bReq.nodesToBrowse[0].nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER); /* browse objects folder */
            bReq.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL; /* return everything */
            UA_BrowseResponse bResp = UA_Client_Service_browse(client, bReq);
            printf("%-9s %-16s %-16s %-16s\n", "NAMESPACE", "NODEID", "BROWSE NAME", "DISPLAY NAME");
            for(size_t i = 0; i < bResp.resultsSize; ++i) {
                for(size_t j = 0; j < bResp.results[i].referencesSize; ++j) {
                    UA_ReferenceDescription *ref = &(bResp.results[i].references[j]);
                    if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_NUMERIC) {
                    } else if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_STRING) {
                        printf("%-9d %-16.*s %-16.*s %-16.*s\n", ref->nodeId.nodeId.namespaceIndex,
                               (int)ref->nodeId.nodeId.identifier.string.length,
                               ref->nodeId.nodeId.identifier.string.data,
                               (int)ref->browseName.name.length, ref->browseName.name.data,
                               (int)ref->displayName.text.length, ref->displayName.text.data);
    
    
                        UA_String argString = UA_STRING(ref->nodeId.nodeId.identifier.string.data);
                        UA_Variant_setScalarCopy(&input, &argString, &UA_TYPES[UA_TYPES_STRING]);
    
                        retval = UA_Client_call(client, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
                                                UA_NODEID_STRING(1, ref->nodeId.nodeId.identifier.string.data), 
                                                1, &input, &outputSize, &output);
                        if(retval == UA_STATUSCODE_GOOD) {
                            UA_String *outputStr = (UA_String*)output->data;
                            printf("outputStr->data=%s\n",(char *)outputStr->data);
    
                            printf("Method call was successful, and %lu returned values available.\n",
                                   (unsigned long)outputSize);
                            UA_Array_delete(output, outputSize, &UA_TYPES[UA_TYPES_VARIANT]);
                        } else {
                            printf("Method call was unsuccessful, and %x returned values available.\n", retval);
                        }
                    }
                    /* TODO: distinguish further types */
                }
            }
            UA_BrowseRequest_clear(&bReq);
            UA_BrowseResponse_clear(&bResp);
            UA_Variant_clear(&input);
    
        }
    
    
    
    #endif
    
        /* Read the value attribute of the node. UA_Client_readValueAttribute is a
         * wrapper for the raw read service available as UA_Client_Service_read. */
        UA_Variant vvalue; /* Variants can hold scalar values and arrays of any type */
        UA_Variant_init(&vvalue);
    
        /* NodeId of the variable holding the current time */
        const UA_NodeId nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME);
        retval = UA_Client_readValueAttribute(client, nodeId, &vvalue);
    
        if(retval == UA_STATUSCODE_GOOD &&
           UA_Variant_hasScalarType(&vvalue, &UA_TYPES[UA_TYPES_DATETIME])) {
            UA_DateTime raw_date = *(UA_DateTime *) vvalue.data;
            UA_DateTimeStruct dts = UA_DateTime_toStruct(raw_date);
            UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "date is: %u-%u-%u %u:%u:%u.%03u\n",
                        dts.day, dts.month, dts.year, dts.hour, dts.min, dts.sec, dts.milliSec);
        }
    
        const UA_NodeId nodeId2 = UA_NODEID_STRING(1, (char *)"sensors");
        retval = UA_Client_readValueAttribute(client, nodeId2, &vvalue);
    
        if(retval == UA_STATUSCODE_GOOD &&
           UA_Variant_hasScalarType(&vvalue, &UA_TYPES[UA_TYPES_INT32])) {
            UA_Int32 myInteger = *(UA_Int32 *) vvalue.data;
            UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "myInteger is: %u\n",myInteger);
        }
        
    
        UA_Client_disconnect(client);
        UA_Client_delete(client);
        return EXIT_SUCCESS;
    }