public LuGaMqtt(
            LuGaMqttConfig config,
            IRepository <Reading> readingRepository)
        {
            var factory = new MqttFactory();

            var options = new ManagedMqttClientOptionsBuilder()
                          .WithAutoReconnectDelay(TimeSpan.FromSeconds(Constants.ReconnectDelay))
                          .WithClientOptions(new MqttClientOptionsBuilder()
                                             .WithClientId(config.ClientId)
                                             .WithTcpServer(config.Host, config.Port)
                                             .WithCredentials(config.Username, config.Password)
                                             .Build())
                          .Build();

            _client = factory.CreateManagedMqttClient();

            _client.ApplicationMessageReceived += (s, e) =>
            {
                if (e.ApplicationMessage.Topic.IndexOf("/value", StringComparison.Ordinal) <= -1 ||
                    e.ApplicationMessage.Topic.IndexOf("$", StringComparison.Ordinal) != -1)
                {
                    return;
                }

                var reading = new Reading();
                var pulled  = e.ApplicationMessage.Topic.Split("/");

                reading.DeviceId    = pulled[1];
                reading.ReadingType = pulled[2];
                reading.Value       = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
                reading.TimeStamp   = DateTime.UtcNow;

                Console.WriteLine($"DeviceId: {reading.DeviceId}");
                Console.WriteLine($"ReadingType: {reading.ReadingType}");
                Console.WriteLine($"Value: {reading.Value}");

                readingRepository.Add(reading);
            };

            _client.Connected += async(s, e) =>
            {
                Console.WriteLine(Constants.ConnectedOutput);
                await _client.SubscribeAsync(
                    new TopicFilterBuilder()
                    .WithTopic(Constants.SubscribeTopic)
                    .Build()
                    );
            };

            _client.Disconnected += (s, e) => {
                Console.WriteLine(Constants.DisconnectedOutput);
            };

            Task.Run(() => Background(options));
        }
        static int Main(string[] args)
        {
            Console.OutputEncoding = Encoding.UTF8;

            string environment = Environment.GetEnvironmentVariable(Constants.Environment);

            if (String.IsNullOrWhiteSpace(environment))
            {
                throw new ArgumentNullException("Environment not found in:" + Constants.Environment);
            }

            Console.WriteLine("Environment: {0}", environment);

            // all passwords should be stored in
            // %APPDATA%\microsoft\UserSecrets\luga\secrets.json
            // https://docs.microsoft.com/en-us/aspnet/core/security/app-secrets?tabs=visual-studio

            var builder = new ConfigurationBuilder()
                          .SetBasePath(Directory.GetCurrentDirectory())
                          .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                          .AddJsonFile($"appsettings.{environment}.json", optional: true)
                          .AddEnvironmentVariables();

            if (environment != null && environment.Contains("Dev"))
            {
                builder.AddUserSecrets <Program>();
            }

            var cfg = builder.Build();

            Console.WriteLine($"Connection string: {cfg[Constants.ConnectionString]}");

            return((int)HostFactory.Run(x =>
            {
                var mqttConfig = new LuGaMqttConfig
                                 (
                    cfg[Constants.Username],
                    cfg[Constants.Password],
                    cfg[Constants.ClientId],
                    cfg[Constants.Host],
                    Convert.ToInt32(cfg[Constants.Port]));

                var readingRepository = new ReadingsRepository(cfg[Constants.ConnectionString]);

                x.Service(y => new LuGaMqtt(mqttConfig, readingRepository));

                x.SetServiceName(Constants.ServiceName);
                x.SetDisplayName(Constants.ServiceName);
            }));
        }