Exemplo n.º 1
0
        protected override void Initialize(HttpControllerContext controllerContext)
        {
            base.Initialize(controllerContext);
            feedtimeContext context = new feedtimeContext();

            DomainManager = new EntityDomainManager <ChangeActivity>(context, Request, Services, enableSoftDelete: true);
        }
Exemplo n.º 2
0
        // POST tables/Baby
        public async Task <IHttpActionResult> PostBaby(Baby item)
        {
            // Ensure the baby is only inserted into the users family
            using (var context = new feedtimeContext())
            {
                string userId      = User.GetId();
                var    userProfile = context.Set <UserProfile>()
                                     .Single(up => up.UserId == userId);
                item.FamilyId = userProfile.FamilyId;
            }

            Baby current = await InsertAsync(item);

            return(CreatedAtRoute("Tables", new { id = current.Id }, current));
        }
Exemplo n.º 3
0
        // DELETE tables/Baby/48D68C86-6EA6-4C25-AA33-223FC9A27959
        public Task DeleteBaby(string id)
        {
            // Ensure that the baby being deleted belongs to the users family
            using (var context = new feedtimeContext())
            {
                string userId = User.GetId();
                var    baby   = context.Set <Baby>()
                                .SingleOrDefault(b => b.Id == id && b.Family.UserProfiles.Any(up => up.UserId == userId));
                if (baby == null)
                {
                    throw new HttpResponseException(HttpStatusCode.NotFound);
                }
            }

            return(DeleteAsync(id));
        }
Exemplo n.º 4
0
        // DELETE tables/UserProfile/48D68C86-6EA6-4C25-AA33-223FC9A27959
        public Task DeleteUserProfile(string id)
        {
            // Ensure that the user profile being deleted belongs to the current user
            using (var context = new feedtimeContext())
            {
                string userId      = User.GetId();
                var    userProfile = context.Set <UserProfile>()
                                     .SingleOrDefault(up => up.UserId == userId);
                if (userProfile == null)
                {
                    throw new HttpResponseException(HttpStatusCode.NotFound);
                }
            }

            return(DeleteAsync(id));
        }
