def test_check_first_run(self): self.assertFalse(state_db.is_set(state_db.Keys.FIRST_MEETING)) self.abm_interaction.set_prompt_to_handle() self.abm_interaction.run_scheduler_once() self.assertTrue(state_db.is_set(state_db.Keys.FIRST_MEETING)) self.assertTrue(state_db.get(state_db.Keys.IS_DONE_AM_CHECKIN_TODAY)) self.assertFalse(state_db.get(state_db.Keys.IS_DONE_PM_CHECKIN_TODAY))
def test_select_first_meeting(self): self.true_plan.insert(FirstMeeting.first_meeting) self.assertFalse(state_db.is_set(state_db.Keys.FIRST_MEETING)) resulting_plan = self.builder.build() self.assertEqual(self.true_plan, resulting_plan) simulate_run_plan(resulting_plan) self.assertTrue(state_db.is_set(state_db.Keys.FIRST_MEETING))
def test_prompt_interactions(self, _): """ Note that the steps goals and numbers get in a weird positive feedback loop because of how I monkey patched the fitbit reader """ num_days = param_db.get(param_db.Keys.WEEKS_WITH_ROBOT)*7 initial_datetime = datetime.datetime( year=2019, month=1, day=1, hour=8, minute=6, second=3 ) with freeze_time(initial_datetime) as frozen_datetime: state_db.reset() self.abm_interaction = AbmInteraction() self.update_after_first_meeting() pm_checkin_datetime = self.get_pm_checkin_datetime(0, initial_datetime) frozen_datetime.move_to(pm_checkin_datetime) self.update_day_steps() self.abm_interaction.set_prompt_to_handle() self.abm_interaction.run_scheduler_once() self.update_after_am_checkin() self.assertTrue(state_db.is_set(state_db.Keys.FIRST_MEETING)) self.assertTrue(state_db.get(state_db.Keys.IS_DONE_AM_CHECKIN_TODAY)) self.assertTrue(state_db.get(state_db.Keys.IS_DONE_PM_CHECKIN_TODAY)) self.assertTrue(state_db.get(state_db.Keys.IS_MET_GOAL)) for day in range(1, num_days + 2): am_checkin_datetime = self.get_am_checkin_datetime(day, initial_datetime) frozen_datetime.move_to(am_checkin_datetime) self.abm_interaction._new_day_update() self.abm_interaction.set_prompt_to_handle() self.abm_interaction.run_scheduler_once() self.update_after_am_checkin() # Run non consequential off-checkin for _ in range(2): self.abm_interaction.set_prompt_to_handle() self.abm_interaction.run_scheduler_once() self.assertTrue(state_db.get(state_db.Keys.IS_DONE_AM_CHECKIN_TODAY)) self.assertFalse(state_db.get(state_db.Keys.IS_DONE_PM_CHECKIN_TODAY)) pm_checkin_datetime = self.get_pm_checkin_datetime(day, initial_datetime) frozen_datetime.move_to(pm_checkin_datetime) self.update_day_steps() self.abm_interaction.set_prompt_to_handle() self.abm_interaction.run_scheduler_once() self.assertTrue(state_db.get(state_db.Keys.IS_DONE_AM_CHECKIN_TODAY)) self.assertTrue(state_db.get(state_db.Keys.IS_DONE_PM_CHECKIN_TODAY)) self.assertTrue(state_db.get(state_db.Keys.IS_MET_GOAL)) # Run non consequential off-checkin for _ in range(2): self.abm_interaction._build_and_run_plan()
def run_scheduler_once(self): self._update_scheduler.run_pending() if not state_db.is_set( state_db.Keys.FIRST_MEETING) or self._is_prompt_to_run: self._update_todays_steps() self._build_and_run_plan() self._is_prompt_to_run = False else: self._checkin_scheduler.run_pending() self._is_go_to_sleep_publisher.publish(Bool(data=True))
def _is_first_meeting(self): return not state_db.is_set(state_db.Keys.FIRST_MEETING)
def __init__( self, credentials_file_path="fitbit_credentials.yaml", redirect_url="http://localhost", is_data_recording_topic='data_capture/is_record', automaticity_topic='abm/automaticity', is_go_to_sleep_topic='cordial/sleep', interface=None, is_reset_state_db=False, goal_setter=None, ): if is_reset_state_db: logging.info("Reseting database") state_db.reset() self._plan_builder = PlanBuilder() if interface is None: interface = TerminalClientAndServerInterface(state_db) self._interface = interface self._fitbit = AbmFitbitClient( credentials_file_path=credentials_file_path, redirect_url=redirect_url, ) start_days_before_first_meeting = datetime.timedelta(days=7) if state_db.is_set(state_db.Keys.FIRST_MEETING): start_date = state_db.get( state_db.Keys.FIRST_MEETING) - start_days_before_first_meeting else: start_date = datetime.datetime.now( ) - start_days_before_first_meeting if goal_setter is None: logging.info('Creating goal setter') goal_setter = GoalSetter( fitbit_active_steps_fn=self._fitbit.get_total_steps, start_date=start_date, num_weeks=param_db.get(param_db.Keys.WEEKS_WITH_ROBOT) + 1, # +1 for week with just fitbit final_week_goal=param_db.get(param_db.Keys.FINAL_STEPS_GOAL), min_weekly_steps_goal=param_db.get( param_db.Keys.MIN_WEEKLY_STEPS_GOAL), week_goal_min_improvement_ratio=1.1, week_goal_max_improvement_ratio=2.0, daily_goal_min_to_max_ratio=2.5, ) self._goal_setter = goal_setter self._is_recording_publisher = rospy.Publisher(is_data_recording_topic, Bool, queue_size=1) self._automaticity_publisher = rospy.Publisher(automaticity_topic, Float32, queue_size=1) self._is_go_to_sleep_publisher = rospy.Publisher(is_go_to_sleep_topic, Bool, queue_size=1) self._update_week_steps_and_goals() self._update_todays_steps() self._checkin_scheduler = schedule.Scheduler() self._update_scheduler = schedule.Scheduler() self._update_scheduler.every(15).seconds.do(self._new_day_update) self._is_prompt_to_run = False if state_db.is_set(state_db.Keys.FIRST_MEETING): self._build_checkin_schedule() state_db.set(state_db.Keys.IS_REDO_SCHEDULE, False) else: self._init_vars()