IoT-Edge-Modbus: How to set the contentType to application/json and contentEncoding to UTF-8 for Iot Edge message.

NickKhoo-7526 31 Reputation points
2020-10-16T05:53:58.067+00:00

Hi All,

In reference to this article - https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-messages-d2c. The topic of interest is:-

"IoT Hub supports writing data to Azure Storage in the Apache Avro format as well as in JSON format. The default is AVRO. When using JSON encoding, you must set the contentType to application/json and contentEncoding to UTF-8 in the message system properties. Both of these values are case-insensitive. If the content encoding is not set, then IoT Hub will write the messages in base 64 encoded format."

How (or) where do I set the contentType? Is it somewhere in Iot Edge Device\Module Twin?

Appreciate your guidance.
Nick

Azure IoT Edge
Azure IoT Edge
An Azure service that is used to deploy cloud workloads to run on internet of things (IoT) edge devices via standard containers.
558 questions
Azure Blob Storage
Azure Blob Storage
An Azure service that stores unstructured data in the cloud as blobs.
2,594 questions
Azure IoT Hub
Azure IoT Hub
An Azure service that enables bidirectional communication between internet of things (IoT) devices and applications.
1,153 questions
0 comments No comments
{count} votes

Accepted answer
  1. Sander van de Velde | MVP 31,101 Reputation points MVP
    2020-10-18T17:38:01.97+00:00

    I forked the original repo to https://github.com/sandervandevelde/iot-edge-modbus and fixed a few things.

    Try my module and enjoy the .net core 3.1 version of iot-edge-modbus.

    Some considerations and limitations:

    Note: This is tested using the Linux version of the containers. Please perform your own extensive tests.

    1 person found this answer helpful.

2 additional answers

Sort by: Most helpful
  1. Sander van de Velde | MVP 31,101 Reputation points MVP
    2020-10-16T16:34:44.067+00:00

    Hello @NickKhoo-7526 , it seems the io-edge-modbus module does not support these extra properties (yet).

    @QuantumCache pointed to the right library where it's clear the ContentType and ContentEncoding are not part of the outputted messages (sent at line 350).

    There are four options to overcome this:

    1. create an issue in the iot-edge-modbus repository with a proposal for the two extra lines
    2. create a pull request in the iot-edge-modbus repository with the fix (adding the two lines at line 349)
    3. fork the iot-edge-modbus repository, fix it and push the module into your own repository
    4. Work around this issue (until fixed) with an extra module

    Step 1 and 2 will keep you waiting until the developer is ready to fix or pull your proposal/request.

    Step 3 is great if you have already (extensive) experience with building iot edge modules.

    Step 4 is not that hard to program. It's just generating the sample C# module in VS Code and adding two extra lines:

    1 person found this answer helpful.

  2. QuantumCache 20,186 Reputation points
    2020-10-16T06:25:01.187+00:00

    Hello @NickKhoo-7526 , Thanks for reaching out to us!

    Please check this C# sample repo where we demonstrate sending the sample message to IoTHub.

    In the below code block, please see

    ContentType = "application/json", ContentEncoding = Encoding.UTF8.ToString(),

     temperature = s_randomGenerator.Next(20, 35);  
                    humidity = s_randomGenerator.Next(60, 80);  
      
                    string dataBuffer = $"{<!-- -->{\"messageId\":{count},\"temperature\":{temperature},\"humidity\":{humidity}}}";  
      
                    using var eventMessage = new Message(Encoding.UTF8.GetBytes(dataBuffer))  
                    {  
                        ContentType = "application/json",  
                        ContentEncoding = Encoding.UTF8.ToString(),  
                    };  
      
                    const int TemperatureThreshold = 30;  
                    bool tempAlert = temperature > TemperatureThreshold;  
                    eventMessage.Properties.Add("temperatureAlert", tempAlert.ToString());  
                    Console.WriteLine($"\t{DateTime.Now}> Sending message: {count}, data: [{dataBuffer}]");  
      
                    await _deviceClient.SendEventAsync(eventMessage);  
    

    The IoTHub documentation has already provided these tutorials and samples in the early stages of the document. Please refer to one of those.

    32852-image.png

    Updated:

    In order for IoT Hub to know whether the message can be routed based on its body contents, the message must contain specific headers which describe the content and encoding of its body. In particular, messages must have both these headers for routing on message body to work:

    • Content type of "application/json"
    • Content encoding must match one of:
    • "utf-8"
    • "utf-16"
    • "utf-32"

    If you are using the Azure IoT Device SDKs, it is pretty straightforward to set the message headers to the required properties. If you are using a third-party protocol library, you can use this table to see how the headers manifest in each of the protocols that IoT Hub supports​:
    32928-image.png

    HTTP requires a custom header to account for batched messages;

    The message body has to be well-formed JSON in order for IoT Hub to route based on the message body. Messages can still be routed based on message headers regardless of whether the content type/content encoding are present. Content type and content encoding are only required for IoT Hub to route based on the body of the message.

    Please also look for IoT Hub message routing: now with routing on message body

    Please let us know if you need further help in this matter.

    2 people found this answer helpful.