public async Task <IActionResult> Handler([HttpTrigger] HttpRequestMessage request) { var content = await request.Content.ReadAsStringAsync(); var eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(content); foreach (var ev in eventGridEvents) { if (ev.EventType == "Microsoft.EventGrid.SubscriptionValidationEvent") { var data = (SubscriptionValidationEventData)ev.Data; var responseData = new SubscriptionValidationResponse() { ValidationResponse = data.ValidationCode }; return(new OkObjectResult(responseData)); } else if (ev.EventType == "Microsoft.Devices.DeviceTelemetry") { log.LogInformation(ev.Data.ToString()); var data = (IotHubDeviceTelemetryEventData)ev.Data; var digitalTwinId = data.SystemProperties["iothub-connection-device-id"]; JObject jsonBody = default; if (data.Body is string) { var base64 = (string)data.Body; var bytes = Convert.FromBase64String(base64); var json = Encoding.UTF8.GetString(bytes); jsonBody = JsonConvert.DeserializeObject <JObject>(json); } else { jsonBody = (JObject)data.Body; } var humidity = jsonBody.Value <string>("Humidity"); log.LogInformation($"Device:{digitalTwinId} Humidity is:{humidity}"); //Update twin using device temperature var response = await client.PublishTelemetryAsync(digitalTwinId, null, JsonConvert.SerializeObject(new { Humidity = humidity })); log.LogInformation($"{digitalTwinId} humidity patched to {humidity}"); // send telemetry var responseT = await client.PublishTelemetryAsync(digitalTwinId, null, JsonConvert.SerializeObject(new { Humidity = humidity })); log.LogInformation($"{digitalTwinId} humidity sent {humidity}"); } } return(new OkResult()); }
public static async Task WriteTelemetry(DigitalTwinsClient client) { string input; string dtid = ""; string patchpayload = ""; Console.WriteLine("Sample json"); Console.WriteLine("{\"dtID\": \"hood-contosocar01\", \"path\": \"/IsOpenTelemetry\", \"value\": \"true\", \"type\": \"boolean\"}"); Console.Write("Add json:"); input = Console.ReadLine(); GetPatchPayload(input, ref dtid, ref patchpayload); Console.WriteLine("patchPayload = {0}", patchpayload); try { await client.PublishTelemetryAsync(dtid, patchpayload); } catch (RequestFailedException e) { Console.WriteLine($"Response {e.Status}: {e.Message}"); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } }
private async Task TelemetryTemperature(DigitalTwinsClient client, string digitalTwinId, double temperature) { var response = await client.PublishTelemetryAsync(digitalTwinId, null, JsonConvert.SerializeObject(new { Temperature = temperature })); log.LogInformation($"{digitalTwinId} temperature patched to {temperature}"); }
public async static void Run([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log) { log.LogInformation(eventGridEvent.Data.ToString()); if (adtInstanceUrl == null) { log.LogError("Application setting \"ADT_SERVICE_URL\" not set"); return; } try { // INSERT authentication code below here ManagedIdentityCredential cred = new ManagedIdentityCredential("https://digitaltwins.azure.net"); DigitalTwinsClient client = new DigitalTwinsClient(new Uri(adtInstanceUrl), cred, new DigitalTwinsClientOptions { Transport = new HttpClientTransport(httpClient) }); log.LogInformation($"Azure digital twins service client connection created."); // INSERT event processing code below here if (eventGridEvent != null && eventGridEvent.Data != null) { // Read 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 fanAlert = (bool)deviceMessage["properties"]["fanAlert"]; // cast directly to a bool var temperatureAlert = deviceMessage["properties"].SelectToken("temperatureAlert") ?? false; // JToken object var humidityAlert = deviceMessage["properties"].SelectToken("humidityAlert") ?? false; // JToken object log.LogInformation($"Device:{deviceId} fanAlert is:{fanAlert}"); log.LogInformation($"Device:{deviceId} temperatureAlert is:{temperatureAlert}"); log.LogInformation($"Device:{deviceId} humidityAlert is:{humidityAlert}"); var bodyJson = Encoding.ASCII.GetString((byte[])deviceMessage["body"]); JObject body = (JObject)JsonConvert.DeserializeObject(bodyJson); log.LogInformation($"Device:{deviceId} Temperature is:{body["temperature"]}"); log.LogInformation($"Device:{deviceId} Humidity is:{body["humidity"]}"); // INSERT ADT update code below here // Update twin properties var patch = new Azure.JsonPatchDocument(); patch.AppendReplace <bool>("/fanAlert", fanAlert); // already a bool patch.AppendReplace <bool>("/temperatureAlert", temperatureAlert.Value <bool>()); // convert the JToken value to bool patch.AppendReplace <bool>("/humidityAlert", humidityAlert.Value <bool>()); // convert the JToken value to bool await client.UpdateDigitalTwinAsync(deviceId, patch); // publish telemetry await client.PublishTelemetryAsync(deviceId, null, bodyJson); } } catch (Exception e) { log.LogError(e.Message); } }
private async Task UpdateDigitalTwinProperty(DigitalTwinsClient client, string deviceId, JToken body, string propertyName) { var propertyToken = body[propertyName]; if (propertyToken != null) { if (Constants.Telemetries.Contains(propertyName.ToUpper())) { var data = new Dictionary <string, double>(); data.Add(propertyName, propertyToken.Value <double>()); await client.PublishTelemetryAsync(deviceId, JsonConvert.SerializeObject(data)); } else { // Update twin using device property var uou = new UpdateOperationsUtility(); uou.AppendReplaceOp($"/{propertyName}", propertyToken.Value <double>()); await client.UpdateDigitalTwinAsync(deviceId, uou.Serialize()); } } }
public async void Run([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log) { log.LogInformation(eventGridEvent.Data.ToString()); if (adtInstanceUrl == null) { log.LogError("Application setting \"ADT_SERVICE_URL\" not set"); } try { //Authenticate with Digital Twins ManagedIdentityCredential cred = new ManagedIdentityCredential("https://digitaltwins.azure.net"); DigitalTwinsClient client = new DigitalTwinsClient(new Uri(adtInstanceUrl), cred, new DigitalTwinsClientOptions { Transport = new HttpClientTransport(httpClient) }); log.LogInformation($"ADT service client connection created."); if (eventGridEvent != null && eventGridEvent.Data != null) { 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"]; string deviceType = (string)deviceMessage["body"]["DeviceType"]; log.LogInformation($"Device:{deviceId} DeviceType is:{deviceType}"); switch (deviceType) { case "Gearbox": var gearboxPayload = new Dictionary <string, int> { ["GearInjNozzleTemp"] = deviceMessage["body"]["GearInjNozzleTemp"].Value <int>(), ["GearPump2Rpm"] = deviceMessage["body"]["GearPump2Rpm"].Value <int>(), ["GearLubricationPressure"] = deviceMessage["body"]["GearLubricationPressure"].Value <int>(), ["GearOilPressure"] = deviceMessage["body"]["GearOilPressure"].Value <int>(), ["GearOilTankLevel"] = deviceMessage["body"]["GearOilTankLevel"].Value <int>() }; await client.PublishTelemetryAsync(deviceId, Guid.NewGuid().ToString(), JsonConvert.SerializeObject(gearboxPayload)); log.LogInformation($"Published component telemetry message to twin '{deviceId}'."); break; case "Generator": var generatorPayload = new Dictionary <string, int> { ["generatingVoltage"] = deviceMessage["body"]["generatingVoltage"].Value <int>(), ["generatingPower"] = deviceMessage["body"]["generatingPower"].Value <int>(), ["GeneratorCableTemp"] = deviceMessage["body"]["GeneratorCableTemp"].Value <int>(), ["GeneratorFanMotorRpm"] = deviceMessage["body"]["GeneratorFanMotorRpm"].Value <int>(), ["GeneratorRpm"] = deviceMessage["body"]["GeneratorRpm"].Value <int>(), ["GeneratorWaterTemp"] = deviceMessage["body"]["GeneratorWaterTemp"].Value <int>(), ["GeneratorWaterOutPressure"] = deviceMessage["body"]["GeneratorWaterOutPressure"].Value <int>(), ["WindingL1Inv1Temp"] = deviceMessage["body"]["WindingL1Inv1Temp"].Value <int>(), ["WindingL2Inv1Temp"] = deviceMessage["body"]["WindingL2Inv1Temp"].Value <int>(), ["WindingL3Inv1Temp"] = deviceMessage["body"]["WindingL3Inv1Temp"].Value <int>() }; await client.PublishTelemetryAsync(deviceId, Guid.NewGuid().ToString(), JsonConvert.SerializeObject(generatorPayload)); log.LogInformation($"Published component telemetry message to twin '{deviceId}'."); break; } } } catch (Exception e) { log.LogError(e.Message); } }
/// <summary> /// Create a temporary component model, twin model and digital twin instance. /// Publish a telemetry message and a component telemetry message to the digital twin instance. /// </summary> public async Task RunSamplesAsync(DigitalTwinsClient client) { PrintHeader("PUBLISH TELEMETRY MESSAGE SAMPLE"); // For the purpose of this example we will create temporary models using a random model Ids. // We will also create temporary twin instances to publish the telemetry to. string componentModelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryComponentModelPrefix, client); string modelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryModelPrefix, client); string twinId = await GetUniqueTwinIdAsync(SamplesConstants.TemporaryTwinPrefix, client); string newComponentModelPayload = SamplesConstants.TemporaryComponentModelPayload .Replace(SamplesConstants.ComponentId, componentModelId); string newModelPayload = SamplesConstants.TemporaryModelWithComponentPayload .Replace(SamplesConstants.ModelId, modelId) .Replace(SamplesConstants.ComponentId, componentModelId); // Then we create the models. await client .CreateModelsAsync(new[] { newComponentModelPayload, newModelPayload }); // Get the models we just created AsyncPageable <DigitalTwinsModelData> models = client.GetModelsAsync(); await foreach (DigitalTwinsModelData model in models) { Console.WriteLine($"Successfully created model '{model.Id}'"); } // Create digital twin with Component payload. string twinPayload = SamplesConstants.TemporaryTwinPayload .Replace(SamplesConstants.ModelId, modelId); BasicDigitalTwin basicDigitalTwin = JsonSerializer.Deserialize <BasicDigitalTwin>(twinPayload); Response <BasicDigitalTwin> createDigitalTwinResponse = await client.CreateOrReplaceDigitalTwinAsync <BasicDigitalTwin>(twinId, basicDigitalTwin); Console.WriteLine($"Created digital twin '{createDigitalTwinResponse.Value.Id}'."); try { #region Snippet:DigitalTwinsSamplePublishTelemetry // construct your json telemetry payload by hand. await client.PublishTelemetryAsync(twinId, Guid.NewGuid().ToString(), "{\"Telemetry1\": 5}"); Console.WriteLine($"Published telemetry message to twin '{twinId}'."); #endregion Snippet:DigitalTwinsSamplePublishTelemetry #region Snippet:DigitalTwinsSamplePublishComponentTelemetry // construct your json telemetry payload by serializing a dictionary. var telemetryPayload = new Dictionary <string, int> { { "ComponentTelemetry1", 9 } }; await client.PublishComponentTelemetryAsync( twinId, "Component1", Guid.NewGuid().ToString(), JsonSerializer.Serialize(telemetryPayload)); Console.WriteLine($"Published component telemetry message to twin '{twinId}'."); #endregion Snippet:DigitalTwinsSamplePublishComponentTelemetry } catch (Exception ex) { FatalError($"Failed to publish a telemetry message due to: {ex.Message}"); } try { // Delete the twin. await client.DeleteDigitalTwinAsync(twinId); // Delete the models. await client.DeleteModelAsync(modelId); await client.DeleteModelAsync(componentModelId); } catch (RequestFailedException ex) when(ex.Status == (int)HttpStatusCode.NotFound) { // Digital twin or models do not exist. } catch (RequestFailedException ex) { FatalError($"Failed to delete due to: {ex.Message}"); } }
public async Task PublishTelemetry_Lifecycle() { // Setup // Create a DigitalTwinsClient instance. DigitalTwinsClient client = GetClient(); string wifiComponentName = "wifiAccessPoint"; string wifiModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.WifiModelIdPrefix).ConfigureAwait(false); string roomWithWifiModelId = await GetUniqueModelIdAsync(client, TestAssetDefaults.RoomWithWifiModelIdPrefix).ConfigureAwait(false); string roomWithWifiTwinId = await GetUniqueTwinIdAsync(client, TestAssetDefaults.RoomWithWifiTwinIdPrefix).ConfigureAwait(false); string eventRouteId = $"someEventRouteId-{GetRandom()}"; try { // Create an event route for the digital twins client. DigitalTwinsEventRoute eventRoute = await CreateEventRoute(client, eventRouteId).ConfigureAwait(false); // Create the models needed for the digital twin. await CreateModelsAndTwins(client, wifiModelId, roomWithWifiModelId, wifiComponentName, roomWithWifiTwinId).ConfigureAwait(false); // Act - Test publishing telemetry to a digital twin. var telemetryOptions = new PublishTelemetryOptions() { TimeStamp = default }; Response publishTelemetryResponse = await client.PublishTelemetryAsync(roomWithWifiTwinId, Recording.Random.NewGuid().ToString(), "{\"Telemetry1\": 5}", telemetryOptions).ConfigureAwait(false); // Assert publishTelemetryResponse.Status.Should().Be((int)HttpStatusCode.NoContent); // Act - Test publishing telemetry to a component in a digital twin. var componentTelemetryOptions = new PublishComponentTelemetryOptions() { TimeStamp = default }; var telemetryPayload = new Dictionary <string, int> { { "ComponentTelemetry1", 9 } }; Response publishComponentTelemetryResponse = await client .PublishComponentTelemetryAsync(roomWithWifiTwinId, wifiComponentName, Recording.Random.NewGuid().ToString(), JsonSerializer.Serialize(telemetryPayload), componentTelemetryOptions) .ConfigureAwait(false); // Assert publishComponentTelemetryResponse.Status.Should().Be((int)HttpStatusCode.NoContent); } catch (Exception ex) { Assert.Fail($"Failure in executing a step in the test case: {ex.Message}."); } finally { // clean up try { if (!string.IsNullOrWhiteSpace(eventRouteId)) { await client.DeleteEventRouteAsync(eventRouteId).ConfigureAwait(false); } if (!string.IsNullOrWhiteSpace(roomWithWifiTwinId)) { await client.DeleteDigitalTwinAsync(roomWithWifiTwinId).ConfigureAwait(false); } if (!string.IsNullOrWhiteSpace(roomWithWifiModelId)) { await client.DeleteModelAsync(roomWithWifiModelId).ConfigureAwait(false); } if (!string.IsNullOrWhiteSpace(wifiModelId)) { await client.DeleteModelAsync(wifiModelId).ConfigureAwait(false); } } catch (Exception ex) { Assert.Fail($"Test clean up failed: {ex.Message}"); } } }
public async static Task Run( [EventGridTrigger] EventGridEvent eventGridEvent, ILogger log) { // The ILogger interface is defined in the // Microsoft.Extensions.Logging namespace and aggregates most // logging patterns to a single method call. In this case, a log // entry is created at the Information level - other methods // exists for various levels including critical, error. etc. As the // Azure Function is running in the cloud, logging is essential // during development and production. log.LogInformation(eventGridEvent.Data.ToString()); // This code checks if the adtInstanceUrl environment variable // has been set - if not, the error is logged and the function exits. // This demonstrates the value of logging to capture the fact that // the function has been incorrectly configured. if (adtInstanceUrl == null) { log.LogError("Application setting \"ADT_SERVICE_URL\" not set"); return; } try { // REVIEW authentication code below here // Notice the use of the ManagedIdentityCredential class. // This class attempts authentication using the managed identity // that has been assigned to the deployment environment earlier. // Once the credential is returned, it is used to construct an // instance of the DigitalTwinsClient. The client contains // methods to retrieve and update digital twin information, like // models, components, properties and relationships. ManagedIdentityCredential cred = new ManagedIdentityCredential("https://digitaltwins.azure.net"); DigitalTwinsClient client = new DigitalTwinsClient( new Uri(adtInstanceUrl), cred, new DigitalTwinsClientOptions { Transport = new HttpClientTransport(httpClient) }); log.LogInformation($"Azure digital twins service client connection created."); // REVIEW event processing code below here if (eventGridEvent != null && eventGridEvent.Data != null) { // Read deviceId and temperature for IoT Hub JSON. // Notice the use of JSON deserialization to access the event data. // The message properties and systemProperties are // easily accessible using an indexer approach. JObject deviceMessage = (JObject)JsonConvert.DeserializeObject(eventGridEvent.Data.ToString()); string deviceId = (string)deviceMessage["systemProperties"]["iothub-connection-device-id"]; var fanAlert = (bool)deviceMessage["properties"]["fanAlert"]; // cast directly to a bool // However where properties are optional, such as temperatureAlert // and humidityAlert, the use of `SelectToken` and a // null-coalescing operation is required to prevent an // exception being thrown. var temperatureAlert = deviceMessage["properties"].SelectToken("temperatureAlert") ?? false; // JToken object var humidityAlert = deviceMessage["properties"].SelectToken("humidityAlert") ?? false; // JToken object log.LogInformation($"Device:{deviceId} fanAlert is:{fanAlert}"); log.LogInformation($"Device:{deviceId} temperatureAlert is:{temperatureAlert}"); log.LogInformation($"Device:{deviceId} humidityAlert is:{humidityAlert}"); // The message body contains the telemetry payload and is // ASCII encoded JSON. Therefore, it must first be decoded and // then deserialized before the telemetry properties can be accessed. var bodyJson = Encoding.ASCII.GetString((byte[])deviceMessage["body"]); JObject body = (JObject)JsonConvert.DeserializeObject(bodyJson); log.LogInformation($"Device:{deviceId} Temperature is:{body["temperature"]}"); log.LogInformation($"Device:{deviceId} Humidity is:{body["humidity"]}"); // REVIEW ADT update code below here // There are two approaches being used to apply data to the // digital twin - the first via property updates using a JSON // patch, the second via the publishing of telemetry data. // The ADT client utilizes a JSON Patch document to add or // update digital twin properties. The JSON Patch defines a // JSON document structure for expressing a sequence of // operations to apply to a JSON document. The various values // are added to the patch as append or replace operations, // and the ADT is then updated asynchronously. var patch = new Azure.JsonPatchDocument(); patch.AppendReplace <bool>("/fanAlert", fanAlert); // already a bool patch.AppendReplace <bool>("/temperatureAlert", temperatureAlert.Value <bool>()); // convert the JToken value to bool patch.AppendReplace <bool>("/humidityAlert", humidityAlert.Value <bool>()); // convert the JToken value to bool await client.UpdateDigitalTwinAsync(deviceId, patch); // publish telemetry // Notice that the telemetry data is handled differently than // the properties - rather than being used to set digital twin // properties, it is instead being published as telemetry // events. This mechanism ensures that the telemetry is // available to be consumed by any downstream subscribers to // the digital twins event route. await client.PublishTelemetryAsync(deviceId, null, bodyJson); } } catch (Exception e) { log.LogError(e.Message); } }
/// <summary> /// Create a temporary component model, twin model and digital twin instance. /// Publish a telemetry message and a component telemetry message to the digital twin instance. /// </summary> public async Task RunSamplesAsync(DigitalTwinsClient client) { PrintHeader("PUBLISH TELEMETRY MESSAGE SAMPLE"); // For the purpose of this example we will create temporary models using a random model Ids. // We will also create temporary twin instances to publish the telemetry to. string componentModelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryComponentModelPrefix, client); string modelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryModelPrefix, client); string twinId = await GetUniqueTwinIdAsync(SamplesConstants.TemporaryTwinPrefix, client); string newComponentModelPayload = SamplesConstants.TemporaryComponentModelPayload .Replace(SamplesConstants.ComponentId, componentModelId); string newModelPayload = SamplesConstants.TemporaryModelWithComponentPayload .Replace(SamplesConstants.ModelId, modelId) .Replace(SamplesConstants.ComponentId, componentModelId); // Then we create the models. await client .CreateModelsAsync(new[] { newComponentModelPayload, newModelPayload }); Console.WriteLine($"Successfully created models with Ids: {componentModelId}, {modelId}"); // Create digital twin with Component payload. string twinPayload = SamplesConstants.TemporaryTwinPayload .Replace(SamplesConstants.ModelId, modelId); await client.CreateDigitalTwinAsync(twinId, twinPayload); Console.WriteLine($"Created digital twin {twinId}."); try { #region Snippet:DigitalTwinsSamplePublishTelemetry // construct your json telemetry payload by hand. Response publishTelemetryResponse = await client.PublishTelemetryAsync(twinId, "{\"Telemetry1\": 5}"); Console.WriteLine($"Published telemetry message to twin with Id {twinId}. Response status: {publishTelemetryResponse.Status}"); #endregion Snippet:DigitalTwinsSamplePublishTelemetry #region Snippet:DigitalTwinsSamplePublishComponentTelemetry // construct your json telemetry payload by serializing a dictionary. var telemetryPayload = new Dictionary <string, int> { { "ComponentTelemetry1", 9 } }; Response publishTelemetryToComponentResponse = await client.PublishComponentTelemetryAsync( twinId, "Component1", JsonSerializer.Serialize(telemetryPayload)); Console.WriteLine($"Published component telemetry message to twin with Id {twinId}. Response status: {publishTelemetryToComponentResponse.Status}"); #endregion Snippet:DigitalTwinsSamplePublishComponentTelemetry } catch (Exception ex) { FatalError($"Failed to publish a telemetry message due to {ex.Message}"); } try { // Delete the twin. await client.DeleteDigitalTwinAsync(twinId); // Delete the models. await client.DeleteModelAsync(modelId); await client.DeleteModelAsync(componentModelId); } catch (RequestFailedException ex) when(ex.Status == (int)HttpStatusCode.NotFound) { // Digital twin or models do not exist. } catch (RequestFailedException ex) { FatalError($"Failed to delete due to {ex.Message}"); } }
public async void Run([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log) { try { // After this is deployed, you need to turn the Managed Identity Status to "On", // Grab Object Id of the function and assigned "Azure Digital Twins Owner (Preview)" role // to this function identity in order for this function to be authorized on ADT APIs. //Authenticate with Digital Twins var credentials = new DefaultAzureCredential(); log.LogInformation(credentials.ToString()); DigitalTwinsClient client = new DigitalTwinsClient( new Uri(adtServiceUrl), credentials, new DigitalTwinsClientOptions { Transport = new HttpClientTransport(httpClient) }); log.LogInformation($"ADT service client connection created."); if (eventGridEvent.Data.ToString().Contains("Alert")) { JObject alertMessage = (JObject)JsonConvert.DeserializeObject(eventGridEvent.Data.ToString()); string deviceId = (string)alertMessage["systemProperties"]["iothub-connection-device-id"]; var ID = alertMessage["body"]["TurbineID"]; var alert = alertMessage["body"]["Alert"]; log.LogInformation($"Device:{deviceId} Device Id is:{ID}"); log.LogInformation($"Device:{deviceId} Alert Status is:{alert}"); var updateProperty = new JsonPatchDocument(); updateProperty.AppendReplace("/Alert", alert.Value <bool>()); updateProperty.AppendReplace("/TurbineID", ID.Value <string>()); log.LogInformation(updateProperty.ToString()); try { await client.UpdateDigitalTwinAsync(deviceId, updateProperty); } catch (Exception e) { log.LogInformation(e.Message); } } else if (eventGridEvent != null && eventGridEvent.Data != null) { JObject deviceMessage = (JObject)JsonConvert.DeserializeObject(eventGridEvent.Data.ToString()); string deviceId = (string)deviceMessage["systemProperties"]["iothub-connection-device-id"]; var ID = deviceMessage["body"]["TurbineID"]; var TimeInterval = deviceMessage["body"]["TimeInterval"]; var Description = deviceMessage["body"]["Description"]; var Code = deviceMessage["body"]["Code"]; var WindSpeed = deviceMessage["body"]["WindSpeed"]; var Ambient = deviceMessage["body"]["Ambient"]; var Rotor = deviceMessage["body"]["Rotor"]; var Power = deviceMessage["body"]["Power"]; log.LogInformation($"Device:{deviceId} Device Id is:{ID}"); log.LogInformation($"Device:{deviceId} Time interval is:{TimeInterval}"); log.LogInformation($"Device:{deviceId} Description is:{Description}"); log.LogInformation($"Device:{deviceId} CodeNumber is:{Code}"); log.LogInformation($"Device:{deviceId} WindSpeed is:{WindSpeed}"); log.LogInformation($"Device:{deviceId} Ambient Temperature is:{Ambient}"); log.LogInformation($"Device:{deviceId} Rotor RPM is:{Rotor}"); log.LogInformation($"Device:{deviceId} Power is:{Power}"); var updateProperty = new JsonPatchDocument(); var turbineTelemetry = new Dictionary <string, Object>() { ["TurbineID"] = ID, ["TimeInterval"] = TimeInterval, ["Description"] = Description, ["Code"] = Code, ["WindSpeed"] = WindSpeed, ["Ambient"] = Ambient, ["Rotor"] = Rotor, ["Power"] = Power }; updateProperty.AppendAdd("/TurbineID", ID.Value <string>()); log.LogInformation(updateProperty.ToString()); try { await client.PublishTelemetryAsync(deviceId, Guid.NewGuid().ToString(), JsonConvert.SerializeObject(turbineTelemetry)); } catch (Exception e) { log.LogInformation(e.Message); } } } catch (Exception e) { log.LogInformation(e.Message); } }