Exemplo n.º 5
0
        // GET api/DataTrends
        public DataTrends Get(string babyId)
        {
            using (var context = new feedtimeContext())
            {
                // Use rolling windows for last 'day' & 'week'
                string userId      = User.GetId();
                var    today       = DateTimeOffset.UtcNow.AddHours(-24);
                var    startOfWeek = DateTimeOffset.UtcNow.AddDays(-7);
                var    dataTrends  = new DataTrends {
                    BabyId = babyId
                };

                var currentBaby = context.Set <Baby>()
                                  .Where(baby => baby.Id == babyId &&
                                         baby.Family.UserProfiles.Any(up => up.UserId == userId))
                                  .SingleOrDefault();
                if (currentBaby == null)
                {
                    throw new HttpResponseException(HttpStatusCode.NotFound);
                }

                dataTrends.StartOfDay     = today;
                dataTrends.StartOfWeek    = startOfWeek;
                dataTrends.BabysBirthDate = currentBaby.DateOfBirth;

                // Retrieve the averages for feeds & sleeps
                var feedsOverLastWeek = context.Set <FeedActivity>()
                                        .Where(activity => activity.BabyId == babyId &&
                                               activity.StartTime >= startOfWeek &&
                                               activity.EndTime.HasValue &&
                                               !activity.Deleted)
                                        .AsEnumerable();
                var feedsOverLastWeekWithVolume = feedsOverLastWeek.Where(activity => activity.MillilitresConsumed.HasValue);
                var feedsOverLastWeekByDay      = feedsOverLastWeek.GroupBy(f => f.StartTime.Date);
                dataTrends.AverageFeedsPerDay = feedsOverLastWeekByDay.Aggregate(0,
                                                                                 (a, b) => a + b.Count(),
                                                                                 a => feedsOverLastWeekByDay.Any()
                                                                                        ? Convert.ToInt32(Math.Round((double)a / feedsOverLastWeekByDay.Count()))
                                                                                        : 0);
                dataTrends.AverageFeedDuration = feedsOverLastWeek.Aggregate(0d,
                                                                             (a, b) => a + (b.EndTime.Value - b.StartTime).Duration().Ticks,
                                                                             a => feedsOverLastWeek.Any()
                                                                                    ? new TimeSpan(Convert.ToInt64(Math.Round((double)a / feedsOverLastWeek.Count())))
                                                                                    : TimeSpan.Zero);
                dataTrends.AverageFeedVolume = feedsOverLastWeekWithVolume.Aggregate(0,
                                                                                     (a, b) => a + b.MillilitresConsumed.Value,
                                                                                     a => feedsOverLastWeekWithVolume.Any()
                                                                                            ? Convert.ToInt32(Math.Round((double)a / feedsOverLastWeekWithVolume.Count()))
                                                                                            : 0);

                var sleepsOverLastWeek = context.Set <SleepActivity>()
                                         .Where(activity => activity.BabyId == babyId &&
                                                activity.StartTime >= startOfWeek &&
                                                activity.EndTime.HasValue &&
                                                !activity.Deleted)
                                         .AsEnumerable();
                var sleepsOverLastWeekByDay = sleepsOverLastWeek.GroupBy(f => f.StartTime.Date);
                dataTrends.AverageSleepsPerDay = sleepsOverLastWeekByDay.Aggregate(0,
                                                                                   (a, b) => a + b.Count(),
                                                                                   a => sleepsOverLastWeekByDay.Any()
                                                                                        ? Convert.ToInt32(Math.Round((double)a / sleepsOverLastWeekByDay.Count()))
                                                                                        : 0);
                dataTrends.AverageSleepDuration = sleepsOverLastWeek.Aggregate(0d,
                                                                               (a, b) => a + (b.EndTime.Value - b.StartTime).Duration().Ticks,
                                                                               a => sleepsOverLastWeek.Any()
                                                                                    ? new TimeSpan(Convert.ToInt64(Math.Round((double)a / sleepsOverLastWeek.Count())))
                                                                                    : TimeSpan.Zero);

                var changesOverLastWeek = context.Set <ChangeActivity>()
                                          .Where(activity => activity.BabyId == babyId &&
                                                 activity.StartTime >= startOfWeek &&
                                                 activity.EndTime.HasValue &&
                                                 !activity.Deleted)
                                          .AsEnumerable();
                var changesOverLastWeekByDay = changesOverLastWeek.GroupBy(f => f.StartTime.Date);
                dataTrends.AverageChangesPerDay = changesOverLastWeekByDay.Aggregate(0,
                                                                                     (a, b) => a + b.Count(),
                                                                                     a => changesOverLastWeekByDay.Any()
                                                                                            ? Convert.ToInt32(Math.Round((double)a / changesOverLastWeekByDay.Count()))
                                                                                            : 0);

                // Retrieve the data for activities over the last 24 hours
                dataTrends.FeedsOverLastDay = context.Set <FeedActivity>()
                                              .Where(activity => activity.BabyId == babyId &&
                                                     activity.StartTime >= today &&
                                                     !activity.Deleted)
                                              .Select(activity => new ActivityTrend {
                    StartTime = activity.StartTime, EndTime = activity.EndTime
                })
                                              .ToList();
                dataTrends.SleepsOverLastDay = context.Set <SleepActivity>()
                                               .Where(activity => activity.BabyId == babyId &&
                                                      activity.StartTime >= today &&
                                                      !activity.Deleted)
                                               .Select(activity => new ActivityTrend {
                    StartTime = activity.StartTime, EndTime = activity.EndTime
                })
                                               .ToList();
                dataTrends.ChangesOverLastDay = context.Set <ChangeActivity>()
                                                .Where(activity => activity.BabyId == babyId &&
                                                       activity.StartTime >= today &&
                                                       !activity.Deleted)
                                                .Select(activity => new ActivityTrend {
                    StartTime = activity.StartTime, EndTime = activity.EndTime
                })
                                                .ToList();

                // Retrieve the data for mood over the last 7 days
                var sleepActivitiesWithFeeling = context.Set <SleepActivity>()
                                                 .Where(activity => activity.BabyId == babyId &&
                                                        activity.StartTime >= startOfWeek &&
                                                        (activity.HowBabyFelt != null || activity.HowParentFelt != null) &&
                                                        !activity.Deleted)
                                                 .Select(activity => new { StartTime = activity.StartTime, HowBabyFelt = activity.HowBabyFelt, HowParentFelt = activity.HowParentFelt })
                                                 .Union(context.Set <FeedActivity>()
                                                        .Where(activity => activity.BabyId == babyId &&
                                                               activity.StartTime >= startOfWeek &&
                                                               (activity.HowBabyFelt != null || activity.HowParentFelt != null) &&
                                                               !activity.Deleted)
                                                        .Select(activity => new { StartTime = activity.StartTime, HowBabyFelt = activity.HowBabyFelt, HowParentFelt = activity.HowParentFelt }))
                                                 .Union(context.Set <ChangeActivity>()
                                                        .Where(activity => activity.BabyId == babyId &&
                                                               activity.StartTime >= startOfWeek &&
                                                               (activity.HowBabyFelt != null || activity.HowParentFelt != null) &&
                                                               !activity.Deleted)
                                                        .Select(activity => new { StartTime = activity.StartTime, HowBabyFelt = activity.HowBabyFelt, HowParentFelt = activity.HowParentFelt }))
                                                 .AsEnumerable();

                dataTrends.BabysMoodOverLastWeek = sleepActivitiesWithFeeling.Where(activity => activity.HowBabyFelt.HasValue)
                                                   .GroupBy(activity => activity.StartTime.Date)
                                                   .AsEnumerable()
                                                   .Select(activityGroup => new MoodTrend
                {
                    Date    = activityGroup.Key,
                    Feeling = AverageFeeling(activityGroup.Select(ag => ag.HowBabyFelt))
                })
                                                   .ToList();

                dataTrends.ParentsMoodOverLastWeek = sleepActivitiesWithFeeling.Where(activity => activity.HowParentFelt.HasValue)
                                                     .GroupBy(activity => activity.StartTime.Date)
                                                     .AsEnumerable()
                                                     .Select(activityGroup => new MoodTrend
                {
                    Date    = activityGroup.Key,
                    Feeling = AverageFeeling(activityGroup.Select(ag => ag.HowParentFelt))
                })
                                                     .ToList();

                // Retrieve the data for length and weight since birth
                dataTrends.MeasurementsSinceBirth = context.Set <Measurement>()
                                                    .Where(m => m.Weight != null || m.Length != null && !m.Deleted)
                                                    .AsEnumerable()
                                                    .GroupBy(measurement => measurement.CreatedAt.Value.Date)
                                                    .Select(measurementGroup => measurementGroup.OrderBy(measurement => measurement.CreatedAt.Value)
                                                            .Last())
                                                    .AsEnumerable()
                                                    .Select(measurement => new MeasurementTrend
                {
                    Date   = measurement.CreatedAt.Value,
                    Length = measurement.Length,
                    Weight = measurement.Weight
                })
                                                    .ToList();

                dataTrends.TrendsGeneratedAt = DateTimeOffset.UtcNow;

                return(dataTrends);
            }
        }
        // GET api/Schedule/abc123
        public ActivitySchedule Get(string babyId)
        {
            using (var context = new feedtimeContext())
            {
                string userId      = User.GetId();
                var    currentBaby = context.Set <Baby>()
                                     .Where(baby => baby.Id == babyId &&
                                            baby.Family.UserProfiles.Any(up => up.UserId == userId))
                                     .SingleOrDefault();
                if (currentBaby == null)
                {
                    throw new HttpResponseException(HttpStatusCode.NotFound);
                }

                // Use rolling windows for last 'week'
                var now         = DateTimeOffset.UtcNow;
                var today       = DateTimeOffset.UtcNow.Date;
                var startOfWeek = DateTimeOffset.UtcNow.AddDays(-7);

                // Calculate feed schedule for last 7 days
                long?averageTimeBetweenFeeds = null;
                //long? averageFeedTime = null;
                DateTimeOffset nextFeedDueAt  = currentBaby.DateOfBirth.Add(TimeSpan.FromHours(2));
                var            feedActivities = context.FeedActivities
                                                .Where(ca => ca.BabyId == babyId &&
                                                       ca.StartTime >= startOfWeek &&
                                                       !ca.Deleted)
                                                .OrderByDescending(ca => ca.StartTime);

                var latestFeedActivity = feedActivities.FirstOrDefault();
                if (latestFeedActivity != null)
                {
                    var feedActivityStartTimes = feedActivities.Select(ca => ca.StartTime)
                                                 .ToList();

                    // Calculate average time between feeds
                    long totalTimeBetweenFeeds = 0;
                    feedActivityStartTimes.Aggregate((a, b) =>
                    {
                        totalTimeBetweenFeeds += (today.Add(a - b) - today).Ticks;
                        return(b);
                    });
                    averageTimeBetweenFeeds = Convert.ToInt64(Math.Round((double)totalTimeBetweenFeeds / feedActivityStartTimes.Count()));

                    //// Calculate average feed time
                    //var completedFeedActivities = feedActivities.Where(a => a.EndTime.HasValue);
                    //var totalFeedTime = completedFeedActivities.Aggregate(0L, (a, b) => a + (b.EndTime.Value - b.StartTime).Ticks);
                    //averageFeedTime = totalFeedTime / completedFeedActivities.Count();

                    // Calculate next feed time
                    var minimumNextFeedTime  = latestFeedActivity.StartTime.Add(new TimeSpan(averageTimeBetweenFeeds.Value));
                    var feedActivitiesByDate = feedActivities.ToList()
                                               .GroupBy(a => a.StartTime.Date)
                                               // For each date select the first feed after 'now'
                                               .Select(ag =>
                    {
                        var ascendingStartTimes = ag.OrderBy(a => a.StartTime.TimeOfDay);
                        var nextFeed            = ascendingStartTimes
                                                  .FirstOrDefault(a => a.StartTime.TimeOfDay > minimumNextFeedTime.TimeOfDay);
                        if (nextFeed == null)
                        {
                            nextFeed = ascendingStartTimes.LastOrDefault();
                        }

                        return(nextFeed == null
                                                                            ? null
                                                                            : Tuple.Create(nextFeed, nextFeed.StartTime.TimeOfDay - now.TimeOfDay));
                    })
                                               .Where(a => a != null);

                    if (feedActivitiesByDate.Any())
                    {
                        var averageTimeToNextFeed = Convert.ToInt64(Math.Round((double)feedActivitiesByDate.Aggregate(0L, (a, b) => a + b.Item2.Ticks)
                                                                               / feedActivitiesByDate.Count()));
                        nextFeedDueAt = now.Add(new TimeSpan(averageTimeToNextFeed));
                    }
                }

                // Calculate sleep schedule for last 7 days
                long?          averageTimeBetweenSleeps = null;
                DateTimeOffset nextSleepDueAt           = currentBaby.DateOfBirth.Add(TimeSpan.FromHours(2));
                var            sleepActivities          = context.SleepActivities
                                                          .Where(ca => ca.BabyId == babyId &&
                                                                 ca.StartTime >= startOfWeek &&
                                                                 !ca.Deleted)
                                                          .OrderByDescending(ca => ca.StartTime);
                var latestSleepActivity = sleepActivities.FirstOrDefault();
                if (latestSleepActivity != null)
                {
                    var sleepActivityStartTimes = sleepActivities.Select(ca => ca.StartTime)
                                                  .ToList();
                    long totalTimeBetweenSleeps = 0;
                    sleepActivityStartTimes.Aggregate((a, b) =>
                    {
                        totalTimeBetweenSleeps += (today.Add(a - b) - today).Ticks;
                        return(b);
                    });
                    averageTimeBetweenSleeps = Convert.ToInt64(Math.Round((double)totalTimeBetweenSleeps / sleepActivityStartTimes.Count()));

                    // Calculate next sleep time
                    var minimumNextSleepTime  = latestSleepActivity.StartTime.Add(new TimeSpan(averageTimeBetweenSleeps.Value));
                    var sleepActivitiesByDate = sleepActivities.ToList()
                                                .GroupBy(a => a.StartTime.Date)
                                                // For each date select the first sleep after 'now'
                                                .Select(ag =>
                    {
                        var ascendingStartTimes = ag.OrderBy(a => a.StartTime.TimeOfDay);
                        var nextSleep           = ascendingStartTimes
                                                  .FirstOrDefault(a => a.StartTime.TimeOfDay > minimumNextSleepTime.TimeOfDay);
                        if (nextSleep == null)
                        {
                            nextSleep = ascendingStartTimes.LastOrDefault();
                        }

                        return(nextSleep == null
                                                                                ? null
                                                                                : Tuple.Create(nextSleep, nextSleep.StartTime.TimeOfDay - now.TimeOfDay));
                    })
                                                .Where(a => a != null);

                    if (sleepActivitiesByDate.Any())
                    {
                        var averageTimeToNextSleep = Convert.ToInt64(Math.Round((double)sleepActivitiesByDate.Aggregate(0L, (a, b) => a + b.Item2.Ticks)
                                                                                / sleepActivitiesByDate.Count()));
                        nextSleepDueAt = now.Add(new TimeSpan(averageTimeToNextSleep));
                    }
                }

                // Calculate change schedule for last 7 days
                long?          averageTimeBetweenChanges = null;
                DateTimeOffset nextChangeDueAt           = currentBaby.DateOfBirth.Add(TimeSpan.FromHours(3));
                var            changeActivities          = context.ChangeActivities
                                                           .Where(ca => ca.BabyId == babyId &&
                                                                  ca.StartTime >= startOfWeek &&
                                                                  !ca.Deleted)
                                                           .OrderByDescending(ca => ca.StartTime);
                var latestChangeActivity = changeActivities.FirstOrDefault();
                if (latestChangeActivity != null)
                {
                    var changeActivityStartTimes = changeActivities.Select(ca => ca.StartTime)
                                                   .ToList();
                    long totalTimeBetweenChanges = 0;
                    changeActivityStartTimes.Aggregate((a, b) =>
                    {
                        totalTimeBetweenChanges += (today.Add(a - b) - today).Ticks;
                        return(b);
                    });
                    averageTimeBetweenChanges = Convert.ToInt64(Math.Round((double)totalTimeBetweenChanges / changeActivityStartTimes.Count()));

                    // Calculate next change time
                    var minimumNextChangeTime  = latestChangeActivity.StartTime.Add(new TimeSpan(averageTimeBetweenChanges.Value));
                    var changeActivitiesByDate = changeActivities.ToList()
                                                 .GroupBy(a => a.StartTime.Date)
                                                 // For each date select the first feed after 'now'
                                                 .Select(ag =>
                    {
                        var ascendingStartTimes = ag.OrderBy(a => a.StartTime.TimeOfDay);
                        var nextChange          = ascendingStartTimes
                                                  .FirstOrDefault(a => a.StartTime.TimeOfDay > minimumNextChangeTime.TimeOfDay);
                        if (nextChange == null)
                        {
                            nextChange = ascendingStartTimes.LastOrDefault();
                        }

                        return(nextChange == null
                                                                                 ? null
                                                                                 : Tuple.Create(nextChange, nextChange.StartTime.TimeOfDay - now.TimeOfDay));
                    })
                                                 .Where(a => a != null);
                    if (changeActivitiesByDate.Any())
                    {
                        var averageTimeToNextChange = Convert.ToInt64(Math.Round((double)changeActivitiesByDate.Aggregate(0L, (a, b) => a + b.Item2.Ticks)
                                                                                 / changeActivitiesByDate.Count()));
                        nextChangeDueAt = now.Add(new TimeSpan(averageTimeToNextChange));
                    }
                }

                // Generate the complete schedule
                return(new ActivitySchedule
                {
                    BabyId = babyId,
                    ScheduleGeneratedAt = DateTimeOffset.UtcNow,

                    CurrentlyFeeding = latestFeedActivity != null
                                        ? !latestFeedActivity.EndTime.HasValue : false,
                    LastFeed = latestFeedActivity,
                    AverageTimeBetweenFeeds = averageTimeBetweenFeeds.HasValue
                                                ? new TimeSpan(averageTimeBetweenFeeds.Value) : (TimeSpan?)null,
                    NextFeedDueAt = nextFeedDueAt,

                    CurrentlySleeping = latestSleepActivity != null
                                        ? !latestSleepActivity.EndTime.HasValue : false,
                    LastSleep = latestSleepActivity,
                    AverageTimeBetweenSleeps = averageTimeBetweenSleeps.HasValue
                                                ? new TimeSpan(averageTimeBetweenSleeps.Value) : (TimeSpan?)null,
                    NextSleepDueAt = nextSleepDueAt,

                    LastChange = latestChangeActivity,
                    AverageTimeBetweenChanges = averageTimeBetweenChanges.HasValue
                                                ? new TimeSpan(averageTimeBetweenChanges.Value) : (TimeSpan?)null,
                    NextChangeDueAt = nextChangeDueAt
                });
            }
        }