public async Task RunAsync(string connectionString, ILogger logger, CancellationToken quitSignal)
    {
    
      this.logger = logger;
      
      deviceClient = DeviceClient.CreateFromConnectionString(connectionString, TransportType.Mqtt,
        new ClientOptions { ModelId = modelId });

      var refrigerator = new PnPComponent(deviceClient, logger);

      await refrigerator.SetPnPCommandHandlerAsync("Reset", async (MethodRequest req, object ctx) =>
      {
        logger.LogWarning("============> Processing Reset");
        MemoryLeak.FreeMemory();
        await refrigerator.ReportPropertyAsync("LastInitDateTime", DateTime.Now.ToUniversalTime());
        return await Task.FromResult(new MethodResponse(200));
      }, null);

      await refrigerator.SetPnPDesiredPropertyHandlerAsync<int>("RefreshInterval", (int newValue) =>
      {
        if (int.TryParse(newValue.ToString(), out int refreshInterval))
        {
          logger.LogWarning("=====================> RefreshInterval: " + refreshInterval);
          RefreshInterval = refreshInterval;
        }
      }, this);

      await Task.Run(async () =>
      {
        RefreshInterval = await refrigerator.ReadDesiredPropertyAsync<int>("RefreshInterval");
        if (RefreshInterval == default(int)) RefreshInterval = defaultRefreshInterval;

        await refrigerator.ReportPropertyAsync("SerialNumber", "1235435");
        await refrigerator.ReportPropertyAsync("LastInitDateTime", DateTime.Now.ToUniversalTime());

        int avg = 21;
        var rnd = new Random(Environment.TickCount);
        while (!quitSignal.IsCancellationRequested)
        {
          var payload = new
          {
            temp = avg + rnd.Next(10)
          };
          await refrigerator.SendTelemetryValueAsync(JsonConvert.SerializeObject(payload));
          logger.LogInformation("Sending CurrentTemperature: " + payload.temp);
          await Task.Delay(RefreshInterval * 1000);
          MemoryLeak.FillMemory();
        }
      });
    }
        public async Task RunDeviceAsync()
        {
            deviceClient = DeviceClient.CreateFromConnectionString(_connectionString, TransportType.Mqtt);

            deviceClient.SetConnectionStatusChangesHandler((ConnectionStatus status, ConnectionStatusChangeReason reason) =>
            {
                Console.WriteLine(status + " " + reason);
            });

            #region commands
            _ = deviceClient.SetMethodHandlerAsync("Reset", async(MethodRequest req, object ctx) =>
            {
                Console.WriteLine("============> Processing Reset");
                MemoryLeak.FreeMemory();
                RefreshInterval = 1;
                await ReportProps();
                return(await Task.FromResult(new MethodResponse(200)));
            }, null);
            #endregion

            #region desired props
            await deviceClient.SetDesiredPropertyUpdateCallbackAsync(async (TwinCollection desiredProperties, object ctx) =>
            {
                Console.WriteLine($"Received desired updates [{desiredProperties.ToJson()}]");
                await ReportWritablePropertyAsync("RefreshInterval", RefreshInterval, 202, "Refresh Interval Pending", desiredProperties.Version);

                string desiredPropertyValue = GetPropertyValueIfFound(desiredProperties, "RefreshInterval");
                if (int.TryParse(desiredPropertyValue, out int refreshInterval))
                {
                    //await Task.Delay(refreshInterval * 1000);
                    _logger.LogWarning("=====================> RefreshInterval: " + refreshInterval);
                    RefreshInterval = refreshInterval;
                    await ReportWritablePropertyAsync("RefreshInterval", RefreshInterval, 200, "Refresh Interval Updated", desiredProperties.Version);
                }
                else
                {
                    await ReportWritablePropertyAsync("RefreshInterval", RefreshInterval, 400, "Refresh Interval Invalid", desiredProperties.Version);
                }
                await Task.FromResult("200");
            }, null);

            async Task ReadDesiredProperties()
            {
                var twin = await deviceClient.GetTwinAsync();

                var    desiredProperties    = twin.Properties.Desired;
                string desiredPropertyValue = GetPropertyValueIfFound(desiredProperties, "RefreshInterval");

                if (int.TryParse(desiredPropertyValue, out int refreshInterval))
                {
                    RefreshInterval = refreshInterval;
                    _logger.LogInformation("Refresh Interval intialized to :" + refreshInterval.ToString());
                    await ReportWritablePropertyAsync("RefreshInterval", refreshInterval, 200, "RefreshInterval updated on read", desiredProperties.Version);
                }
                else
                {
                    _logger.LogWarning("Refresh interval cant be assigned to int: " + desiredPropertyValue);
                }
            }

            async Task ReportWritablePropertyAsync(string propertyName, object payload, int statuscode, string description, long version)
            {
                //var root = new TwinCollection();
                var propertyVal = new TwinCollection();
                var valtc       = new TwinCollection();

                valtc["value"]            = payload;
                valtc["sc"]               = statuscode;
                valtc["sd"]               = description;
                valtc["sv"]               = version;
                propertyVal[propertyName] = valtc;
                //root[this.componentName] = propertyVal;

                //var reportedVal = root;

                await deviceClient.UpdateReportedPropertiesAsync(propertyVal);

                Console.WriteLine($"Reported writable property [{propertyName}] - {JsonConvert.SerializeObject(payload)}");
            }

            #endregion

            #region reported props
            async Task ReportProps()
            {
                var props = new TwinCollection();

                props["SerialNumber"]     = "0032434";
                props["LastInitDateTime"] = DateTime.Now.ToUniversalTime();
                await deviceClient.UpdateReportedPropertiesAsync(props);
            }

            #endregion

            #region telemetry
            async Task SendTelemetryValueAsync(object telemetryPayload)
            {
                var message = new Message(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(telemetryPayload)))
                {
                    ContentType = "application/json", ContentEncoding = "utf-8"
                };
                await deviceClient.SendEventAsync(message);
            }

            #endregion

            await Task.Run(async() =>
            {
                await ReadDesiredProperties();
                await ReportProps();
                int avg = 21;
                var rnd = new Random(Environment.TickCount);
                while (!_quitSignal.IsCancellationRequested)
                {
                    var payload = new
                    {
                        temp = avg + rnd.Next(10)
                    };
                    await SendTelemetryValueAsync(payload);
                    _logger.LogInformation("Sending CurrentTemperature: " + payload.temp);
                    await Task.Delay(RefreshInterval * 1000);
                    MemoryLeak.FillMemory();
                }
            });
        }