public async Task SendTripPointToIOTHub(string tripId, string userId, TripPoint tripDataPoint) { //Note: Each individual trip point is being serialized separately so that it can be sent over as an individual message //This is the expected format by the IOT Hub\ML var settings = new JsonSerializerSettings {ContractResolver = new CustomContractResolver()}; var tripDataPointBlob = JsonConvert.SerializeObject(tripDataPoint, settings); var tripBlob = JsonConvert.SerializeObject( new { TripId = tripId, UserId = userId }); tripBlob = tripBlob.TrimEnd('}'); string packagedBlob = $"{tripBlob},\"TripDataPoint\":{tripDataPointBlob}}}"; if (!CrossConnectivity.Current.IsConnected) { //If there is no network connection, save in buffer and try again Logger.Instance.Track("Unable to push data to IOT Hub - no network connection."); await AddTripPointToBuffer(packagedBlob); return; } try { await iotHub.SendEvent(packagedBlob); } catch (Exception e) { //An exception will be thrown if the data isn't received by the IOT Hub; store data in buffer and try again Logger.Instance.Track("Unable to send data to IOT Hub: " + e.Message); AddTripPointToBuffer(packagedBlob); } }
async void Geolocator_PositionChanged(object sender, PositionEventArgs e) { // Only update the route if we are meant to be recording coordinates if (IsRecording) { var userLocation = e.Position; TripPoint previous = null; double newDistance = 0; if (CurrentTrip.Points.Count > 1) { previous = CurrentTrip.Points[CurrentTrip.Points.Count - 1]; newDistance = DistanceUtils.CalculateDistance(userLocation.Latitude, userLocation.Longitude, previous.Latitude, previous.Longitude); if (newDistance > 4) // if more than 4 miles then gps is off don't use return; } var point = new TripPoint { TripId = CurrentTrip.Id, RecordedTimeStamp = DateTime.UtcNow, Latitude = userLocation.Latitude, Longitude = userLocation.Longitude, Sequence = CurrentTrip.Points.Count, Speed = -255, RPM = -255, ShortTermFuelBank = -255, LongTermFuelBank = -255, ThrottlePosition = -255, RelativeThrottlePosition = -255, Runtime = -255, DistanceWithMalfunctionLight = -255, EngineLoad = -255, MassFlowRate = -255, EngineFuelRate = -255, VIN = "-255" }; //Add OBD data if (obdDataProcessor != null) point.HasSimulatedOBDData = obdDataProcessor.IsObdDeviceSimulated; await AddOBDDataToPoint(point); CurrentTrip.Points.Add(point); try { if (obdDataProcessor != null) { //Push the trip data packaged with the OBD data to the IOT Hub obdDataProcessor.SendTripPointToIOTHub(CurrentTrip.Id, CurrentTrip.UserId, point); } } catch (Exception ex) { Logger.Instance.Report(ex); } if (CurrentTrip.Points.Count > 1 && previous != null) { CurrentTrip.Distance += newDistance; Distance = CurrentTrip.TotalDistanceNoUnits; //calculate gas usage var timeDif1 = point.RecordedTimeStamp - previous.RecordedTimeStamp; CurrentTrip.FuelUsed += fuelConsumptionRate * 0.00002236413 * timeDif1.TotalSeconds; if (CurrentTrip.FuelUsed == 0) FuelConsumption = "N/A"; else FuelConsumption = Settings.MetricUnits ? (CurrentTrip.FuelUsed * 3.7854).ToString("N2") : CurrentTrip.FuelUsed.ToString("N2"); } else { CurrentTrip.FuelUsed = 0; FuelConsumption = "N/A"; } var timeDif = point.RecordedTimeStamp - CurrentTrip.RecordedTimeStamp; //track seconds, minutes, then hours if (timeDif.TotalMinutes < 1) ElapsedTime = $"{timeDif.Seconds}s"; else if (timeDif.TotalHours < 1) ElapsedTime = $"{timeDif.Minutes}m {timeDif.Seconds}s"; else ElapsedTime = $"{(int)timeDif.TotalHours}h {timeDif.Minutes}m {timeDif.Seconds}s"; if (point.EngineLoad != -255) EngineLoad = $"{(int)point.EngineLoad}%"; FuelConsumptionUnits = Settings.MetricUnits ? "Liters" : "Gallons"; DistanceUnits = Settings.MetricDistance ? "Kilometers" : "Miles"; OnPropertyChanged("Stats"); } CurrentPosition = e.Position; }
async Task AddOBDDataToPoint(TripPoint point) { //Read data from the OBD device point.HasOBDData = false; Dictionary<string, string> obdData = null; if (obdDataProcessor != null) obdData = await obdDataProcessor.ReadOBDData(); if (obdData != null) { double speed = -255, rpm = -255, efr = -255, el = -255, stfb = -255, ltfb = -255, fr = -255, tp = -255, rt = -255, dis = -255, rtp = -255; var vin = String.Empty; if (obdData.ContainsKey("el") && !string.IsNullOrWhiteSpace(obdData["el"])) { if (!double.TryParse(obdData["el"], out el)) el = -255; } if (obdData.ContainsKey("stfb")) double.TryParse(obdData["stfb"], out stfb); if (obdData.ContainsKey("ltfb")) double.TryParse(obdData["ltfb"], out ltfb); if (obdData.ContainsKey("fr")) { double.TryParse(obdData["fr"], out fr); if (fr != -255) { fuelConsumptionRate = fr; } } if (obdData.ContainsKey("tp")) double.TryParse(obdData["tp"], out tp); if (obdData.ContainsKey("rt")) double.TryParse(obdData["rt"], out rt); if (obdData.ContainsKey("dis")) double.TryParse(obdData["dis"], out dis); if (obdData.ContainsKey("rtp")) double.TryParse(obdData["rtp"], out rtp); if (obdData.ContainsKey("spd")) double.TryParse(obdData["spd"], out speed); if (obdData.ContainsKey("rpm")) double.TryParse(obdData["rpm"], out rpm); if (obdData.ContainsKey("efr") && !string.IsNullOrWhiteSpace(obdData["efr"])) { if (!double.TryParse(obdData["efr"], out efr)) efr = -255; } else { efr = -255; } if (obdData.ContainsKey("vin")) vin = obdData["vin"]; point.EngineLoad = el; point.ShortTermFuelBank = stfb; point.LongTermFuelBank = ltfb; point.MassFlowRate = fr; point.ThrottlePosition = tp; point.Runtime = rt; point.DistanceWithMalfunctionLight = dis; point.RelativeThrottlePosition = rtp; point.Speed = speed; point.RPM = rpm; point.EngineFuelRate = efr; point.VIN = vin; #if DEBUG foreach (var kvp in obdData) Logger.Instance.Track($"{kvp.Key} {kvp.Value}"); #endif point.HasOBDData = true; } }
void UpdateTripStatistics(TripPoint point) { PastTripsDetailViewModel.CurrentPosition = point; labelOneTitle.Text = PastTripsDetailViewModel.FuelConsumptionUnits; labelOneValue.Text = PastTripsDetailViewModel.FuelConsumption; labelTwoTitle.Text = PastTripsDetailViewModel.DistanceUnits; labelTwoValue.Text = PastTripsDetailViewModel.Distance; labelThreeTitle.Text = "Elapsed Time"; labelThreeValue.Text = PastTripsDetailViewModel.ElapsedTime; labelFourTitle.Text = PastTripsDetailViewModel.SpeedUnits; labelFourValue.Text = PastTripsDetailViewModel.Speed; }
void UpdateMap(TripPoint point, bool updateCamera = true) { if (map == null) return; //Get trail position or current potion to move car var latlng = point == null ? viewModel?.CurrentPosition?.ToLatLng() : point.ToLatLng(); Activity?.RunOnUiThread(() => { UpdateCar(latlng); driveLine?.Remove(); var polyOptions = new PolylineOptions(); if (allPoints == null) { allPoints = viewModel.CurrentTrip.Points.ToLatLngs(); } else if (point != null) { allPoints.Add(point.ToLatLng()); } polyOptions.Add(allPoints.ToArray()); if (!driveLineColor.HasValue) driveLineColor = new Color(ContextCompat.GetColor(Activity, Resource.Color.recording_accent)); polyOptions.InvokeColor(driveLineColor.Value); driveLine = map.AddPolyline(polyOptions); if (updateCamera) UpdateCamera(latlng); }); }