Hi @Ho Kin Haw Greetings! Welcome to Microsoft Q&A forum. Thank you for posting this question here.
Analyzing the attached Azure function log image, I could tell that your function is not processing the data correctly. My first observation is that the message body is encoded. Please refer the below image for details.
The code is trying to extract device ID and the message properties from this body. Since it is encoded, it is failing to fetch the proper data, and I suspect you are getting null
for these values. You can also confirm this behavior by observing the logs and identify that your following logger statement is not getting executed.
logger.LogInformation($"Received telemetry data for device:{deviceId}. Temperature: {temperature}, Humidity: {humidity}");
To resolve this issue, make sure that the telemetry message pushed from your simulator has utf-8
encoded and is in the content type form of JSON
. Please refer the below sample code that shows how you can set this parameters.
var telemetryDataPoint = new
{
Level_of_Material = currentTemperature
};
var messageString = JsonSerializer.Serialize(telemetryDataPoint);
var message = new Microsoft.Azure.Devices.Client.Message(Encoding.UTF8.GetBytes(messageString))
{
ContentType = "application/json",
ContentEncoding = "utf-8"
};
await deviceClient.SendEventAsync(message);
Console.WriteLine($"{DateTime.Now} > Sending message: {messageString}");
Once you have the ContentType
and ContentEncoding
for the message set as above, you can see that the message received by Azure function appears in plain text. Please find the below image of the event processed on my Azure function for reference.
Here is the snippet of the Azure function sample I tested for extracting the data and updating the Digital Twin. Kindly notice that there is a difference in the approach of extracting the data from the event.
var credentials = new DefaultAzureCredential();
DigitalTwinsClient client = new DigitalTwinsClient(
new Uri(adtServiceUrl), credentials, new DigitalTwinsClientOptions
{ Transport = new HttpClientTransport(httpClient) });
log.LogInformation($"ADT service client connection created.");
if (eventGridEvent != null && eventGridEvent.Data != null)
{
try{
log.LogInformation(eventGridEvent.Data.ToString());
// Reading deviceId and temperature for IoT Hub JSON
JObject deviceMessage = (JObject)JsonConvert.DeserializeObject(eventGridEvent.Data.ToString());
string deviceId = (string)deviceMessage["systemProperties"]["iothub-connection-device-id"];
var temperature = deviceMessage["body"]["Level_of_Material"];
log.LogInformation($"Device:{deviceId} Level_of_Material is:{temperature}");
//Update twin using device temperature
var updateTwinData = new JsonPatchDocument();
updateTwinData.AppendReplace("/Level_of_Material", temperature.Value<double>());
await client.UpdateDigitalTwinAsync("deviceId", updateTwinData);
}
catch(Exception ex){
Console.WriteLine($"Error : {ex.Message}");
}
}
I could see my Digital Twin property updating without any issues.
Please note that the method UpdateDigitalTwinAsync works when there is an initial value on the Digital Twin property. Please make sure you set an initial value either using the DTDL model of the Digital Twin explorer portal for smooth functioning.
Hope this helps! Please let us know if you need any additional assistance on this.
If the response helped, please do click Accept Answer and Yes for the answer provided. Doing so would help other community members with similar issue identify the solution. I highly appreciate your contribution to the community.