forked from tcgoetz/GarminDB
-
Notifications
You must be signed in to change notification settings - Fork 0
/
checkup.py
142 lines (124 loc) · 7.03 KB
/
checkup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/env python3
"""Class running a checkup against the DB data."""
__author__ = "Tom Goetz"
__copyright__ = "Copyright Tom Goetz"
__license__ = "GPL"
import sys
import logging
import argparse
from datetime import datetime, time, timedelta
import Fit
import GarminDB
import garmin_db_config_manager as GarminDBConfigManager
from version import format_version
logging.basicConfig(filename='graphs.log', filemode='w', level=logging.INFO)
logger = logging.getLogger(__file__)
logger.addHandler(logging.StreamHandler(stream=sys.stdout))
root_logger = logging.getLogger()
class CheckUp(object):
"""Class running a checkup against the DB data."""
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 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 __activity_string(self, activity_db, activity):
if activity.is_steps_activity():
steps_activity = GarminDB.StepsActivities.get(activity_db, activity.activity_id)
return ('%s: "%s" %.2f %s in %s pace: %s %s speed: %.2f %s' %
(activity.start_time, activity.name, activity.distance, self.unit_strings[Fit.units.UnitTypes.distance_long], activity.elapsed_time,
steps_activity.avg_pace, self.unit_strings[Fit.units.UnitTypes.pace], activity.avg_speed,
self.unit_strings[Fit.units.UnitTypes.speed]))
return '%s: "%s" %s in %s (%s)' % (activity.start_time, activity.name, activity.distance, activity.elapsed_time, activity.avg_speed)
def activity_course(self, course_id):
"""Run a checkup on all activities matching the course_id."""
activity_db = GarminDB.ActivitiesDB(self.db_params, self.debug)
activities = GarminDB.Activities.get_by_course_id(activity_db, course_id)
activities_count = len(activities)
fastest_activity = GarminDB.Activities.get_fastest_by_course_id(activity_db, course_id)
slowest_activity = GarminDB.Activities.get_slowest_by_course_id(activity_db, course_id)
logger.info('Matching Activities: %d', activities_count)
logger.info(' first: %s', self.__activity_string(activity_db, activities[0]))
logger.info(' lastest: %s', self.__activity_string(activity_db, activities[-1]))
logger.info(' fastest: %s', self.__activity_string(activity_db, fastest_activity))
logger.info(' slowest: %s', self.__activity_string(activity_db, slowest_activity))
def battery_status(self):
"""Check for devices with low battery status."""
devices = GarminDB.Device.get_all(self.garmin_db)
for device in devices:
battery_level = GarminDB.DeviceInfo.get_col_latest_where(self.garmin_db, GarminDB.DeviceInfo.battery_status,
[GarminDB.DeviceInfo.serial_number == device.serial_number,
GarminDB.DeviceInfo.battery_status != Fit.field_enums.BatteryStatus.invalid])
if battery_level is Fit.field_enums.BatteryStatus.low:
logger.info("Device %s %s (%s) has a low battery", device.manufacturer, device.product, device.serial_number)
def main(argv):
"""Run a data checkup of the user's choice."""
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)
checks_group = parser.add_argument_group('Checks')
checks_group.add_argument("-b", "--battery", help="Check for low battery levels.", action="store_true", default=False)
checks_group.add_argument("-c", "--course", help="Show statistics from all workouts for a single course.", type=int, default=None)
checks_group.add_argument("-g", "--goals", help="Run a checkup on the user\'s goals.", action="store_true", default=False)
args = parser.parse_args()
checkup = CheckUp(args.trace)
if args.battery:
checkup.battery_status()
if args.course:
checkup.activity_course(args.course)
if args.goals:
checkup.goals()
if __name__ == "__main__":
main(sys.argv[1:])