I am currently trying to publish a datetime value AND a temperature value with the OPC UA implementation called open62541.
For this, I have been using the test example from the open62541 github repository as it is already publishing the current datetime. I have tried to add another DSF(DataSetField) for the temperature value like it was shown with the datetime. But it won't publish it.
The following code snippet shows how I define methods for adding the DataSetFields:
/**
* **DataSetField handling**
*
* The DataSetField (DSF) is part of the PDS and describes exactly one published
* field. */
static void
addDataSetField(UA_Server *server) {
/* Add a field to the previous created PublishedDataSet */
UA_NodeId dataSetFieldIdent;
UA_DataSetFieldConfig dataSetFieldConfig;
memset(&dataSetFieldConfig, 0, sizeof(UA_DataSetFieldConfig));
dataSetFieldConfig.dataSetFieldType = UA_PUBSUB_DATASETFIELD_VARIABLE;
dataSetFieldConfig.field.variable.fieldNameAlias = UA_STRING("Server localtime");
dataSetFieldConfig.field.variable.promotedField = UA_FALSE;
dataSetFieldConfig.field.variable.publishParameters.publishedVariable =
UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME);
dataSetFieldConfig.field.variable.publishParameters.attributeId =
UA_ATTRIBUTEID_VALUE;
UA_Server_addDataSetField(server, publishedDataSetIdent,
&dataSetFieldConfig, &dataSetFieldIdent);
}
static void
addDataSetFieldTemperature(UA_Server *server) {
/* Add a field to the previous created PublishedDataSet */
UA_NodeId dataSetFieldIdent;
UA_DataSetFieldConfig dataSetFieldConfig;
memset(&dataSetFieldConfig, 0, sizeof(UA_DataSetFieldConfig));
dataSetFieldConfig.dataSetFieldType = UA_PUBSUB_DATASETFIELD_VARIABLE;
dataSetFieldConfig.field.variable.fieldNameAlias = UA_STRING("Temperature");
dataSetFieldConfig.field.variable.promotedField = UA_FALSE;
dataSetFieldConfig.field.variable.publishParameters.publishedVariable =
UA_NODEID_NUMERIC(0, 50);
dataSetFieldConfig.field.variable.publishParameters.attributeId =
UA_ATTRIBUTEID_VALUE;
UA_Server_addDataSetField(server, publishedDataSetIdent,
&dataSetFieldConfig,
&dataSetFieldIdent);
}
In the main function, I then call both methods to add them to the PDS (PublishedDataSet):
addPubSubConnection(server, transportProfile, networkAddressUrl);
addPublishedDataSet(server);
addDataSetFieldTemperature(server);
addDataSetField(server);
addWriterGroup(server);
addDataSetWriter(server);
The temperature value is a simple double value, so what am I doing wrong here? Maybe the error is within the subscribed client application?
For subscribing to the values published, I have also used the example on github (the file is called tutorial_pubsub_subscribe.c) and I am trying to parse the values as followed:
/* Loop over the fields and print well-known content types */
for(int i = 0; i < dsm->data.keyFrameData.fieldCount; i++) {
const UA_DataType *currentType = dsm->data.keyFrameData.dataSetFields[i].value.type;
if(currentType == &UA_TYPES[UA_TYPES_BYTE]) {
UA_Byte value = *(UA_Byte *)dsm->data.keyFrameData.dataSetFields[i].value.data;
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
"Message content: [Byte] \tReceived data: %i", value);
} else if (currentType == &UA_TYPES[UA_TYPES_DATETIME]) {
UA_DateTime value = *(UA_DateTime *)dsm->data.keyFrameData.dataSetFields[i].value.data;
UA_DateTimeStruct receivedTime = UA_DateTime_toStruct(value);
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
"Message content: [DateTime] \t"
"Received date: %02i-%02i-%02i Received time: %02i:%02i:%02i",
receivedTime.year, receivedTime.month, receivedTime.day,
receivedTime.hour, receivedTime.min, receivedTime.sec);
} else if(currentType == &UA_TYPES[UA_TYPES_UINT16]) {
UA_UInt16 receivedTemp =
*(UA_UInt16 *)dsm->data.keyFrameData.dataSetFields[i].value.data;
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
"Message content: [UA_UInt16] \t"
"Received temperature: %i",
receivedTemp);
}
Any suggestions? Thank you so much in advance, if you need any further details on this issue, please let me know and I will further edit the question!
EDIT: If you want to have a look to the whole sample code, please have a look at the links below: For the publish application: https://github.com/open62541/open62541/blob/master/examples/pubsub/tutorial_pubsub_publish.c
For the subscribe application: https://github.com/open62541/open62541/blob/master/examples/pubsub/tutorial_pubsub_subscribe.c