open62541: опубликовать значение температуры - PullRequest
1 голос
/ 20 марта 2019

В настоящее время я пытаюсь опубликовать значение datetime И значение температуры в реализации OPC UA под названием open62541.

Для этого я использовал тестовый пример из репозитория open62541 github, так как он уже публикуетсятекущая дата / времяЯ попытался добавить еще один DSF (DataSetField) для значения температуры, как это было показано с датой и временем.Но он не публикует его.

Следующий фрагмент кода показывает, как я определяю методы для добавления 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);
}

В основной функции я затем вызываю оба метода, чтобы добавить ихдля PDS (Опубликованный набор данных):

addPubSubConnection(server, transportProfile, networkAddressUrl);
addPublishedDataSet(server);
addDataSetFieldTemperature(server);
addDataSetField(server);
addWriterGroup(server);
addDataSetWriter(server);

Значение температуры является простым двойным значением, так что я здесь не так делаю?Может быть, ошибка в подписанном клиентском приложении?

Для подписки на опубликованные значения я также использовал пример на github (файл называется tutorial_pubsub_subscribe.c) и пытаюсь проанализировать значения следующим образом.:

/* 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);
    }

Есть предложения?Заранее большое спасибо, если вам понадобится дополнительная информация по этому вопросу, пожалуйста, дайте мне знать, и я отредактирую вопрос!

РЕДАКТИРОВАТЬ: Если вы хотите посмотреть весь пример кода,Посмотрите ссылки ниже: Для заявки на публикацию: https://github.com/open62541/open62541/blob/master/examples/pubsub/tutorial_pubsub_publish.c

Для заявки на подписку: https://github.com/open62541/open62541/blob/master/examples/pubsub/tutorial_pubsub_subscribe.c

...