private async void LoadHistoricalData() { var endDate = _selectedCropCycle.EndDate?.AddDays(1) ?? DateTimeOffset.Now.AddDays(1); var sensorsHistories = await _db.SensorsHistory.Where( sh => sh.LocationID == _selectedCropCycle.LocationID && sh.TimeStamp > _selectedCropCycle.StartDate && sh.TimeStamp < endDate).ToListAsync(); Parallel.ForEach(SensorsToGraph, tuple => { var shCollection = sensorsHistories.Where(sh => sh.SensorID == tuple.sensor.ID); var datapointCollection = new List <BindableDatapoint>(); foreach (var sh in shCollection) { sh.DeserialiseData(); foreach (var dp in sh.Data) { if (dp.TimeStamp > _selectedCropCycle.StartDate) // becuase datapoints are packed into days, we must avoid datapoitns that astarted before the cropRun { var bindable = new BindableDatapoint(dp); datapointCollection.Add(bindable); } } } var ordered = datapointCollection.OrderBy(dp => dp.timestamp); tuple.historicalDatapoints = new ObservableCollection <BindableDatapoint>(ordered); }); }
public void ReceiveDatapoint(IEnumerable <Messenger.SensorReading> readings) { if (SensorsToGraph != null) { _pauseChart.Invoke(); var Added = false; foreach (var reading in readings) { var tuple = SensorsToGraph.FirstOrDefault(stup => stup.sensor.ID == reading.SensorId); if (tuple != null) { if (tuple.hourlyDatapoints.Count == 0 || tuple.hourlyDatapoints.LastOrDefault().timestamp < reading.Timestamp.LocalDateTime) { Added = true; var datapoint = new BindableDatapoint(reading.Timestamp, reading.Value); tuple.hourlyDatapoints.Add(datapoint); //Remove datapoints if we are storing more than an hour of them if (tuple.hourlyDatapoints.Count > 3000) { tuple.hourlyDatapoints.RemoveAt(0); } } } } if (Added) { var tupleForChartUpdate = SensorsToGraph.FirstOrDefault(); if (tupleForChartUpdate?.RealtimeMode ?? false) { tupleForChartUpdate.Axis.Minimum = tupleForChartUpdate.hourlyDatapoints.FirstOrDefault()?.timestamp ?? DateTime.Now.AddHours(-1); tupleForChartUpdate.Axis.Maximum = tupleForChartUpdate.hourlyDatapoints.LastOrDefault()?.timestamp ?? DateTime.Now; } } _resumeChart.Invoke(); } }