protected async override Task OnActivateAsync()
        {
            try
            {
                // Initialize States
                await StateManager.TryAddStateAsync(QueueState, new Queue<Payload>());
                var result = await StateManager.TryGetStateAsync<Device>(MetadataState);
                if (!result.HasValue)
                {
                    // The device id is a string with the following format: device<number>
                    var deviceIdAsString = Id.ToString();
                    long deviceId;
                    long.TryParse(deviceIdAsString.Substring(6), out deviceId);

                    var metadata = new Device
                    {
                        DeviceId = deviceId,
                        Name = deviceIdAsString,
                        MinThreshold = MinThresholdDefault,
                        MaxThreshold = MaxThresholdDefault,
                        Model = Unknown,
                        Type = Unknown,
                        Manufacturer = Unknown,
                        City = Unknown,
                        Country = Unknown
                    };
                    await StateManager.TryAddStateAsync(MetadataState, metadata);
                }

                // Create EventHubClient
                CreateEventHubClient();
            }
            catch (Exception ex)
            {
                // Trace exception as ETW event
                ActorEventSource.Current.Error(ex);

                // Trace exception using Application Insights
                Program.TelemetryClient.TrackException(ex, new Dictionary<string, string>
                {
                    { "ActorType", "DeviceActor"},
                    { "ActorId", Id.ToString()},
                    { "ServiceName", ActorService.Context.ServiceName.ToString()},
                    { "Partition", ActorService.Context.PartitionId.ToString()},
                    { "Node", ActorService.Context.NodeContext.NodeName}
                });
            }
        }
        public async Task<Device> GetData()
        {
            // Retrieve Metadata from the Actor state
            Device metadata;
            var metadataResult = await StateManager.TryGetStateAsync<Device>(MetadataState);
            if (metadataResult.HasValue)
            {
                metadata = metadataResult.Value;
            }
            else
            {
                // The device id is a string with the following format: device<number>
                var deviceIdAsString = Id.ToString();
                long deviceId;
                long.TryParse(deviceIdAsString.Substring(6), out deviceId);

                metadata = new Device
                {
                    DeviceId = deviceId,
                    Name = deviceIdAsString,
                    MinThreshold = MinThresholdDefault,
                    MaxThreshold = MaxThresholdDefault,
                    Model = Unknown,
                    Type = Unknown,
                    Manufacturer = Unknown,
                    City = Unknown,
                    Country = Unknown
                };
            }
            return metadata;
        }
        public async Task SetData(Device data)
        {
            // Validate parameter
            if (data == null)
            {
                return;
            }

            // Save metadata to Actor state
            await StateManager.SetStateAsync(MetadataState, data);

            // Trace ETW event
            ActorEventSource.Current.Metadata(data);

            // Track Application Insights event
            Program.TelemetryClient.TrackEvent(new EventTelemetry
            {
                Name = "Metadata",
                Properties =
                            {
                                {"DeviceId", data.DeviceId.ToString(CultureInfo.InvariantCulture)},
                                {"Name", data.Name},
                                {"City", data.City},
                                {"Country", data.Country},
                                {"Manufacturer", data.Manufacturer},
                                {"Model", data.Model},
                                {"Type", data.Type},
                                {"MinThreshold", data.MinThreshold.ToString(CultureInfo.InvariantCulture)},
                                {"MaxThreshold", data.MaxThreshold.ToString(CultureInfo.InvariantCulture)},
                                {"ActorType", "DeviceActor"},
                                {"ActorId", Id.ToString()},
                                {"ServiceName", ActorService.Context.ServiceName.ToString()},
                                {"Partition", ActorService.Context.PartitionId.ToString()},
                                {"Node", ActorService.Context.NodeContext.NodeName}
                            }
            });
        }
 public async Task SetDevice(Device device)
 {
     try
     {
         var proxy = GetActorProxy(device.DeviceId);
         if (proxy != null)
         {
             await proxy.SetData(device);
         }
     }
     catch (AggregateException ex)
     {
         if (ex.InnerExceptions?.Count > 0)
         {
             foreach (var exception in ex.InnerExceptions)
             {
                 ServiceEventSource.Current.Message(exception.Message);
             }
         }
     }
     catch (Exception ex)
     {
         ServiceEventSource.Current.Message(ex.Message);
     }
 }
 public void Metadata(Device device)
 {
     if (device != null && IsEnabled())
     {
         Metadata(device.DeviceId,
                  device.Name,
                  device.City,
                  device.Country,
                  device.Manufacturer,
                  device.Model,
                  device.Type,
                  device.MinThreshold,
                  device.MaxThreshold);
     }
 }
 public void Alert(Device device, Payload payload)
 {
     if (device != null && payload != null && IsEnabled())
     {
         Alert(device.DeviceId,
               device.Name,
               device.City,
               device.Country,
               device.Manufacturer,
               device.Model,
               device.Type,
               device.MinThreshold,
               device.MaxThreshold,
               payload.Value,
               payload.Status,
               payload.Timestamp);
     }
 }