Публикация объекта JSON через MQTT в AWS IoT из ESP32 с использованием среды C и ESP-IDF.

У меня есть структура IoT_Publish_Message_Params, которую необходимо подготовить, чтобы подготовить публикацию в AWS IoT. Приведенный ниже фрагмент отлично работает, когда я передаю строку в качестве полезной нагрузки.

/**
 * @brief Publish Message Parameters Type
 *
 * Defines a type for MQTT Publish messages. Used for both incoming and out going messages
 *
 */
typedef struct {
    QoS qos;        ///< Message Quality of Service
    uint8_t isRetained; ///< Retained messages are \b NOT supported by the AWS IoT Service at the time of this SDK release.
    uint8_t isDup;      ///< Is this message a duplicate QoS > 0 message?  Handled automatically by the MQTT client.
    uint16_t id;        ///< Message sequence identifier.  Handled automatically by the MQTT client.
    void *payload;      ///< Pointer to MQTT message payload (bytes).
    size_t payloadLen;  ///< Length of MQTT payload.
} IoT_Publish_Message_Params;

IoT_Publish_Message_Params paramsQOS0;
sprintf(cPayload, "%s : %d ", "Hello from HOME!!", i);

paramsQOS0.qos = QOS0;
paramsQOS0.payload = (void *) cPayload;
paramsQOS0.isRetained = 0;
paramsQOS0.payloadLen = strlen(cPayload);
rc = aws_iot_mqtt_publish(&client, TOPIC, TOPIC_LEN, &paramsQOS0);

Теперь я хочу отправить реальную полезную нагрузку JSON, и я не уверен, как я могу это сделать. Я пытался использовать cJSON для создания объекта JSON:

cJSON *root,*fmt;
root=cJSON_CreateObject();
paramsQOS0.payload = (void *) root
cJSON_AddItemToObject(root, "response", fmt=cJSON_CreateObject());
cJSON_AddNumberToObject(fmt,"hello", 123);
cJSON_AddNumberToObject(fmt,"bye", 321);

Однако мой вопрос заключается в том, что мне здесь передать как IoT_Publish_Message_Params.payloadLen? И как передать объект json в IoT_Publish_Message_Params.payload?


person Karan Raj Pradhan    schedule 09.09.2020    source источник
comment
Если у вас не будет много динамических сообщений и если вы все равно обрабатываете свое сообщение в лямбда-выражении или бэкэнд-сервисе, я предлагаю вам отправить его в двоичном виде. Работа с json может быть неэффективной для встроенных систем с небольшим объемом памяти, таких как ESP32. Но вы должны закодировать свое сообщение на уровне правил IoT, например «выбрать закодированное (*) как данные из /some/topic».   -  person Ozan ERTÜRK    schedule 21.10.2020


Ответы (2)


Как я вижу, у вас есть два варианта. Отправьте JSON в виде строки или необработанных байтов.

Если вы хотите отправить его в виде строки (например, {"CarType":"BMW","carID":"bmw123"}), вам нужно преобразовать его в строку. Нашел код здесь.

char* str = cJSON_Print(root);  
paramsQOS0.payload = (void *) str;
paramsQOS0.payloadLen = strlen(str);

Однако было бы намного эффективнее отправлять его в виде необработанных байтов. Для этого вам понадобится указатель на начало объекта и размер объекта в байтах. Быстро просканировав страницу GitHub, я нашел cJSON_GetArraySize, который, по-видимому, возвращает размер объекта.

Тогда это должно выглядеть примерно так:

paramsQOS0.payload = (void *) root;
paramsQOS0.payloadLen = cJSON_GetArraySize(root); // Not sure about this one

Отказ от ответственности. Я не использовал cJSON и не тестировал код. Я пытаюсь показать вам, в каком направлении двигаться.

person Hein Wessels    schedule 09.09.2020

IoT_Publish_Message_Params состоит из payload и payloadLen элементов, поэтому вы можете указать любую допустимую память и длину байтов, которые хотите отправить. В вашем первом примере вы предоставили статически выделенную строку и ее длину.

JSON — это протокол кодирования на основе строк, поэтому payload будет указателем char, а payloadLen можно вычислить с помощью strlen.

cJSON_Print возвращает строку json для объекта, используйте возвращенный им указатель и назначьте его payload.

Прочтите документацию по API cJSON, как его использовать. И ниже показано, как вы можете изменить свой код для отправки строки JSON.

IoT_Publish_Message_Params paramsQOS0;
char *json_str;

/* create a json message */
cJSON *root, *response;
root = cJSON_CreateObject();
response = cJSON_CreateObject();
cJSON_AddItemToObject(root, "response", response);
cJSON_AddNumberToObject(response, "hello", 123);
cJSON_AddNumberToObject(response, "bye", 321);

json_str = cJSON_Print(root);
if (json_str != NULL)
{
    paramsQOS0.qos = QOS0;
    paramsQOS0.isRetained = 0;
    paramsQOS0.payload = json_str;
    paramsQOS0.payloadLen = strlen(json_str);
    rc = aws_iot_mqtt_publish(&client, TOPIC, TOPIC_LEN, &paramsQOS0);
    free(json_str);
}

cJSON_Delete(root);
person shubham    schedule 18.09.2020