I am trying to create a small program in C which will poll a frame of data over a opc/ua connection using the open62541 library and the forward it to a kafka server.
Everything works fine when fetching the values from the nodes separately but I would like to use a UA_ReadRequest for that. The problem is that I am only receiving empty responses.
The opc/ua server is coded with in python using the freeopc package.
This is the function that tries tu use a UA_ReadResponse to fetch a several values for specified nodeIDs:
void retrieveOPCData(void)
{
UA_ReadRequest request;
UA_ReadRequest_init(&request);
UA_ReadValueId ids[nodeCount];
for (int i = 0; i < nodeCount; i++)
{
UA_ReadValueId_init(&ids[i]);
ids[i].attributeId = UA_ATTRIBUTEID_VALUE;
ids[i].nodeId = nodesToRead[i];
}
request.nodesToRead = ids;
for (int i = 0; i < nodeCount; i++)
{
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "ID%i: %s, %i", i,
request.nodesToRead[i].nodeId.identifier.string.data,
request.nodesToRead[i].nodeId.namespaceIndex);
}
UA_ReadResponse response = UA_Client_Service_read(client, request);
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Status: %i",
response.responseHeader.serviceResult);
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Responses: %li", response.resultsSize);
}
The result value is UA_STATUSCODE_GOOD but the number of responses is 0. It works fine when fetching the values one after the other like this:
void readNodeAtIndex(int index)
{
if (index >= nodeCount)
{
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Index out of Range");
return;
}
UA_Variant variant;
UA_Variant_init(&variant);
const UA_NodeId nodeId = nodesToRead[index];
UA_StatusCode retval = UA_Client_readValueAttribute(client, nodeId, &variant);
if (retval == UA_STATUSCODE_GOOD && UA_Variant_hasScalarType(&variant,
&UA_TYPES[UA_TYPES_DOUBLE]))
{
UA_Double value = *(UA_Double*)variant.data;
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Double-Value: %f", value);
}
else if (retval == UA_STATUSCODE_GOOD && UA_Variant_hasScalarType(&variant,
&UA_TYPES[UA_TYPES_BOOLEAN]))
{
UA_Boolean value = *(UA_Boolean*)variant.data;
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Boolean-Value: %i", value);
}
UA_Variant_clear(&variant);
}
The opc/ua server is setup like this:
server = Server()
space_url = "opc.tcp://localhost:61032"
server.set_endpoint(space_url)
server.set_security_policy([ua.SecurityPolicyType.NoSecurity])
node = server.get_objects_node()
You need to set nodesToReadSize:
UA_ReadRequest request;
UA_ReadRequest_init(&request);
UA_ReadValueId ids[nodeCount];
for (int i = 0; i < nodeCount; i++)
{
UA_ReadValueId_init(&ids[i]);
ids[i].attributeId = UA_ATTRIBUTEID_VALUE;
ids[i].nodeId = nodesToRead[i];
}
request.nodesToReadSize = nodeCount;
request.nodesToRead = ids;