def showForms(): form = ShiftLogForm() shiftLogDAO = shift_log_DAO() resident_list = shiftLogDAO.get_incompleted_residents() form.resident.choices = [(resident_map['resident_id'], resident_map['name']) for resident_map in resident_list] resident_dict = { resident_map['resident_id']: resident_map['name'] for resident_map in resident_list } if request.method == 'POST': if form.validate_on_submit(): # handle submitted data here # process form here submitted_name = form.resident.data # name_to_show = "testing" name_to_show = resident_dict[submitted_name] submitted_date = form.date.data submitted_time = form.time.data submitted_falls = form.falls.data submitted_near_falls = form.near_falls.data submitted_consumption = form.consumption.data submitted_toilet_visits = 0 submitted_temperature = form.temperature.data submitted_sbp = form.sbp.data submitted_dbp = form.dbp.data submitted_pulse = form.pulse.data # shiftLogDAO = shift_log_DAO() if submitted_time == 1: day_night = "Day" else: day_night = "Night" shiftLog = Shift_log(submitted_date, submitted_time, submitted_name, submitted_falls, submitted_near_falls, submitted_consumption, submitted_toilet_visits, submitted_temperature, submitted_sbp, submitted_dbp, submitted_pulse) response = 'Shift log for ' + submitted_date.strftime( '%Y-%m-%d' ) + '(' + day_night + ') for ' + name_to_show + ' has already been recorded. Please enter another date.' try: shiftLogDAO.insert_shift_log(shiftLog) except: flash(response) return render_template('eosforms.html', form=form) response = 'Shift log for ' + name_to_show + ' has been successfully recorded. Click <a href="/admin/shift_log" class="alert-link">here</a> to view/edit responses.' flash(Markup(response)) return redirect(url_for('showForms')) else: return render_template('eosforms.html', form=form) else: return render_template('eosforms.html', form=form)
def create_view(self): form = ShiftLogForm() shiftLogDAO = shift_log_DAO() resident_list = shiftLogDAO.get_incompleted_residents() form.resident.choices = [(resident_map['resident_id'], resident_map['name']) for resident_map in resident_list] return render_template('eosforms.html', form=form)
def showOverviewResidents(): ''' This method prepares all the necessary variables to pass into the html for display Each resident will have the following: Name ('name'), List of Toilet Alerts ('toilet_alerts'), List of Sleep Alerts (WIP), Overall Alert Level ('alert_highest') NOTE: jinja templates do not allow for import of python modules, so all calculation will be done here ''' residents_raw = resident_DAO.get_list_of_residents() residents = [] date_in_use = datetime.datetime.now() # date_in_use = datetime.datetime(2018, 4, 19, 23, 34, 12) # TODO: change to current system time once live data is available juvo_date_in_use = datetime.datetime.now( ) # datetime.datetime(2018, 8, 12, 22, 34, 12) # TODO: change to current system time once live data is available for resident in residents_raw: r = {} r['name'] = resident['name'] r['resident_id'] = resident['resident_id'] # settle night toilet usage r['toilet_alerts'], __ = input_data.input_data.get_nightly_toilet_indicator( int(resident['resident_id']), date_in_use) r['toilet_tooltip'] = [] if len(r['toilet_alerts']) == 0: r['toilet_tooltip'].append( "Night toilet visit numbers appear normal") else: # NOTE: right now we just append, but use separate list for tooltips in case of future changes r['toilet_tooltip'].extend(r['toilet_alerts']) # settle sleep duration r['sleep_alerts'], __, __, __, __, __, __ = input_data.input_data.get_nightly_sleep_indicator( int(resident['resident_id']), date_in_use) r['sleep_tooltip'] = [] if len(r['sleep_alerts']) == 0: r['sleep_tooltip'].append( "Normal level of motion during sleep detected") else: # NOTE: for future changes r['sleep_tooltip'].extend(r['sleep_alerts']) r['vitals_alerts'], __, __, __, __ = input_data.input_data.get_vital_signs_indicator( resident['resident_id'], juvo_date_in_use) r['vitals_tooltip'] = [] if len(r['vitals_alerts']) == 0: r['vitals_tooltip'].append( "Vital signs from previous week appear to be normal") else: r['vitals_tooltip'].extend(r['vitals_alerts']) # print("DEBUG resident id sleep_alerts", resident['resident_id'], r['sleep_alerts']) r['alert_highest'] = max(0, len(r['toilet_alerts']), len(r['sleep_alerts']), len(r['vitals_alerts'])) residents.append(r) # return render_template('overview_residents_amanda.html', residents=residents) information = {} information['num_residents'] = len( resident_DAO.get_list_of_residents(location_filter='STB')) num_good_health = 0 for r_dict in residents: if r_dict['alert_highest'] == 0: num_good_health += 1 information['health_percentage'] = num_good_health / information[ 'num_residents'] * 100 # in percentage sldao = shift_log_DAO.shift_log_DAO() information['num_shift_forms'] = sldao.get_today_logs() sensor_statuses = sensor_mgmt.Sensor_mgmt.get_all_sensor_status_v2( retBatteryLevel=True) # print(sensor_statuses) sensor_down_count = 0 for _sensor in sensor_statuses: if _sensor[1][0] > 0: sensor_down_count += 1 information['sensors_down'] = sensor_down_count return render_template('overview_residents.html', residents=residents, information=information)
class input_shiftlogs(object): # input_raw_data = pd.DataFrame() sldao = shift_log_DAO() input_raw_data = sldao.get_all_logs() input_raw_data['datetime'] = pd.to_datetime(input_raw_data['datetime'], format='%Y-%m-%dT%H:%M:%S') input_raw_data['food_consumption'] = pd.to_numeric( input_raw_data['food_consumption']) input_raw_data['pulse_pressure'] = input_raw_data[ 'systolic_bp'] - input_raw_data['diastolic_bp'] input_raw_max_date = input_raw_data['datetime'].max() input_raw_min_date = input_raw_data['datetime'].min() # print(input_raw_data) daytime_start = datetime.time(7, 30) daytime_end = datetime.time(19, 30) # changeable parameters NOTE: should be changeable para_temperature_max = 37.6 para_temperature_min = 35.5 para_temperature_sd = 0.66 para_pulse_pressure_max = 50 @staticmethod def update_shiftlogs_data(): input_shiftlogs.input_raw_data = input_shiftlogs.sldao.get_all_logs() input_shiftlogs.input_raw_data['datetime'] = pd.to_datetime( input_shiftlogs.input_raw_data['datetime'], format='%Y-%m-%dT%H:%M:%S') input_shiftlogs.input_raw_data['food_consumption'] = pd.to_numeric( input_shiftlogs.input_raw_data['food_consumption']) input_shiftlogs.input_raw_data[ 'pulse_pressure'] = input_shiftlogs.input_raw_data[ 'systolic_bp'] - input_shiftlogs.input_raw_data['diastolic_bp'] input_shiftlogs.input_raw_max_date = input_shiftlogs.input_raw_data[ 'datetime'].max() input_shiftlogs.input_raw_min_date = input_shiftlogs.input_raw_data[ 'datetime'].min() @staticmethod def date_only(original_date): return original_date.replace(hour=0, minute=0, second=0, microsecond=0) @staticmethod def get_logs_filter_options(): '''Returns labels and values in an array of tuples''' return [('No. of Falls', 'num_falls'), ('No. of Near Falls', 'num_near_falls'), ('Food Consumption', 'food_consumption'), ('Temperature', 'temperature'), ('Systolic//Diastolic Bp', 'sys_dia'), ('Pulse Pressure', 'pulse_pressure'), ('Pulse Rate', 'pulse_rate')] @staticmethod def get_relevant_data(start_date, end_date, patient_id): ''' Retrieve sensor data based on location, start and end dates, and the device grouped=True to get grouped data for toilet visits ''' # TODO: this part probably is the best to convert to retrieve from DB relevant_data = input_shiftlogs.input_raw_data.loc[ (input_shiftlogs.input_raw_data['patient_id'] == patient_id) & (input_shiftlogs.input_raw_data['datetime'] < end_date) & (input_shiftlogs.input_raw_data['datetime'] > start_date), [ 'patient_id', 'datetime', 'num_falls', 'num_near_falls', 'food_consumption', 'temperature', 'systolic_bp', 'diastolic_bp', 'pulse_pressure', 'pulse_rate' ]] return relevant_data @staticmethod def get_logs_by_date(start_date=input_raw_min_date, end_date=input_raw_max_date, patient_id=1, time_period=None): """ Function returns dates and aggregated number of times the sensor was activated To get day only, use time_period='Day' and to get night_only use time_period='Night' """ # NOTE: last day of the returned output is not accurate if offset is used because the next day's data is needed to get the current night's data current_data = input_shiftlogs.get_relevant_data( start_date, end_date, patient_id) # print(current_data) # print(current_data) if time_period == 'Day': current_data = current_data.loc[(current_data['datetime'].dt.time >= input_shiftlogs.daytime_start) & (current_data['datetime'].dt.time < input_shiftlogs.daytime_end)] elif time_period == 'Night': current_data = current_data.loc[ (current_data['datetime'].dt.time < input_shiftlogs. daytime_start) | (current_data['datetime'].dt.time > input_shiftlogs.daytime_end )] # group by date only current_data['date_only'] = current_data['datetime'].apply( input_shiftlogs.date_only) result_data = current_data.groupby( ['date_only'], as_index=False)['num_falls', 'num_near_falls', 'food_consumption', 'temperature', 'systolic_bp', 'diastolic_bp', 'pulse_pressure', 'pulse_rate'].mean() # add 0 for days with no data result_data.set_index('date_only', inplace=True) if isinstance(start_date, str): start_date = datetime.datetime.strptime(start_date, '%Y-%m-%d') if isinstance(end_date, str): end_date = datetime.datetime.strptime(end_date, '%Y-%m-%d') all_days_range = pd.date_range(start_date.date(), end_date.date() + datetime.timedelta(days=-1), freq='D') try: result_data = result_data.loc[all_days_range] except KeyError as e: erroroutput = pd.DataFrame() erroroutput['num_falls'] = [] erroroutput['num_near_falls'] = [] erroroutput['food_consumption'] = [] erroroutput['temperature'] = [] erroroutput['systolic_bp'] = [] erroroutput['diastolic_bp'] = [] erroroutput['pulse_pressure'] = [] erroroutput['pulse_rate'] = [] erroroutput['date_only'] = [] result_data.fillna(0, inplace=True) # undo set index result_data.reset_index(inplace=True) result_data.rename(columns={'index': 'date_only'}, inplace=True) # print("result data from get_num_visits_by_date\n", result_data) return result_data @staticmethod def get_residents_options(): return input_shiftlogs.input_raw_data['patient_id'].unique().tolist() @staticmethod def get_shiftlog_indicators(patient_id, current_sys_time=None): ret_alerts = [] if not current_sys_time: current_sys_time = datetime.datetime.now() current_sys_date = current_sys_time.date() three_weeks_ago = current_sys_date + datetime.timedelta(days=-21) one_week_ago = current_sys_date + datetime.timedelta(days=-7) four_weeks_ago = current_sys_date + datetime.timedelta(days=-28) # get data first current_data = input_shiftlogs.get_relevant_data( four_weeks_ago, current_sys_date, patient_id) # print(current_data) # patient_id,datetime,num_falls,num_near_falls,food_consumption,temperature,systolic_bp,diastolic_bp,pulse_pressure,pulse_rate # compare averages three_week_data = current_data.loc[(current_data['datetime'] < one_week_ago)] # print(three_week_data) past_week_data = current_data.loc[ current_data['datetime'] > one_week_ago] # print(past_week_data) # check averages then check for significant out-of-range numbers # check temperatures temperature_sd = three_week_data['temperature'].std( ) # NOTE: maybe can change to some other stdevs three_week_average_temp = three_week_data['temperature'].mean() past_week_average_temp = past_week_data['temperature'].mean() if (past_week_average_temp - input_shiftlogs.para_temperature_sd * temperature_sd) > three_week_average_temp: ret_alerts.append( "Significant increase in temperature in the past week") elif (past_week_average_temp + input_shiftlogs.para_temperature_sd * temperature_sd) < three_week_average_temp: ret_alerts.append( "Significant decrease in temperature in the past week") if any((past_week_data['temperature'] < input_shiftlogs.para_temperature_min) | (past_week_data['temperature'] > input_shiftlogs.para_temperature_max)): ret_alerts.append("Abnormal temperatures detected in past week") return ret_alerts
import pandas as pd import datetime # pandas settings pd.options.mode.chained_assignment = None # default='warn pd.set_option('display.expand_frame_repr', False) if __name__ == '__main__': # we want to import from same directory if using this # module as-is (for debugging mainly, or for loading data in the future) sys.path.append(".") from DAOs.shift_log_DAO import shift_log_DAO else: # if called from index.py from DAOs.shift_log_DAO import shift_log_DAO # input_raw_data = pd.DataFrame() sldao = shift_log_DAO() input_raw_data = sldao.get_all_logs() input_raw_data['datetime'] = pd.to_datetime(input_raw_data['datetime'], format='%Y-%m-%dT%H:%M:%S') input_raw_data['food_consumption'] = pd.to_numeric( input_raw_data['food_consumption']) input_raw_data['pulse_pressure'] = input_raw_data[ 'systolic_bp'] - input_raw_data['diastolic_bp'] input_raw_max_date = input_raw_data['datetime'].max() input_raw_min_date = input_raw_data['datetime'].min() # print(input_raw_data) daytime_start = datetime.time(7, 30) daytime_end = datetime.time(19, 30) def date_only(original_date):