diff --git a/sql/insights/create_questions.sql b/sql/insights/create_questions.sql index 8a0f52441..854770b3c 100644 --- a/sql/insights/create_questions.sql +++ b/sql/insights/create_questions.sql @@ -696,6 +696,126 @@ UPDATE questions SET dependency_response=(SELECT ARRAY_AGG(id) FROM response_cho WHERE question_text=ANY(ARRAY['How noticeable do you think the effects of your difficulty sleeping are to other people?', 'How much does your difficulty sleeping interfere with the rest of your day? (e.g. daytime fatigue, mood, concentration, memory, mood, etc.)']); +-- jyfan 2016-10-31 strict alarm questions +INSERT INTO questions (question_text, lang, frequency, response_type, responses, dependency, ask_time, category) + VALUES ( + 'You could benefit from a consistent wake time. Set a recurring alarm for 6:00 AM? Existing alarms will be deleted.', -- text + 'EN', -- lang + 'trigger', -- frequency (note, trigger is currently not implemented in QuestionProcessor) + 'choice', --response_type, + '{"Yes", "No", "No, this time doesn''t work"}', --text responses + null, -- dependency + 'anytime', -- ask_time + 'insight' --category +); + +INSERT INTO questions (question_text, lang, frequency, response_type, responses, dependency, ask_time, category) + VALUES ( + 'You could benefit from a consistent wake time. Set a recurring alarm for 6:30 AM? Existing alarms will be deleted.', -- text + 'EN', -- lang + 'trigger', -- frequency (note, trigger is currently not implemented in QuestionProcessor) + 'choice', --response_type, + '{"Yes", "No", "No, this time doesn''t work"}', --text responses + null, -- dependency + 'anytime', -- ask_time + 'insight' --category +); + +INSERT INTO questions (question_text, lang, frequency, response_type, responses, dependency, ask_time, category) + VALUES ( + 'You could benefit from a consistent wake time. Set a recurring alarm for 7:00 AM? Existing alarms will be deleted.', -- text + 'EN', -- lang + 'trigger', -- frequency (note, trigger is currently not implemented in QuestionProcessor) + 'choice', --response_type, + '{"Yes", "No", "No, this time doesn''t work"}', --text responses + null, -- dependency + 'anytime', -- ask_time + 'insight' --category +); + +INSERT INTO questions (question_text, lang, frequency, response_type, responses, dependency, ask_time, category) + VALUES ( + 'You could benefit from a consistent wake time. Set a recurring alarm for 7:30 AM? Existing alarms will be deleted.', -- text + 'EN', -- lang + 'trigger', -- frequency (note, trigger is currently not implemented in QuestionProcessor) + 'choice', --response_type, + '{"Yes", "No", "No, this time doesn''t work"}', --text responses + null, -- dependency + 'anytime', -- ask_time + 'insight' --category +); + +INSERT INTO questions (question_text, lang, frequency, response_type, responses, dependency, ask_time, category) + VALUES ( + 'You could benefit from a consistent wake time. Set a recurring alarm for 8:00 AM? Existing alarms will be deleted.', -- text + 'EN', -- lang + 'trigger', -- frequency (note, trigger is currently not implemented in QuestionProcessor) + 'choice', --response_type, + '{"Yes", "No", "No, this time doesn''t work"}', --text responses + null, -- dependency + 'anytime', -- ask_time + 'insight' --category +); + +INSERT INTO questions (question_text, lang, frequency, response_type, responses, dependency, ask_time, category) + VALUES ( + 'You could benefit from a consistent wake time. Set a recurring alarm for 8:30 AM? Existing alarms will be deleted.', -- text + 'EN', -- lang + 'trigger', -- frequency (note, trigger is currently not implemented in QuestionProcessor) + 'choice', --response_type, + '{"Yes", "No", "No, this time doesn''t work"}', --text responses + null, -- dependency + 'anytime', -- ask_time + 'insight' --category +); + +INSERT INTO questions (question_text, lang, frequency, response_type, responses, dependency, ask_time, category) + VALUES ( + 'You could benefit from a consistent wake time. Set a recurring alarm for 9:00 AM? Existing alarms will be deleted.', -- text + 'EN', -- lang + 'trigger', -- frequency (note, trigger is currently not implemented in QuestionProcessor) + 'choice', --response_type, + '{"Yes", "No", "No, this time doesn''t work"}', --text responses + null, -- dependency + 'anytime', -- ask_time + 'insight' --category +); + +INSERT INTO questions (question_text, lang, frequency, response_type, responses, dependency, ask_time, category) + VALUES ( + 'You could benefit from a consistent wake time. Set a recurring alarm for 9:30 AM? Existing alarms will be deleted.', -- text + 'EN', -- lang + 'trigger', -- frequency (note, trigger is currently not implemented in QuestionProcessor) + 'choice', --response_type, + '{"Yes", "No", "No, this time doesn''t work"}', --text responses + null, -- dependency + 'anytime', -- ask_time + 'insight' --category +); + +INSERT INTO questions (question_text, lang, frequency, response_type, responses, dependency, ask_time, category) + VALUES ( + 'You could benefit from a consistent wake time. Set a recurring alarm for 10:00 AM? Existing alarms will be deleted.', -- text + 'EN', -- lang + 'trigger', -- frequency (note, trigger is currently not implemented in QuestionProcessor) + 'choice', --response_type, + '{"Yes", "No", "No, this time doesn''t work"}', --text responses + null, -- dependency + 'anytime', -- ask_time + 'insight' --category +); + +INSERT INTO response_choices (question_id, response_text) + (SELECT id, UNNEST(responses) FROM questions WHERE id IN (SELECT id FROM questions ORDER BY id DESC LIMIT 9)); + +UPDATE questions SET responses = S.texts, responses_ids = S.ids FROM ( + SELECT question_id, ARRAY_AGG(id) AS ids, ARRAY_AGG(response_text) AS texts + FROM response_choices where question_id IN + (select id from questions order by id DESC LIMIT 9) GROUP BY question_id) AS S +WHERE questions.id = S.question_id; + + + diff --git a/suripu-core/src/main/java/com/hello/suripu/core/models/Insights/InsightCard.java b/suripu-core/src/main/java/com/hello/suripu/core/models/Insights/InsightCard.java index d0ad204b7..b2c29a791 100644 --- a/suripu-core/src/main/java/com/hello/suripu/core/models/Insights/InsightCard.java +++ b/suripu-core/src/main/java/com/hello/suripu/core/models/Insights/InsightCard.java @@ -51,7 +51,8 @@ public enum Category { GOAL_SCHEDULE_THOUGHTS(33), GOAL_SCREENS(34), GOAL_WAKE_VARIANCE(35), - SLEEP_DEPRIVATION(36); + SLEEP_DEPRIVATION(36), + STRICT_ALARM(37); private int value; diff --git a/suripu-core/src/main/java/com/hello/suripu/core/models/Insights/QuestionCard.java b/suripu-core/src/main/java/com/hello/suripu/core/models/Insights/QuestionCard.java new file mode 100644 index 000000000..81b8537cc --- /dev/null +++ b/suripu-core/src/main/java/com/hello/suripu/core/models/Insights/QuestionCard.java @@ -0,0 +1,30 @@ +package com.hello.suripu.core.models.Insights; + +import org.joda.time.DateTime; + +/** + * Created by jyfan on 11/7/16. + */ +public class QuestionCard { + public Long accountId; + public Integer questionId; + public DateTime startDate; + public DateTime expireDate; + + private QuestionCard(final Long accountId, + final Integer questionId, + final DateTime startDate, + final DateTime expireDate) { + this.accountId = accountId; + this.questionId = questionId; + this.startDate = startDate; + this.expireDate = expireDate; + } + + public static QuestionCard createQuestionCard(final Long accountId, + final Integer questionId, + final DateTime startDate, + final DateTime expireDate) { + return new QuestionCard(accountId, questionId, startDate, expireDate); + } +} diff --git a/suripu-core/src/main/java/com/hello/suripu/core/models/Questions/QuestionCategory.java b/suripu-core/src/main/java/com/hello/suripu/core/models/Questions/QuestionCategory.java index 5e6a89704..d282abdc6 100644 --- a/suripu-core/src/main/java/com/hello/suripu/core/models/Questions/QuestionCategory.java +++ b/suripu-core/src/main/java/com/hello/suripu/core/models/Questions/QuestionCategory.java @@ -11,7 +11,8 @@ public enum QuestionCategory { ANOMALY_LIGHT("anomaly_light"), GOAL_GO_OUTSIDE("goal_go_outside"), GOAL("goal"), - SURVEY("survey"); + SURVEY("survey"), + INSIGHT("insight"); //paired with insight, should be 1st priority private String value; diff --git a/suripu-core/src/main/java/com/hello/suripu/core/processors/InsightProcessor.java b/suripu-core/src/main/java/com/hello/suripu/core/processors/InsightProcessor.java index 89eb6a9c4..7dafa4711 100644 --- a/suripu-core/src/main/java/com/hello/suripu/core/processors/InsightProcessor.java +++ b/suripu-core/src/main/java/com/hello/suripu/core/processors/InsightProcessor.java @@ -5,6 +5,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.hello.suripu.core.db.AccountReadDAO; @@ -15,6 +16,8 @@ import com.hello.suripu.core.db.DeviceReadDAO; import com.hello.suripu.core.db.InsightsDAODynamoDB; import com.hello.suripu.core.db.MarketingInsightsSeenDAODynamoDB; +import com.hello.suripu.core.db.QuestionResponseDAO; +import com.hello.suripu.core.db.QuestionResponseReadDAO; import com.hello.suripu.core.db.SleepStatsDAODynamoDB; import com.hello.suripu.core.db.TrendsInsightsDAO; import com.hello.suripu.core.flipper.FeatureFlipper; @@ -24,6 +27,9 @@ import com.hello.suripu.core.models.Insights.InfoInsightCards; import com.hello.suripu.core.models.Insights.InsightCard; import com.hello.suripu.core.models.Insights.MarketingInsightsSeen; +import com.hello.suripu.core.models.Insights.QuestionCard; +import com.hello.suripu.core.models.Question; +import com.hello.suripu.core.models.Questions.QuestionCategory; import com.hello.suripu.core.preferences.AccountPreferencesDAO; import com.hello.suripu.core.preferences.PreferenceName; import com.hello.suripu.core.preferences.TemperatureUnit; @@ -42,6 +48,7 @@ import com.hello.suripu.core.processors.insights.SleepDeprivation; import com.hello.suripu.core.processors.insights.SleepMotion; import com.hello.suripu.core.processors.insights.SoundDisturbance; +import com.hello.suripu.core.processors.insights.StrictAlarm; import com.hello.suripu.core.processors.insights.TemperatureHumidity; import com.hello.suripu.core.processors.insights.WakeStdDevData; import com.hello.suripu.core.processors.insights.WakeVariance; @@ -99,6 +106,7 @@ public class InsightProcessor { private final AccountReadDAO accountReadDAO; private final CalibrationDAO calibrationDAO; private final MarketingInsightsSeenDAODynamoDB marketingInsightsSeenDAODynamoDB; + private final QuestionResponseDAO questionResponseDAO; private static final ImmutableSet marketingInsightPool = ImmutableSet.copyOf(Sets.newHashSet(InsightCard.Category.DRIVE, InsightCard.Category.EAT, @@ -109,6 +117,8 @@ public class InsightProcessor { InsightCard.Category.SWIM, InsightCard.Category.WORK)); + private final Map strictAlarmTextQidMap; + public InsightProcessor(@NotNull final DeviceDataDAODynamoDB deviceDataDAODynamoDB, @NotNull final DeviceReadDAO deviceReadDAO, @NotNull final TrendsInsightsDAO trendsInsightsDAO, @@ -122,7 +132,9 @@ public InsightProcessor(@NotNull final DeviceDataDAODynamoDB deviceDataDAODynamo @NotNull final LightData lightData, @NotNull final WakeStdDevData wakeStdDevData, @NotNull final CalibrationDAO calibrationDAO, - @NotNull final MarketingInsightsSeenDAODynamoDB marketingInsightsSeenDAODynamoDB + @NotNull final MarketingInsightsSeenDAODynamoDB marketingInsightsSeenDAODynamoDB, + @NotNull final QuestionResponseDAO questionResponseDAO, + @NotNull final Map strictAlarmTextQidMap ) { this.deviceDataDAODynamoDB = deviceDataDAODynamoDB; this.deviceReadDAO = deviceReadDAO; @@ -138,6 +150,8 @@ public InsightProcessor(@NotNull final DeviceDataDAODynamoDB deviceDataDAODynamo this.accountReadDAO = accountReadDAO; this.calibrationDAO = calibrationDAO; this.marketingInsightsSeenDAODynamoDB = marketingInsightsSeenDAODynamoDB; + this.questionResponseDAO = questionResponseDAO; + this.strictAlarmTextQidMap = strictAlarmTextQidMap; } public void generateInsights(final Long accountId, final DateTime accountCreated, final RolloutClient featureFlipper) { @@ -169,7 +183,7 @@ private Optional generateNewUserInsights(final Long accoun if (featureFlipper.userFeatureActive(FeatureFlipper.INSIGHTS_LAST_SEEN, accountId, Collections.EMPTY_LIST)) { final List insightsLastSeenList = this.insightsLastSeenDAO.getAll(accountId); recentCategories = InsightsLastSeen.getLastSeenInsights(insightsLastSeenList); - }else { + } else { recentCategories = this.getRecentInsightsCategories(accountId); } return generateNewUserInsights(accountId, accountAge, recentCategories); @@ -464,7 +478,10 @@ public Optional generateInsightsByCategory(final Long acco final DateTimeFormatter timeFormat; final TemperatureUnit tempUnit; + final DateTime queryEndDate = DateTime.now(DateTimeZone.UTC).withTimeAtStartOfDay(); + Optional insightCardOptional = Optional.absent(); + Optional questionCardOptional = Optional.absent(); switch (category) { case AIR_QUALITY: insightCardOptional = Particulates.getInsights(accountId, deviceAccountPair, sleepStatsDAODynamoDB, deviceDataInsightQueryDAO, calibrationDAO); @@ -538,6 +555,9 @@ public Optional generateInsightsByCategory(final Long acco case SOUND: insightCardOptional = SoundDisturbance.getInsights(accountId, deviceAccountPair, deviceDataDAODynamoDB, sleepStatsDAODynamoDB); break; + case STRICT_ALARM: + questionCardOptional = StrictAlarm.getQuestion(sleepStatsDAODynamoDB, accountId, queryEndDate, DAYS_ONE_WEEK, strictAlarmTextQidMap); + break; case SWIM: insightCardOptional = MarketingInsights.getSwimInsight(accountId); break; @@ -546,7 +566,6 @@ public Optional generateInsightsByCategory(final Long acco insightCardOptional = TemperatureHumidity.getInsights(accountId, deviceAccountPair, deviceDataInsightQueryDAO, tempUnit, sleepStatsDAODynamoDB); break; case WAKE_VARIANCE: - final DateTime queryEndDate = DateTime.now(DateTimeZone.UTC).withTimeAtStartOfDay(); insightCardOptional = WakeVariance.getInsights(sleepStatsDAODynamoDB, accountId, wakeStdDevData, queryEndDate, DAYS_ONE_WEEK); break; case WORK: @@ -565,6 +584,15 @@ public Optional generateInsightsByCategory(final Long acco final InsightsLastSeen newInsight = new InsightsLastSeen(accountId, insightCardOptional.get().category, DateTime.now(DateTimeZone.UTC)); this.insightsLastSeenDAO.markLastSeen(newInsight); return Optional.of(category); + + } else if (questionCardOptional.isPresent()) { + final QuestionCard questionCard = questionCardOptional.get(); + + //insert question to postgres + this.questionResponseDAO.insertAccountQuestion(questionCard.accountId, questionCard.questionId, questionCard.startDate, questionCard.expireDate); + final InsightsLastSeen newMockInsight = new InsightsLastSeen(accountId, category, DateTime.now(DateTimeZone.UTC)); + this.insightsLastSeenDAO.markLastSeen(newMockInsight); + return Optional.of(category); } return Optional.absent(); @@ -664,6 +692,8 @@ public static class Builder { private @Nullable AccountInfoProcessor accountInfoProcessor; private @Nullable CalibrationDAO calibrationDAO; private @Nullable MarketingInsightsSeenDAODynamoDB marketingInsightsSeenDAODynamoDB; + private @Nullable QuestionResponseDAO questionResponseDAO; + private @Nullable Map strictAlarmTextQidMap; public Builder withMarketingInsightsSeenDAO(final MarketingInsightsSeenDAODynamoDB marketingInsightsSeenDAO) { this.marketingInsightsSeenDAODynamoDB = marketingInsightsSeenDAO; @@ -719,6 +749,25 @@ public Builder withCalibrationDAO(final CalibrationDAO calibrationDAO) { return this; } + public Builder withQuestionResponseDAO(final QuestionResponseDAO questionResponseDAO) { + this.questionResponseDAO = questionResponseDAO; + return this; + } + + public Builder withQuestions(final QuestionResponseDAO questionResponseDAO) { + this.strictAlarmTextQidMap = new HashMap<>(); + + final List allQuestions = questionResponseDAO.getAllQuestions(); + for (final Question question : allQuestions) { + if (question.category != QuestionCategory.INSIGHT) { + continue; + } + this.strictAlarmTextQidMap.put(question.text, question.id); + } + + return this; + } + public InsightProcessor build() { checkNotNull(deviceReadDAO, "deviceReadDAO can not be null"); checkNotNull(trendsInsightsDAO, "trendsInsightsDAO can not be null"); @@ -733,8 +782,11 @@ public InsightProcessor build() { checkNotNull(wakeStdDevData, "wakeStdDevData cannot be null"); checkNotNull(calibrationDAO, "calibrationDAO cannot be null"); checkNotNull(marketingInsightsSeenDAODynamoDB, "marketInsightsSeenDAO cannot be null"); + checkNotNull(questionResponseDAO, "questionResponseDAO cannot be null"); + checkNotNull(strictAlarmTextQidMap, "textQidMap cannot be null"); - return new InsightProcessor(deviceDataDAODynamoDB, + return new InsightProcessor( + deviceDataDAODynamoDB, deviceReadDAO, trendsInsightsDAO, scoreDAODynamoDB, @@ -747,7 +799,9 @@ public InsightProcessor build() { lightData, wakeStdDevData, calibrationDAO, - marketingInsightsSeenDAODynamoDB); + marketingInsightsSeenDAODynamoDB, + questionResponseDAO, + strictAlarmTextQidMap); } } } diff --git a/suripu-core/src/main/java/com/hello/suripu/core/processors/QuestionSurveyProcessor.java b/suripu-core/src/main/java/com/hello/suripu/core/processors/QuestionSurveyProcessor.java index 24ddc7fda..a823191a2 100644 --- a/suripu-core/src/main/java/com/hello/suripu/core/processors/QuestionSurveyProcessor.java +++ b/suripu-core/src/main/java/com/hello/suripu/core/processors/QuestionSurveyProcessor.java @@ -122,7 +122,6 @@ public List getSurveyQuestions(final Long accountId, final DateTime to /* Insert questions */ - private void saveQuestion(final Long accountId, final Question question, final DateTime todayLocal, final DateTime expireDate) { LOGGER.debug("action=saved_question processor=question_survey account_id={} question_id={} today_local={} expire_date={}", accountId, question.id, todayLocal, expireDate); this.questionResponseDAO.insertAccountQuestion(accountId, question.id, todayLocal, expireDate); diff --git a/suripu-core/src/main/java/com/hello/suripu/core/processors/insights/StrictAlarm.java b/suripu-core/src/main/java/com/hello/suripu/core/processors/insights/StrictAlarm.java new file mode 100644 index 000000000..fc749fbdc --- /dev/null +++ b/suripu-core/src/main/java/com/hello/suripu/core/processors/insights/StrictAlarm.java @@ -0,0 +1,148 @@ +package com.hello.suripu.core.processors.insights; + +import com.google.common.base.Optional; +import com.google.common.collect.Lists; +import com.hello.suripu.core.db.SleepStatsDAODynamoDB; +import com.hello.suripu.core.models.AggregateSleepStats; +import com.hello.suripu.core.models.Insights.InsightCard; +import com.hello.suripu.core.models.Insights.QuestionCard; +import com.hello.suripu.core.processors.InsightProcessor; +import com.hello.suripu.core.util.DateTimeUtil; +import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.Map; + +/** + * Created by jyfan on 10/31/16. + */ +public class StrictAlarm { + + private static final Logger LOGGER = LoggerFactory.getLogger(WakeVariance.class); + private static final int NUM_DAYS_ONE_WEEK = 7; + + public static Optional getQuestion(final SleepStatsDAODynamoDB sleepStatsDAODynamoDB, final Long accountId, final DateTime queryEndDate, final int numDays, final Map strictAlarmTextQidMap) { + + //get wake variance data for the past n=numDays days + final DateTime queryStartDate = queryEndDate.minusDays(numDays); + final String queryEndDateString = DateTimeUtil.dateToYmdString(queryEndDate); + final String queryStartDateString = DateTimeUtil.dateToYmdString(queryStartDate); + + final List sleepStats = sleepStatsDAODynamoDB.getBatchStats(accountId, queryStartDateString, queryEndDateString); + LOGGER.debug("insight=wake-variance sleep_stat_len={} account_id={}", sleepStats.size(), accountId); + final List wakeTimeList = Lists.newArrayList(); + final List weekdayWakeTimeList = Lists.newArrayList(); + for (final AggregateSleepStats stat : sleepStats) { + + final Long wakeTimeStamp = stat.sleepStats.wakeTime; + final DateTime wakeTimeDateTime = new DateTime(wakeTimeStamp, DateTimeZone.forOffsetMillis(stat.offsetMillis)); + final int wakeTime = wakeTimeDateTime.getMinuteOfDay(); + wakeTimeList.add(wakeTime); + + final int dayOfWeek = wakeTimeDateTime.getDayOfWeek(); + if (dayOfWeek < 5) { //if weekday (exclude friday night/sat morning) + weekdayWakeTimeList.add(wakeTime); + } + + } + + final Boolean qualifyInsight = qualifyStrictAlarm(wakeTimeList); + if (!qualifyInsight) { + return Optional.absent(); + } + + if (weekdayWakeTimeList.isEmpty()) { + return Optional.absent(); + } + + //calculate target wake time + final Integer recWeekdayWakeMins = getRecommendedWakeMinutes(weekdayWakeTimeList); + final Optional recQidOptional = mapWakeTimeToQid(recWeekdayWakeMins, strictAlarmTextQidMap); + + if (!recQidOptional.isPresent()) { + return Optional.absent(); + } + + final Integer offsetMillis = sleepStats.get(0).offsetMillis; + final DateTime todayLocal = DateTime.now(DateTimeZone.UTC).plusMillis(offsetMillis).withTimeAtStartOfDay(); + final DateTime expireDate = todayLocal.plusDays(NUM_DAYS_ONE_WEEK); + + return Optional.of(QuestionCard.createQuestionCard(accountId, recQidOptional.get(), todayLocal, expireDate)); + } + + public static Boolean qualifyStrictAlarm(final List wakeTimeList) { + + if (wakeTimeList.isEmpty() || wakeTimeList.size() <=2) { + return Boolean.FALSE; //not big enough to calculate variance usefully + } + + // compute variance + final DescriptiveStatistics stats = new DescriptiveStatistics(); + for (final int wakeTime : wakeTimeList) { + stats.addValue(wakeTime); + } + + final Double wakeStdDevDouble = stats.getStandardDeviation(); + final int wakeStdDev = (int) Math.round(wakeStdDevDouble); + + if (wakeStdDev >= 90) { //1.5 hours + return Boolean.TRUE; + } + + return Boolean.FALSE; + } + + public static Integer getRecommendedWakeMinutes(final List weekdayWakeTimeList) { + + final DescriptiveStatistics stats = new DescriptiveStatistics(); + for (final int wakeTime : weekdayWakeTimeList) { + stats.addValue(wakeTime); + } + + final int avgWeekdayWake = (int) stats.getMean(); + + return avgWeekdayWake; + } + + public static Optional mapWakeTimeToQid(final Integer recommendedWakeTimeMins, final Map textQidMap) { + + final String questionText; + + if (recommendedWakeTimeMins < 360) { //6AM + questionText = "nonexistent question"; + } else if (recommendedWakeTimeMins < 375) { //6:30AM + questionText = "You could benefit from a consistent wake time. Set a recurring alarm for 6:00 AM? Existing alarms will be deleted."; + } else if (recommendedWakeTimeMins < 405) { //6:45AM + questionText = "You could benefit from a consistent wake time. Set a recurring alarm for 6:30 AM? Existing alarms will be deleted."; //TODO edit to real time + } else if (recommendedWakeTimeMins < 435) { //7:15AM + questionText = "You could benefit from a consistent wake time. Set a recurring alarm for 7:00 AM? Existing alarms will be deleted."; + } else if (recommendedWakeTimeMins < 465) { //7:45AM + questionText = "You could benefit from a consistent wake time. Set a recurring alarm for 7:30 AM? Existing alarms will be deleted."; + } else if (recommendedWakeTimeMins < 495) { //8:15AM + questionText = "You could benefit from a consistent wake time. Set a recurring alarm for 8:00 AM? Existing alarms will be deleted."; + } else if (recommendedWakeTimeMins < 525) { //8:45AM + questionText = "You could benefit from a consistent wake time. Set a recurring alarm for 8:30 AM? Existing alarms will be deleted."; + } else if (recommendedWakeTimeMins < 555) { //9:15AM + questionText = "You could benefit from a consistent wake time. Set a recurring alarm for 9:00 AM? Existing alarms will be deleted."; + } else if (recommendedWakeTimeMins < 585) { //9:45AM + questionText = "You could benefit from a consistent wake time. Set a recurring alarm for 9:30 AM? Existing alarms will be deleted."; + } else if (recommendedWakeTimeMins < 630) { //10:30AM + questionText = "You could benefit from a consistent wake time. Set a recurring alarm for 10:00 AM? Existing alarms will be deleted."; + } else { + questionText = "nonexistent question"; + } + + final Integer qid = textQidMap.get(questionText); + if (qid == null) { + return Optional.absent(); + } + + return Optional.of(qid); + } + + +} diff --git a/suripu-core/src/main/java/com/hello/suripu/core/util/QuestionUtils.java b/suripu-core/src/main/java/com/hello/suripu/core/util/QuestionUtils.java index dc36667d0..b595735ed 100644 --- a/suripu-core/src/main/java/com/hello/suripu/core/util/QuestionUtils.java +++ b/suripu-core/src/main/java/com/hello/suripu/core/util/QuestionUtils.java @@ -21,16 +21,18 @@ public static ImmutableList sortQuestionByCategory(final List strictAlarmTextQidMap = new HashMap<>(); //Prepping for taking care of @NotNull check for light final int light = 2; @@ -244,7 +248,9 @@ private InsightProcessor setUp() { lightData, wakeStdDevData, calibrationDAO, - marketingInsightsSeenDAODynamoDB); + marketingInsightsSeenDAODynamoDB, + questionResponseDAO, + strictAlarmTextQidMap); //only to get rid of null pointer exception final InsightCard insightCardMock = Mockito.mock(InsightCard.class); diff --git a/suripu-core/src/test/java/com/hello/suripu/core/util/SenseOneFiveDataConversionTest.java b/suripu-core/src/test/java/com/hello/suripu/core/util/SenseOneFiveDataConversionTest.java index b42097fc5..c4976dee0 100644 --- a/suripu-core/src/test/java/com/hello/suripu/core/util/SenseOneFiveDataConversionTest.java +++ b/suripu-core/src/test/java/com/hello/suripu/core/util/SenseOneFiveDataConversionTest.java @@ -33,7 +33,7 @@ public class SenseOneFiveDataConversionTest { final float ALERT_CO2_HIGH = 1200; final float ALERT_UV_HIGH = 2; - + @Test public void testRGBtoLux_one() throws IOException { final float LUXMETER_GOLDSTANDARD_MIN = 500;