private async Task ConvertAndStoreDataPoints() { if (conversionTask == null || conversionTask.IsCompleted) { conversionTask = Task.Run(async() => { #if DEBUG Stopwatch timer = Stopwatch.StartNew(); #endif IStorageService storageService = StorageService.Current; var dataPoints = await storageService.GetAllWalkingDataPoints(); //MergeWalkingDataPoints(ref dataPoints); var daysConverted = dataPoints .Where(dp => !dp.HasBeenCounted) .GroupBy(dp => dp.Start.Date) .Select(g => { float minutesBrisk = g .Where(dp => dp.WasBrisk) .Aggregate(0f, (acc, dp) => acc + (float)(dp.Stop - dp.Start).TotalSeconds) / 60f; float minutesRegular = g .Where(dp => !dp.WasBrisk) .Aggregate(0f, (acc, dp) => acc + (float)(dp.Stop - dp.Start).TotalSeconds) / 60f; return(new WalkingDayModel { Day = g.Key, MinutesBriskWalking = (uint)Math.Ceiling(minutesBrisk), MinutesRegularWalking = (uint)Math.Ceiling(minutesRegular), }); }).ToList(); foreach (var day in daysConverted) { //Make sure that we update existing days var existingDay = await storageService.GetWalkingDay(day.Day); if (existingDay != null) { day.MinutesBriskWalking += existingDay.MinutesBriskWalking; day.MinutesRegularWalking += existingDay.MinutesRegularWalking; } //Store updated day await storageService.AddOrUpdateWalkingDay(day); } //NOTE: Remove all datapoints as they now have been accounted for and todays merged datapoints will be resaved await storageService.DeleteDataBaseTables(Table.WalkingDataPoints); var todaysDataPoints = dataPoints .Where(dp => dp.Start >= DateTime.Today) .ToList(); //make sure we set them to counted foreach (var dp in todaysDataPoints) { dp.HasBeenCounted = true; } await storageService.StoreWalkingDataPoints(todaysDataPoints); var today = await storageService.GetWalkingDay(DateTime.Today); if (today == null) { today = new WalkingDayModel { Day = DateTime.Today, MinutesBriskWalking = 0, MinutesRegularWalking = 0 }; daysConverted.Add(today); } todaysHistory.minutesBriskWalkToday = today.MinutesBriskWalking; todaysHistory.minutesRegularWalkToday = today.MinutesRegularWalking; todaysHistory.todaysWalking = MergeTimeAdjacentDataPoints(todaysDataPoints); OnTodaysWalkingUpdated(todaysHistory); await storageService.RemoveOldWalkingDays(); const int THIRTY_DAYS = 30; var daysInStorage = await storageService.GetWalkingDaysSinceInclusive(DateTime.Today.AddDays(-THIRTY_DAYS)); daysConverted = daysConverted.Union(daysInStorage).ToList(); //fill in missing days from last 30 for (int i = 0; i < THIRTY_DAYS - 1; ++i) { var dayOffset = (i + 1); DateTime day = DateTime.Today.AddDays(-dayOffset); //Check if data for day already exists if (!daysConverted.Any(d => d.Day.Date == day.Date)) { daysConverted.Add(new WalkingDayModel { Day = day.Date, MinutesBriskWalking = 0, MinutesRegularWalking = 0 }); } } dailyHistory = daysConverted; dailyHistory.Sort((dA, dB) => dA.Day.CompareTo(dB.Day)); OnDailyWalkingHistoryUpdated(dailyHistory); //Make absolutely sure they are in order UpdateThisWeekFromThirtyDaysHistory(); #if DEBUG Debug.WriteLine("Running datapoint conversion took {0} ms", timer.ElapsedMilliseconds); #endif }); await conversionTask; } }
private async Task UpdateWalkingHistory() { IStorageService storageService = StorageService.Current; //convert old data to daily data points var storedDataPoints = await storageService.GetAllWalkingDataPoints(); var convertedDaysTasks = storedDataPoints .Where(dp => !dp.HasBeenCounted) .GroupBy(dp => dp.Start.Date) .Select(async g => { var minutesBriskWalking = (uint)Math.Ceiling(g.Where(dp => dp.WasBrisk && !dp.WasUnknown).Sum(t => (t.Stop - t.Start).TotalMinutes)); var minutesRegularWalking = (uint)Math.Ceiling(g.Where(dp => !dp.WasBrisk && !dp.WasUnknown).Sum(t => (t.Stop - t.Start).TotalMinutes)); var minutesUnknownWalking = (uint)Math.Ceiling(g.Where(dp => dp.WasUnknown).Sum(t => (t.Stop - t.Start).TotalMinutes)); var existingDay = await storageService.GetWalkingDay(g.Key); if (existingDay == null) { existingDay = new WalkingDayModel { Day = g.Key, MinutesBriskWalking = minutesBriskWalking, MinutesRegularWalking = minutesRegularWalking, MinutesUnknownWalking = minutesUnknownWalking, }; } else { existingDay.MinutesBriskWalking += minutesBriskWalking; existingDay.MinutesRegularWalking += minutesRegularWalking; existingDay.MinutesUnknownWalking += minutesUnknownWalking; } await storageService.AddOrUpdateWalkingDay(existingDay); return(existingDay); }); var convertedDays = await Task.WhenAll(convertedDaysTasks); //NOTE: We delete all here since they have all been accounted for above. Mixing merged dp with "raw" dps from Google Fitness is a recipe for disaster. await storageService.DeleteDataBaseTables(Table.WalkingDataPoints); //Flag todays as counted var todaysDataPoints = storedDataPoints .Where(dp => dp.Start >= DateTime.Today) .Select(dp => { dp.HasBeenCounted = true; return(dp); }).ToList(); //await storageService.UpdateWalkingDataPoints(todaysDataPoints); await storageService.StoreWalkingDataPoints(todaysDataPoints); if (storedDataPoints.Count > 0) { await storageService.StoreTimeOfLatestWalkingDataPointOrMidnight(storedDataPoints .OrderByDescending(dp => dp.Stop).First().Stop); } var todaysData = convertedDays.FirstOrDefault(day => day.Day == DateTime.Today); //Make sure we add days without walking if (todaysData == null) { todaysData = new WalkingDayModel { Day = DateTime.Today, MinutesBriskWalking = (uint)Math.Ceiling(todaysDataPoints.Where(dp => dp.WasBrisk && !dp.WasUnknown).Sum(t => (t.Stop - t.Start).TotalMinutes)), MinutesRegularWalking = (uint)Math.Ceiling(todaysDataPoints.Where(dp => !dp.WasBrisk && !dp.WasUnknown).Sum(t => (t.Stop - t.Start).TotalMinutes)), MinutesUnknownWalking = (uint)Math.Ceiling(todaysDataPoints.Where(dp => dp.WasUnknown).Sum(t => (t.Stop - t.Start).TotalMinutes)), }; await storageService.AddOrUpdateWalkingDay(todaysData); } todaysHistory.minutesRegularWalkToday = todaysData.MinutesRegularWalking; todaysHistory.minutesBriskWalkToday = todaysData.MinutesBriskWalking; todaysHistory.minutesUnknownWalkToday = todaysData.MinutesUnknownWalking; todaysHistory.todaysWalking = MergeTimeAdjacentDataPoints(todaysDataPoints); OnTodaysWalkingUpdated(todaysHistory); await storageService.RemoveOldWalkingDays(); const int THIRTY_DAYS = 30; var startDate = DateTime.Today.AddDays(-THIRTY_DAYS); dailyHistory = await storageService.GetWalkingDaysSinceInclusive(startDate); for (var i = 0; i < THIRTY_DAYS - 1; ++i) { var dayOffset = (i + 1); var day = DateTime.Today.AddDays(-dayOffset); //Check if data for day already exists if (!dailyHistory.Any(d => d.Day.Date == day.Date)) { dailyHistory.Add(new WalkingDayModel { Day = day.Date, MinutesBriskWalking = 0, MinutesRegularWalking = 0, MinutesUnknownWalking = 0, }); } } dailyHistory.Sort((d1, d2) => d1.Day.CompareTo(d2.Day)); OnDailyWalkingHistoryUpdated(dailyHistory); UpdateThisWeekFromThirtyDaysHistory(); }