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); }