private void HandleMqttMessage(MqttApplicationMessageReceivedEventArgs e)
        {
            var topics  = e.ApplicationMessage.Topic.Split('/');
            var device  = topics[1];
            var command = topics[3];
            var value   = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);

            int dataType;

            if (!int.TryParse(command, out dataType))
            {
                _logger.LogInformation("Invalid format for data type {DataType}", command);
                return;
            }

            if (!AllowedCodes.Contains(dataType))
            {
                _logger.LogInformation("Unknown data type {DataType}", dataType);
                return;
            }

            int payLoad;

            if (string.IsNullOrEmpty(value) || !int.TryParse(value, out payLoad))
            {
                _logger.LogInformation("Invalid payload format. Payload: {Payload}", value);
                return;
            }

            var limits = CodeMinMax[dataType];

            if (payLoad < limits.min || payLoad > limits.max)
            {
                _logger.LogInformation("Payload out of bounds. Payload: {Payload}, min: {Min}, max: {max}", payLoad, limits.min, limits.max);
                return;
            }

            _deviceState.SetProperty(command, payLoad);
            using (var scope = _serviceScopeFactory.CreateScope())
            {
                var hub = scope.ServiceProvider.GetService <IHubContext <MqttHub> >();
                hub.Clients.All.SendAsync("Receive", device, command, value);
            }
        }
        protected async override Task Handle(HandleMqttMessage request, CancellationToken cancellationToken)
        {
            _logger.LogInformation("Handling mqtt message. Topic {Topic}, Payload {Payload}", request.Topic, request.Payload);
            var topics = request.Topic.Split('/');

            // Topic format is devices/{deviceId}/{dataType}
            if (topics.Length != 4)
            {
                _logger.LogInformation("Unsupported topic format. {Topic}", request.Topic);
                return;
            }

            var deviceId       = topics[1];
            var dataTypeString = topics[3];

            int dataType;

            if (!int.TryParse(dataTypeString, out dataType))
            {
                _logger.LogInformation("Invalid format for data type {DataType}", dataTypeString);
                return;
            }

            if (!AllowedCodes.Contains(dataType))
            {
                _logger.LogInformation("Unknown data type {DataType}", dataType);
                return;
            }

            string payloadString = UTF8Encoding.UTF8.GetString(request.Payload);
            int    payLoad;

            if (string.IsNullOrEmpty(payloadString) || !int.TryParse(payloadString, out payLoad))
            {
                _logger.LogInformation("Invalid payload format. Payload: {Payload}", payloadString);
                return;
            }

            var limits = CodeMinMax[dataType];

            if (payLoad < limits.min || payLoad > limits.max)
            {
                _logger.LogInformation("Payload out of bounds. Payload: {Payload}, min: {Min}, max: {max}", payLoad, limits.min, limits.max);
                return;
            }

            var device = await _deviceRepository.Get(deviceId);

            if (device is null)
            {
                _logger.LogInformation("No device with id {Id}", deviceId);
                return;
            }

            var entry = new DeviceDataIncoming
            {
                DeviceId  = device.Id,
                DataType  = dataType,
                TimeStamp = DateTime.Now,
                Value     = payLoad
            };

            await _deviceDataIncomingRepository.Create(entry);

            switch (dataType)
            {
            case 1000: device.InsideTemperature = payLoad; break;

            case 1001: device.OutsideTemperature = payLoad; break;

            case 1010: device.HasOutsideTemperatureSensor = payLoad == 0 ? false : true; break;

            case 1011: device.OutsideTemperature = payLoad; break;

            case 1020: device.OutsideTemperature = payLoad; break;

            case 2000: device.OperationTimeInSec = payLoad; break;

            case 2010: device.WorkingHour = payLoad; break;

            case 4040: device.IsOperational = payLoad == 0 ? false : true; break;

            case 4050: device.SilentMode = payLoad == 0 ? false : true; break;

            case 8000: device.MachineIsBroken = payLoad == 0 ? false : true; break;

            case 9000: device.SerialNumber = payLoad; break;

            default: break;
            }

            await _deviceRepository.Update(device);
        }