def copy_data(overwite, latest, stats): """Copy data from a mounted Garmin USB device to files.""" logger.info("___Copying Data___") copy = Copy(gc_config.device_mount_dir()) settings_dir = GarminDBConfigManager.get_or_create_fit_files_dir() root_logger.info("Copying settings to %s", settings_dir) copy.copy_settings(settings_dir) if Statistics.activities in stats: activities_dir = GarminDBConfigManager.get_or_create_activities_dir() root_logger.info("Copying activities to %s", activities_dir) copy.copy_activities(activities_dir, latest) if Statistics.monitoring in stats: monitoring_dir = GarminDBConfigManager.get_or_create_monitoring_dir( datetime.datetime.now().year) root_logger.info("Copying monitoring to %s", monitoring_dir) copy.copy_monitoring(monitoring_dir, latest) if Statistics.sleep in stats: monitoring_dir = GarminDBConfigManager.get_or_create_monitoring_dir( datetime.datetime.now().year) root_logger.info("Copying sleep to %s", monitoring_dir) copy.copy_sleep(monitoring_dir, latest)
def main(argv): """Import and analyze Microsoft Health data.""" parser = argparse.ArgumentParser() parser.add_argument("-v", "--version", help="print the program's version", action='version', version=format_version(sys.argv[0])) parser.add_argument("-t", "--trace", help="Turn on debug tracing", type=int, default=0) modes_group = parser.add_argument_group('Modes') modes_group.add_argument( "-i", "--input_file", help="Specifiy the CSV file to import into the database") modes_group.add_argument("--delete_db", help="Delete MSHealth db file.", action="store_true", default=False) args = parser.parse_args() root_logger = logging.getLogger() if args.trace: root_logger.setLevel(logging.DEBUG) else: root_logger.setLevel(logging.INFO) db_params = GarminDBConfigManager.get_db_params() if args.delete_db: MSHealthDB.MSHealthDB.delete_db(db_params) sys.exit() mshealth_dir = GarminDBConfigManager.get_or_create_mshealth_dir() metric = GarminDBConfigManager.get_metric() msd = MSHealthData(args.input_file, mshealth_dir, db_params, metric, args.trace) if msd.file_count() > 0: msd.process_files() mshv = MSVaultData(args.input_file, mshealth_dir, db_params, metric, args.trace) if mshv.file_count() > 0: mshv.process_files() analyze = Analyze(db_params) analyze.get_years() analyze.summary()
def setUpClass(cls): db_params = GarminDBConfigManager.get_db_params() cls.plugin_manager = GarminDbPluginManager( GarminDBConfigManager.get_or_create_plugins_dir(), db_params) cls.garmin_mon_db = GarminDB.MonitoringDB(db_params) table_dict = { 'monitoring_info_table': GarminDB.MonitoringInfo, 'monitoring_hr_table': GarminDB.MonitoringHeartRate, 'monitoring_intensity_table': GarminDB.MonitoringIntensity, 'monitoring_climb_table': GarminDB.MonitoringClimb, 'monitoring_table': GarminDB.Monitoring, } super().setUpClass(cls.garmin_mon_db, table_dict)
def __init__(self, debug): """Return an instance of the CheckUp class.""" self.db_params = GarminDBConfigManager.get_db_params() self.debug = debug self.garmin_db = GarminDB.GarminDB(self.db_params) self.measurement_system = GarminDB.Attributes.measurements_type(self.garmin_db) self.unit_strings = Fit.units.unit_strings[self.measurement_system]
def __graph_multiple(cls, time, data_list, stat_name, period, ylabel_list, yrange_list, save): title = f'{stat_name} by {period}' figure = plt.figure(figsize=GarminDBConfigManager.graphs('size')) for index, data in enumerate(data_list): color = Colors.from_integer(index).name axes = figure.add_subplot(111, label=ylabel_list[index], frame_on=(index == 0)) axes.plot(time, data, color=color) axes.set_ylabel(ylabel_list[index], color=color) axes.yaxis.set_label_position( YAxisLabelPostion.from_integer(index).name) if (index % 2) == 0: axes.yaxis.tick_right() else: axes.yaxis.tick_left() axes.tick_params(axis='y', colors=color) if yrange_list is None: axes.set_ylim([min(data), max(data)]) else: axes.set_ylim(yrange_list[index]) axes.grid() axes.set_title(title) axes.set_xlabel('Time') if save: figure.savefig(stat_name + ".png") plt.show()
def setUpClass(cls): db_params = GarminDBConfigManager.get_db_params() db = GarminDB.GarminSummaryDB(db_params) table_dict = { 'summary_table' : GarminDB.Summary, 'months_table' : GarminDB.MonthsSummary, 'weeks_table' : GarminDB.WeeksSummary, 'days_table' : GarminDB.DaysSummary } super().setUpClass(db, table_dict)
def test_parse_uprofile(self): db_params = GarminDBConfigManager.get_db_params(test_db=True) gp = GarminProfile(db_params, self.file_path, debug=2) if gp.file_count() > 0: gp.process() garmindb = GarminDB.GarminDB(db_params) measurement_system = GarminDB.Attributes.measurements_type(garmindb) self.assertEqual( measurement_system, Fit.field_enums.DisplayMeasure.statute, 'DisplayMeasure expected %r found %r' % (Fit.field_enums.DisplayMeasure.statute, measurement_system))
def graph_activity(self, activity, period, days): """Generate a graph for the given activity with points every period spanning days.""" if period is None: period = GarminDBConfigManager.graphs_activity_config( activity, 'period') if days is None: days = GarminDBConfigManager.graphs_activity_config( activity, 'days') db_params = GarminDBConfigManager.get_db_params() sum_db = HealthDB.SummaryDB(db_params, self.debug) end_ts = datetime.datetime.now() start_ts = end_ts - datetime.timedelta(days=days) table = self.__table[period] data = table.get_for_period(sum_db, start_ts, end_ts, table) if period == 'days': time = [entry.day for entry in data] else: time = [entry.first_day for entry in data] graph_func_name = '_graph_' + activity graph_func = getattr(self, graph_func_name, None) graph_func(time, data, period)
def goals(self): """Do a checkup of th euser's goals.""" look_back_days = GarminDBConfigManager.checkup('look_back_days') end_ts = datetime.now() start_ts = end_ts - timedelta(days=look_back_days) results = GarminDB.DailySummary.get_for_period(self.garmin_db, start_ts, end_ts) step_goal_days = 0 step_goal_days_in_week = 0 floors_goal_days = 0 floor_goal_days_in_week = 0 days_in_week = 0 intensity_time = time.min intensity_time_goal = time.min intensity_weeks = 0 intensity_goal_weeks = 0 for result in results: if result.day.weekday() == 0: days_in_week = 0 step_goal_days_in_week = 0 floor_goal_days_in_week = 0 intensity_time = time.min intensity_time_goal = time.min days_in_week += 1 if result.steps_goal_percent >= 100: step_goal_days += 1 step_goal_days_in_week += 1 else: logger.debug('Steps: goal not met on %s', result.day) if result.floors_goal_percent >= 100: floors_goal_days += 1 floor_goal_days_in_week += 1 else: logger.debug('Floors: goal not met on %s', result.day) intensity_time = Fit.conversions.add_time(intensity_time, result.intensity_time) intensity_time_goal = Fit.conversions.add_time(intensity_time_goal, result.intensity_time_goal) if result.day.weekday() == 6: if days_in_week == 7: intensity_weeks += 1 if step_goal_days_in_week < days_in_week: logger.info('Steps: goal not met %d days for week ending in %s', days_in_week - step_goal_days_in_week, result.day) if floor_goal_days_in_week < days_in_week: logger.info('Floors: goal not met %d days for week ending in %s', days_in_week - floor_goal_days_in_week, result.day) if intensity_time >= intensity_time_goal: intensity_goal_weeks += 1 else: logger.info('Intensity mins: goal not met for week ending in %s', result.day) logger.info('Summary:') logger.info('Steps: met goal %d of last %d days', step_goal_days, look_back_days) logger.info('Floors: met goal %d of last %d days', floors_goal_days, look_back_days) logger.info('Intensity mins: met goal %d of last %d weeks', intensity_goal_weeks, intensity_weeks)
def __graph_multiple_single_axes(cls, time, data_list, stat_name, ylabel, save): title = f'{stat_name} Over Time' figure = plt.figure(figsize=GarminDBConfigManager.graphs('size')) for index, data in enumerate(data_list): color = Colors.from_integer(index).name axes = figure.add_subplot(111, frame_on=(index == 0)) axes.plot(time, data, color=color) axes.grid() axes.set_title(title) axes.set_xlabel('Time') axes.set_ylabel(ylabel) if save: figure.savefig(stat_name + ".png") plt.show()
def setUpClass(cls): db_params = GarminDBConfigManager.get_db_params() cls.garmin_db = GarminDB.GarminDB(db_params) table_dict = { 'attributes_table' : GarminDB.Attributes, 'device_table' : GarminDB.Device, 'device_info_table' : GarminDB.DeviceInfo, 'file_table' : GarminDB.File, 'weight_table' : GarminDB.Weight, 'stress_table' : GarminDB.Stress, 'sleep_table' : GarminDB.Sleep, 'sleep_events_table' : GarminDB.SleepEvents, 'resting_heart_rate_table' : GarminDB.RestingHeartRate } super().setUpClass(cls.garmin_db, table_dict)
def __graph_over(cls, date, over_data_dicts, under_data_dict, title, xlabel, ylabel, save_name=None): figure = plt.figure(figsize=GarminDBConfigManager.graphs('size')) # First graph the data that appears under axes = figure.add_subplot(111, frame_on=True) axes.fill_between(under_data_dict['time'], under_data_dict['data'], 0, color=Colors.c.name) axes.set_ylim(under_data_dict['limits']) axes.set_xticks([]) axes.set_yticks([]) # then graph the data that appears on top colors = [Colors.r.name, Colors.b.name] for index, _ in enumerate(over_data_dicts): over_data_dict = over_data_dicts[index] color = colors[index] label = over_data_dict['label'] axes = figure.add_subplot(111, frame_on=False, label=label) axes.plot(over_data_dict['time'], over_data_dict['data'], color=color) axes.set_ylabel(label, color=color) axes.yaxis.set_label_position( YAxisLabelPostion.from_integer(index).name) if (index % 2) == 0: axes.yaxis.tick_right() axes.set_xticks([]) else: axes.yaxis.tick_left() limits = over_data_dicts[index].get('limits') if limits is not None: axes.set_ylim(limits) axes.grid() axes.set_title(title) axes.set_xlabel(xlabel) x_format = mdates.DateFormatter('%H:%M') axes.xaxis.set_major_formatter(x_format) if save_name: figure.savefig(save_name) plt.show()
def test_summary_json_file_import(self): db_params = GarminDBConfigManager.get_db_params(test_db=True) gjsd = GarminSummaryData( db_params, 'test_files/json/monitoring/summary', latest=False, measurement_system=Fit.field_enums.DisplayMeasure.statute, debug=2) if gjsd.file_count() > 0: gjsd.process() table_not_none_cols_dict = { GarminDB.DailySummary: [ GarminDB.DailySummary.rhr, GarminDB.DailySummary.distance, GarminDB.DailySummary.steps, GarminDB.DailySummary.floors_goal ] } self.check_not_none_cols(GarminDB.GarminDB(db_params), table_not_none_cols_dict)
def test_fit_file_import(self): db_params = GarminDBConfigManager.get_db_params(test_db=True) self.profile_function('fit_mon_import', self.fit_file_import, db_params) test_mon_db = GarminDB.GarminDB(db_params) self.check_db_tables_exists(test_mon_db, {'device_table': GarminDB.Device}) self.check_db_tables_exists(test_mon_db, { 'file_table': GarminDB.File, 'device_info_table': GarminDB.DeviceInfo }, self.gfd_file_count) table_not_none_cols_dict = { GarminDB.Monitoring: [ GarminDB.Monitoring.timestamp, GarminDB.Monitoring.activity_type, GarminDB.Monitoring.duration ] } self.check_not_none_cols(GarminDB.MonitoringDB(db_params), table_not_none_cols_dict)
def graph_date(self, date): """Generate a graph for the given date.""" if date is None: date = (datetime.datetime.now() - datetime.timedelta(days=1)).date() db_params = GarminDBConfigManager.get_db_params() mon_db = GarminDB.MonitoringDB(db_params, self.debug) start_ts = datetime.datetime.combine(date, datetime.datetime.min.time()) end_ts = datetime.datetime.combine(date, datetime.datetime.max.time()) hr_data = GarminDB.MonitoringHeartRate.get_for_period( mon_db, start_ts, end_ts, GarminDB.MonitoringHeartRate) data = GarminDB.Monitoring.get_for_period(mon_db, start_ts, end_ts, GarminDB.Monitoring) over_data_dict = [{ 'label': 'Cumulative Steps', 'time': [entry.timestamp for entry in data], 'data': self.__format_steps(data), }, { 'label': 'Heart Rate', 'time': [entry.timestamp for entry in hr_data], 'data': [entry.heart_rate for entry in hr_data], 'limits': (30, 220) }] under_data_dict = { 'time': [entry.timestamp for entry in data], 'data': self.__remove_discontinuities([entry.intensity for entry in data]), 'limits': (0, 10) } # self.__graph_day(date, (hr_time, hr), (mon_time, activity), self.save) save_name = f"{date}_daily.png" if self.save else None self.__graph_over( date, over_data_dict, under_data_dict, f'Daily Summary for {date}: Heart Rate and Steps over Activity', 'Time of Day', 'heart rate', save_name=save_name)
def test_copy_activity(self): activities_dir = GarminDBConfigManager.get_or_create_activities_dir(test_dir=True) logger.info("Copying activities to %s", activities_dir) self.copy.copy_activities(activities_dir)
def copy_settings(self, settings_dir): """Copy settings FIT files from a USB mounted Garmin device to the given directory.""" device_settings_dir = GarminDBConfigManager.device_settings_dir( self.device_mount_dir) self.__copy(device_settings_dir, settings_dir)
import HealthDB import GarminDB from garmin_db_config_manager import GarminDBConfigManager from garmin_connect_config_manager import GarminConnectConfigManager from statistics import Statistics from open_with_basecamp import OpenWithBaseCamp from open_with_google_earth import OpenWithGoogleEarth from garmin_db_plugin import GarminDbPluginManager logging.basicConfig(filename='garmin.log', filemode='w', level=logging.INFO) logger = logging.getLogger(__file__) logger.addHandler(logging.StreamHandler(stream=sys.stdout)) root_logger = logging.getLogger() gc_config = GarminConnectConfigManager() db_params_dict = GarminDBConfigManager.get_db_params() plugin_manager = GarminDbPluginManager( GarminDBConfigManager.get_or_create_plugins_dir(), db_params_dict) stats_to_db_map = { Statistics.monitoring: GarminDB.MonitoringDB, Statistics.steps: GarminDB.MonitoringDB, Statistics.itime: GarminDB.MonitoringDB, Statistics.sleep: GarminDB.GarminDB, Statistics.rhr: GarminDB.GarminDB, Statistics.weight: GarminDB.GarminDB, Statistics.activities: GarminDB.ActivitiesDB } summary_dbs = [GarminDB.GarminSummaryDB, HealthDB.SummaryDB]
def download_data(overwite, latest, stats): """Download selected activity types from Garmin Connect and save the data in files. Overwrite previously downloaded data if indicated.""" logger.info("___Downloading %s Data___", 'Latest' if latest else 'All') download = Download() if not download.login(): logger.error("Failed to login!") sys.exit() if Statistics.activities in stats: if latest: activity_count = gc_config.latest_activity_count() else: activity_count = gc_config.all_activity_count() activities_dir = GarminDBConfigManager.get_or_create_activities_dir() root_logger.info("Fetching %d activities to %s", activity_count, activities_dir) download.get_activity_types(activities_dir, overwite) download.get_activities(activities_dir, activity_count, overwite) if Statistics.monitoring in stats: date, days = __get_date_and_days( GarminDB.MonitoringDB(db_params_dict), latest, GarminDB.MonitoringHeartRate, GarminDB.MonitoringHeartRate.heart_rate, 'monitoring') if days > 0: root_logger.info("Date range to update: %s (%d) to %s", date, days, GarminDBConfigManager.get_monitoring_base_dir()) download.get_daily_summaries( GarminDBConfigManager.get_or_create_monitoring_dir, date, days, overwite) download.get_hydration( GarminDBConfigManager.get_or_create_monitoring_dir, date, days, overwite) download.get_monitoring( GarminDBConfigManager.get_or_create_monitoring_dir, date, days) root_logger.info( "Saved monitoring files for %s (%d) to %s for processing", date, days, GarminDBConfigManager.get_monitoring_base_dir()) if Statistics.sleep in stats: date, days = __get_date_and_days(GarminDB.GarminDB(db_params_dict), latest, GarminDB.Sleep, GarminDB.Sleep.total_sleep, 'sleep') if days > 0: sleep_dir = GarminDBConfigManager.get_or_create_sleep_dir() root_logger.info("Date range to update: %s (%d) to %s", date, days, sleep_dir) download.get_sleep(sleep_dir, date, days, overwite) root_logger.info( "Saved sleep files for %s (%d) to %s for processing", date, days, sleep_dir) if Statistics.weight in stats: date, days = __get_date_and_days(GarminDB.GarminDB(db_params_dict), latest, GarminDB.Weight, GarminDB.Weight.weight, 'weight') if days > 0: weight_dir = GarminDBConfigManager.get_or_create_weight_dir() root_logger.info("Date range to update: %s (%d) to %s", date, days, weight_dir) download.get_weight(weight_dir, date, days, overwite) root_logger.info( "Saved weight files for %s (%d) to %s for processing", date, days, weight_dir) if Statistics.rhr in stats: date, days = __get_date_and_days( GarminDB.GarminDB(db_params_dict), latest, GarminDB.RestingHeartRate, GarminDB.RestingHeartRate.resting_heart_rate, 'rhr') if days > 0: rhr_dir = GarminDBConfigManager.get_or_create_rhr_dir() root_logger.info("Date range to update: %s (%d) to %s", date, days, rhr_dir) download.get_rhr(rhr_dir, date, days, overwite) root_logger.info( "Saved rhr files for %s (%d) to %s for processing", date, days, rhr_dir)
def login(self): """Login to Garmin Connect.""" profile_dir = GarminDBConfigManager.get_or_create_fit_files_dir() username = self.gc_config.get_user() password = self.gc_config.get_password() if not username or not password: print("Missing config: need username and password. Edit GarminConnectConfig.json.") return logger.debug("login: %s %s", username, password) get_headers = { 'Referer' : self.garmin_connect_login_url } params = { 'service' : self.modern_rest_client.url(), 'webhost' : self.garmin_connect_base_url, 'source' : self.garmin_connect_login_url, 'redirectAfterAccountLoginUrl' : self.modern_rest_client.url(), 'redirectAfterAccountCreationUrl' : self.modern_rest_client.url(), 'gauthHost' : self.sso_rest_client.url(), 'locale' : 'en_US', 'id' : 'gauth-widget', 'cssUrl' : self.garmin_connect_css_url, 'privacyStatementUrl' : '//connect.garmin.com/en-US/privacy/', 'clientId' : 'GarminConnect', 'rememberMeShown' : 'true', 'rememberMeChecked' : 'false', 'createAccountShown' : 'true', 'openCreateAccount' : 'false', 'displayNameShown' : 'false', 'consumeServiceTicket' : 'false', 'initialFocus' : 'true', 'embedWidget' : 'false', 'generateExtraServiceTicket' : 'true', 'generateTwoExtraServiceTickets' : 'false', 'generateNoServiceTicket' : 'false', 'globalOptInShown' : 'true', 'globalOptInChecked' : 'false', 'mobile' : 'false', 'connectLegalTerms' : 'true', 'locationPromptShown' : 'true', 'showPassword' : 'true' } try: response = self.sso_rest_client.get(self.garmin_connect_sso_login, get_headers, params) except RestResponseException as e: root_logger.error("Exception during login get: %s", e) RestClient.save_binary_file('login_get.html', e.response) return False found = re.search(r"name=\"_csrf\" value=\"(\w*)", response.text, re.M) if not found: logger.error("_csrf not found: %s", response.status_code) RestClient.save_binary_file('login_get.html', response) return False logger.debug("_csrf found (%s).", found.group(1)) data = { 'username' : username, 'password' : password, 'embed' : 'false', '_csrf' : found.group(1) } post_headers = { 'Referer' : response.url, 'Content-Type' : 'application/x-www-form-urlencoded' } try: response = self.sso_rest_client.post(self.garmin_connect_sso_login, post_headers, params, data) except RestException as e: root_logger.error("Exception during login post: %s", e) return False found = re.search(r"\?ticket=([\w-]*)", response.text, re.M) if not found: logger.error("Login ticket not found (%d).", response.status_code) RestClient.save_binary_file('login_post.html', response) return False params = { 'ticket' : found.group(1) } try: response = self.modern_rest_client.get('', params=params) except RestException: logger.error("Login get homepage failed (%d).", response.status_code) RestClient.save_binary_file('login_home.html', response) return False self.user_prefs = self.__get_json(response.text, 'VIEWER_USERPREFERENCES') if profile_dir: self.modern_rest_client.save_json_to_file(f'{profile_dir}/profile.json', self.user_prefs) self.display_name = self.user_prefs['displayName'] self.social_profile = self.__get_json(response.text, 'VIEWER_SOCIAL_PROFILE') self.full_name = self.social_profile['fullName'] root_logger.info("login: %s (%s)", self.full_name, self.display_name) return True
def import_data(debug, latest, stats): """Import previously downloaded Garmin data into the database.""" logger.info("___Importing %s Data___", 'Latest' if latest else 'All') ignore_dev_fields = gc_config.ignore_dev_fields() # Import the user profile and/or settings FIT file first so that we can get the measurement system and some other things sorted out first. fit_files_dir = GarminDBConfigManager.get_or_create_fit_files_dir() gp = GarminProfile(db_params_dict, fit_files_dir, debug) if gp.file_count() > 0: gp.process() gsfd = GarminSettingsFitData(fit_files_dir, debug) if gsfd.file_count() > 0: gsfd.process_files( FitFileProcessor(db_params_dict, plugin_manager, ignore_dev_fields, debug)) garmindb = GarminDB.GarminDB(db_params_dict) measurement_system = GarminDB.Attributes.measurements_type(garmindb) if Statistics.weight in stats: weight_dir = GarminDBConfigManager.get_or_create_weight_dir() gwd = GarminWeightData(db_params_dict, weight_dir, latest, measurement_system, debug) if gwd.file_count() > 0: gwd.process() if Statistics.monitoring in stats: monitoring_dir = GarminDBConfigManager.get_or_create_monitoring_base_dir( ) gsd = GarminSummaryData(db_params_dict, monitoring_dir, latest, measurement_system, debug) if gsd.file_count() > 0: gsd.process() ghd = GarminHydrationData(db_params_dict, monitoring_dir, latest, measurement_system, debug) if ghd.file_count() > 0: ghd.process() gfd = GarminMonitoringFitData(monitoring_dir, latest, measurement_system, debug) if gfd.file_count() > 0: gfd.process_files( MonitoringFitFileProcessor(db_params_dict, plugin_manager, ignore_dev_fields, debug)) if Statistics.sleep in stats: sleep_dir = GarminDBConfigManager.get_or_create_sleep_dir() gsd = GarminSleepData(db_params_dict, sleep_dir, latest, debug) if gsd.file_count() > 0: gsd.process() if Statistics.rhr in stats: rhr_dir = GarminDBConfigManager.get_or_create_rhr_dir() grhrd = GarminRhrData(db_params_dict, rhr_dir, latest, debug) if grhrd.file_count() > 0: grhrd.process() if Statistics.activities in stats: activities_dir = GarminDBConfigManager.get_or_create_activities_dir() # Tcx fields are less precise than the JSON files, so load Tcx first and overwrite with better JSON values. gtd = GarminTcxData(activities_dir, latest, measurement_system, debug) if gtd.file_count() > 0: gtd.process_files(db_params_dict) gjsd = GarminJsonSummaryData(db_params_dict, activities_dir, latest, measurement_system, debug) if gjsd.file_count() > 0: gjsd.process() gdjd = GarminJsonDetailsData(db_params_dict, activities_dir, latest, measurement_system, debug) if gdjd.file_count() > 0: gdjd.process() gfd = GarminActivitiesFitData(activities_dir, latest, measurement_system, debug) if gfd.file_count() > 0: gfd.process_files( ActivityFitFileProcessor(db_params_dict, plugin_manager, ignore_dev_fields, debug))
def setUpClass(cls): cls.db_params = GarminDBConfigManager.get_db_params(test_db=True) cls.garmin_db = GarminDB.GarminDB(cls.db_params)
def copy_sleep(self, monitoring_dir, latest=False): """Copy daily sleep data FIT files from a USB mounted Garmin device to the given directory.""" device_sleep_dir = GarminDBConfigManager.device_sleep_dir( self.device_mount_dir) self.__copy(device_sleep_dir, monitoring_dir, latest)
def test_copy_settings(self): settings_dir = GarminDBConfigManager.get_or_create_fit_files_dir(test_dir=True) root_logger.info("Copying settings to %s", settings_dir) self.copy.copy_settings(settings_dir)
def test_copy_sleep(self): monitoring_dir = GarminDBConfigManager.get_or_create_monitoring_dir(datetime.datetime.now().year, test_dir=True) root_logger.info("Copying sleep to %s", monitoring_dir) self.copy.copy_sleep(monitoring_dir)
def copy_activities(self, activities_dir, latest=False): """Copy activites data FIT files from a USB mounted Garmin device to the given directory.""" device_activities_dir = GarminDBConfigManager.device_activities_dir( self.device_mount_dir) self.__copy(device_activities_dir, activities_dir, latest)