Azure IoT Hub and JSON message format

Hi,

I try to connect my photon with an Azure IoT Hub (not with the integration in the particle cloud). Currently I am using c# to send my message and that looks like this:

Sending message:
{"SensorValue":"870"} Properties: { 'DT-Telemetry': '1.0','DT-SensorHardwareId': 'ParticleSensorCO','CreationTimeUtc': '2019-05-31T08:40:50.3324194Z','x-ms-client-request-id': '34f4946d-6378-4b12-8591-be283bcf5e99', }

Now I use the v2 azure iot hub library and try to get the same JSON:

  DynamicJsonBuffer jsonBuffer(JSON_OBJECT_SIZE(12) + 200);
  JsonObject &root = jsonBuffer.createObject();

  root["SensorValue"] = 20 + random(-3, 3); 
  root["DT-Telemetry"] = "1.0";
  root["DT-SensorHardwareId"] = "ParticleSensor01ID";
  root["CreationTimeUtc"] = Time.format(Time.now(), TIME_FORMAT_ISO8601_FULL).c_str();
  root["x-ms-client-request-id"] = "7a6a292f-b52d-47f8-8369-55a7bf805bb3";

  root.printTo(telemetryBuffer, sizeof(telemetryBuffer));

  return telemetryBuffer;

The issue is offcourse that all the properties are added to the same JSON object. But how can I add my properties JSON message to the same message and get the same message as above in my c# sample?

I publish like this, but I think I have to add the properties when sending?

  if (hub.loop())
  {
    if (count++ % 25 == 0)
    {
      Serial.printf("msg id: %d\n", msgId);
      Serial.printf(telemetryToJson());
      hub.publish(telemetryToJson());
    }
  }

A lot of "same" somethings which makes it a bit confusing what's actually referenced by each.
e.g. "add ... message to same message" sounds very much like a circular reference.

I'm also not entirely sure about your original "message" as it doesn't seem to be a valid JSON - it's missing the enclosing curly braces and a comma preceding the Properties key (which also isn't wrapped in quotes).

If your message was expected to look like

{"SensorValue": "870"
, "Properties": 
  { "DT-Telemetry": "1.0"
  , "DT-SensorHardwareId": "ParticleSensorCO"
  , "CreationTimeUtc": "2019-05-31T08:40:50.3324194Z"
  , "x-ms-client-request-id": "34f4946d-6378-4b12-8591-be283bcf5e99" 
  } 
}

you'd need something like that to create it

  DynamicJsonBuffer jsonBuffer(JSON_OBJECT_SIZE(12) + 200);
  JsonObject &root = jsonBuffer.createObject();

  root["SensorValue"] = 20 + random(-3, 3); 

  JsonObject &properties = root.createNestedObject("Properties");
  properties["DT-Telemetry"] = "1.0";  
  properties["DT-SensorHardwareId"] = "ParticleSensor01ID";
  properties["CreationTimeUtc"] = (const char*)Time.format(TIME_FORMAT_ISO8601_FULL);
  properties["x-ms-client-request-id"] = "7a6a292f-b52d-47f8-8369-55a7bf805bb3";

Maybe if you show how you create your message in C# we may be able to understand how to create something as similar as possible.

@ScruffR thanks for the fast response! I have checked the ‘raw’ IoT Hub data from my C# and now the particle format:

From my C# sample:

Device: [particle01], 
Data:[{"SensorValue":"892"}] 
Properties: 
'DT-Telemetry': '1.0' 
'DT-SensorHardwareId': 'ParticleSensorCO'
'CreationTimeUtc': '2019-05-31T10:14:18.5400351Z'
'x-ms-client-request-id': '9631ec31-13ef-409d-85f9-9663ac1dcab0'

From particle now:

Device: [particle01], 
Data:[{"SensorValue":"20",
"Properties":{"DT-Telemetry":"1.0","DT-SensorHardwareId":"ParticleSensor01ID",
"CreationTimeUtc":"2019-05-31T10:12:51Z",
"x-ms-client-request-id":"7a6a292f-b52d-47f8-8369-55a7bf805bb3"}}]

So it looks they really add it as message property and not in the JSON. I do that also in C#:

serializer.WriteObject(stream, telemetryMessage);
var byteArray = stream.ToArray();
Message eventMessage = new Message(byteArray);
eventMessage.Properties.Add("DT-Telemetry", "1.0");
eventMessage.Properties.Add("DT-SensorHardwareId", $"{sensor.HardwareId}");
eventMessage.Properties.Add("CreationTimeUtc", DateTime.UtcNow.ToString("o"));
eventMessage.Properties.Add("x-ms-client-request-id", Guid.NewGuid().ToString());

Any idea?

That looks as if there were three individual entities in your original pessage (Device, Data & Properties) - non of which seem to be actual JSONs.
Your serializer doesn’t appear to create any of the former two.

Device is from the logging for the IoT Hub itself, so can be ignored and it is not send from the device itself. The same with Data, after the Data: the data from the sensor is displayed on the two examples

Which library are you using for hub?
If you are using AZURE_IOT_HUB_CLIENT the library examples illustrate how to add properties to a message

  MAP_HANDLE propMap = IoTHubMessage_Properties(msg.messageHandle);
  Map_AddOrUpdate(propMap, "PropName", propText)

However, I can’t find the implementation of Map_AddOrUpdate() in that lib :confused:

I am using the AzureIotHubClientV2 library (not the first version)

Not sure whether this library supports application properties.
The samples certainly don’t show how, nor can I find any function that would support properties.

I guess there is a way to “append” the properties to the raw body, but since I’m not using Azure I’m not (yet) aware of the required format.

Can you show more of your C# code (e.g. how you add the Data body).
Can you dump out the raw eventMessage string after you added the properties?

1 Like

Thanks for your work. Hopefully somebody has experience with this

Here is some background

As it seems the properties are not part of the payload but an “extension” to the topic.

That library doesn’t seem to provide a {property_bag} topic.
However with hub.directMessage() you should be able to append your own “property_bag” to the default topic.