Search code examples
azurearduinoiothub

Arduino Azure IoT library contains messages with base64 encoding


I'm using the Azure IoT library for Arduino. Based on the example in the GitHub repository for ESP32, please see: https://github.com/Azure/azure-sdk-for-c-arduino/tree/main/examples/Azure_IoT_Hub_ESP32

I'm sending messages to the Azure IoT Hub based on sensor data, and from there, I'm transferring them to Cosmos DB. However, I noticed that the messages are base64 encoded. My code for sending messages in my Arduino file looks like this:

static void generateTelemetryPayload(const char* activity) {
    time_t now = time(NULL);
    struct tm* timeinfo;
    char timeStr[64];

    timeinfo = localtime(&now);
    strftime(timeStr, sizeof(timeStr), "%Y-%m-%dT%H:%M:%S", timeinfo);

    DynamicJsonDocument json(1024);

    json["category"] = "human_presence";

    if (activity != "") {
        json["activity"] = activity;
    }

    json["zone"] = zone;
    json["timestamp"] = getFormattedTime();

    char mqtt_message[128];
    serializeJson(json, mqtt_message);
    telemetry_payload = mqtt_message;
}

static void sendTelemetry(const char* message) {
    Logger.Info("Sending telemetry ...");

    if (az_result_failed(az_iot_hub_client_telemetry_get_publish_topic(
        &client, NULL, telemetry_topic, sizeof(telemetry_topic), NULL))) {
        Logger.Error("Failed az_iot_hub_client_telemetry_get_publish_topic");
        return;
    }

    generateTelemetryPayload(message);

    if (esp_mqtt_client_publish(
        mqtt_client,
        telemetry_topic,
        (const char*)telemetry_payload.c_str(),
        telemetry_payload.length(),
        MQTT_QOS1,
        DO_NOT_RETAIN_MSG) == 0) {
        Logger.Error("Failed publishing");
    } else {
        Logger.Info("Message published successfully");
    }
}

I found a possible solution that might help. To send your messages as JSON instead of a base64 string, adding UTF-8 and application/json encoding to the message. I don't know how to implement this with the Arduino library. Is there a possibility to send my messages as JSON instead of a base64 string?


Solution

  • Last week, I delved into this issue and discovered a solution. References suggesting that the solution involved adding UTF-8 and application/json encoding to the message. I couldn't find any solutions specific to my issue, especially in combination with the Azure IoT Library for Arduino. After several attempts, I found a solution: adding the string $.ct=application%2Fjson%3Bcharset%3Dutf-8 to the topic resolves the issue. If anyone else is facing the same problem, this is the solution:

    static void send_telemetry(const char* message, int time = -1)
    {
        az_span telemetry = AZ_SPAN_FROM_BUFFER(telemetry_payload);
    
        Logger.Info("Sending telemetry ...");
    
        // The topic could be obtained just once during setup,
        // however if properties are used the topic need to be generated again to
        // reflect the current values of the properties.
        if (az_result_failed(az_iot_hub_client_telemetry_get_publish_topic(
                &hub_client, NULL, telemetry_topic, sizeof(telemetry_topic), NULL)))
        {
            Logger.Error("Failed az_iot_hub_client_telemetry_get_publish_topic");
            return;
        }
    
        get_telemetry_payload(telemetry, message, time, &telemetry);
    
        if (esp_mqtt_client_publish(
            mqtt_client,
            (std::string(telemetry_topic) + "$.ct=application%2Fjson%3Bcharset%3Dutf-8").c_str(),
            (const char*)az_span_ptr(telemetry),
            az_span_size(telemetry),
            MQTT_QOS1,
            DO_NOT_RETAIN_MSG) < 0)
        {
            Logger.Error("Failed publishing");
        }
        else
        {
            Logger.Info("Message published successfully");
        }
    }