Azure Device Twin desired and reported properties synchronization RRS feed

  • Question

  • What is the most appropriate way to synchronize desired and reported properties.

    Currently how I think it should be:

    1. On the Azure portal setup routing of "desired property update" event to IotHub.
    2. Create class implementing IEventProcessor:
    internal class LoggingEventProcessor: IEventProcessor {
     public Task OpenAsync(PartitionContext context) {
      Console.WriteLine($ "LoggingEventProcessor opening, partition: {context.PartitionId}");
      return Task.CompletedTask;
     public async Task CloseAsync(PartitionContext context, CloseReason reason) {
      Console.WriteLine($ "LoggingEventProcessor closing, partition: {context.PartitionId}, reason: {reason}");
      if (reason == CloseReason.Shutdown) {
       await context.CheckpointAsync();
     public Task ProcessEventsAsync(PartitionContext context, IEnumerable < EventData > messages) {
      foreach(var msg in messages) {
       string messageSource = (string) msg.SystemProperties["iothub-message-source"];
       var deviceId = msg.SystemProperties["iothub-connection-device-id"];
       var payload = Encoding.ASCII.GetString(msg.Body.Array, msg.Body.Offset, msg.Body.Count);
       switch (messageSource) {
        case "deviceLifecycleEvents":
         Twin tw = JsonConvert.DeserializeObject < Twin > (payload);
         Console.WriteLine($ "Events received on partition: {context.PartitionId}, deviceId: {deviceId}, payload: {payload}");
        case "twinChangeEvents":
         DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(connectionStringBuilder.ToString(), Microsoft.Azure.Devices.Client.TransportType.Amqp);
         var props = new TwinCollection();
         props["temperature"] = payload;
         return deviceClient.UpdateReportedPropertiesAsync(props);
         Console.WriteLine($ "Message source '{messageSource}' not supported");
      return context.CheckpointAsync();
     public Task ProcessErrorAsync(PartitionContext context, Exception error) {
      Console.WriteLine($ "LoggingEventProcessor closing, partition: {context.PartitionId}, reason: {error.Message}");
      return Task.CompletedTask;

    Any better idea? Anything with Microsoft.Azure.Devices.JobClient or so?

    Wednesday, May 1, 2019 5:20 PM

All replies

  • Hello Ruslan,

    Did you see this doc?:

    See specifically the section "Receive twin notifications"

    "This operation allows the solution back end to be notified when the twin is modified. To do so, your IoT solution needs to create a route and to set the Data Source equal to twinChangeEvents. By default, no such routes pre-exist, so no twin notifications are sent. If the rate of change is too high, or for other reasons such as internal failures, the IoT Hub might send only one notification that contains all changes. Therefore, if your application needs reliable auditing and logging of all intermediate states, you should use device-to-cloud messages. The twin notification message includes properties and body"

    You are using D2C in the code you shared above, that's because you need reliable auditing? In your code looks like you are updating a reported property from the Service side, that's not possible... Reported properties can be updated only by the device.

    Read more here:

    • Desired properties. Used along with reported properties to synchronize device configuration or conditions. The solution back end can set desired properties, and the device app can read them. The device app can also receive notifications of changes in the desired properties.
    • Reported properties. Used along with desired properties to synchronize device configuration or conditions. The device app can set reported properties, and the solution back end can read and query them.

    Thank you!

    Thursday, May 2, 2019 3:25 PM