0

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}");
                break;
            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);
                break;
            default:
                Console.WriteLine($"Message source '{messageSource}' not supported");
                break;
        }
    }
    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?

amplifier
  • 1,793
  • 1
  • 21
  • 55
  • why do you want to update reported properties on the cloud-side? Usually reported properties are only written by the device. Desired properties are written by the service side. – silent Apr 30 '19 at 12:34
  • @silent Because my hardware is unable to communicate directly with azure. – amplifier Apr 30 '19 at 15:30
  • the comment by @silent is correct, please put more details about your special device side, gateway, etc. Note, that the device twin represents a state (shadow) of the real device in the cloud between two facing endpoints such as a device and service. Each state transmission is going across those distributed sides. – Roman Kiss May 01 '19 at 20:33
  • @RomanKiss Cloud communicates with devices via a Java application. Devices can only send message only to this application. I need to manage states of devices. – amplifier May 02 '19 at 13:00
  • @RomanKiss My idea is to change reported properties by device application (implemented as a part of the Java application). So - I catch updates of desired properties by implementing IEventProcessor and route setup for directing desired property update to an event hub. When I get such an update, I send I command to real device, let's say, to update its firmware. When real device update its firmware, it send a telegram back to the java application, the application then updates reported properties - I can use DeviceClient object for it. – amplifier May 02 '19 at 13:03

1 Answers1

0

It is better to use the event trigger function either from IoT Hub or from IoT Event Hub.

Then while doing evenhub manipulation check for the desired and reported values.

Hope this answers your question.

e h
  • 1