private async Task TelemetryReceived(DeviceTelemetry telemetry)
        {
            //query device with serial number
            var device = _deviceRepository.AsQueryable().FirstOrDefault(q => q.SerialNumber == telemetry.SerialNumber);

            //check if device is known
            if (device == null)
            {
                Console.WriteLine($"WARN: Received telemetry for unknown device: {telemetry.SerialNumber}");
                return;
            }


            //check if this telemetry is first entry for the device
            if (!device.LastKnownLatitue.HasValue || !device.LastKnownLongitude.HasValue)
            {
                device.LastKnownLongitude = telemetry.Longitude;
                device.LastKnownLatitue   = telemetry.Latitude;
                device.LastContact        = telemetry.DeviceDate;
                //this is first telemetry so we can not calculate speed for the device
                await _deviceRepository.UpdateAsync(device);

                return;
            }

            //calculate distance in meters
            var distance = Math.Round(new Coordinates(device.LastKnownLatitue.Value, device.LastKnownLongitude.Value)
                                      .DistanceTo(
                                          new Coordinates(telemetry.Latitude, telemetry.Longitude),
                                          UnitOfLength.Meter
                                          ), 2);

            //calculate speed meters per hour
            double speed = 0;

            if (distance > 0)
            {
                speed = Math.Round(
                    GeolocationDistanceCalculator.SpeedAsMeterPerHour(distance, telemetry.DeviceDate,
                                                                      device.LastContact.Value), 2);
            }

            //set last known speed for the device
            device.LastKnownSpeed = speed;

            //check device behaviour
            device.State = distance <= DeviceConstants.MoveAlertInMeters
                ? DeviceState.OperatingAbnormally
                : DeviceState.OperatingNormally;

            device.LastContact = telemetry.DeviceDate;

            //update device
            await _deviceRepository.UpdateAsync(device);
        }
        public void SpeedAsMeterPerHour()
        {
            //Scenario
            //assume subject moves 1 meter per second
            // calculates speed meters per hour

            var distance = 1;                  //1 meter
            var shouldBe = distance * 60 * 60; // object should move 3600 meter per hour, distance * second * minute

            var date1 = DateTime.UtcNow;
            var date2 = date1.AddSeconds(1);

            var speed = GeolocationDistanceCalculator.SpeedAsMeterPerHour(distance, date2, date1);

            Assert.AreEqual(speed, shouldBe);
        }