From a635795acdd30a5ef5b7cf7ba01e08cd31c43109 Mon Sep 17 00:00:00 2001 From: Chris Schlaeger Date: Sat, 16 Apr 2016 22:20:59 +0200 Subject: New: Monthly report added --- lib/postrunner/FitFileStore.rb | 23 +++++++++++++++++++ lib/postrunner/Main.rb | 21 ++++++++++++++--- lib/postrunner/SleepStatistics.rb | 48 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 3 deletions(-) diff --git a/lib/postrunner/FitFileStore.rb b/lib/postrunner/FitFileStore.rb index 75bd104..07a1335 100644 --- a/lib/postrunner/FitFileStore.rb +++ b/lib/postrunner/FitFileStore.rb @@ -341,6 +341,29 @@ module PostRunner puts SleepStatistics.new(monitoring_files).daily(day) end + def monthly_report(day) + monitorings = [] + # 'day' specifies the current month. It must be in the form of + # YYYY-MM-01. But we don't know what timezone the watch was set to for a + # given date. The files are always named after the moment of finishing + # the recording expressed as GMT time. Each file contains information + # about the time zone for the specific file. Recording is always flipped + # to a new file at midnight GMT but there are usually multiple files per + # GMT day. + day_as_time = Time.parse(day).gmtime + @store['devices'].each do |id, device| + # We are looking for all files that potentially overlap with our + # localtime day. + monitorings += device.monitorings(day_as_time - 36 * 60 * 60, + day_as_time + 33 * 24 * 60 * 60) + end + monitoring_files = monitorings.map do |m| + read_fit_file(File.join(fit_file_dir(m.fit_file_name, m.device.long_uid, + 'monitor'), m.fit_file_name)) + end + puts SleepStatistics.new(monitoring_files).monthly(day) + end + private def read_fit_file(fit_file_name) diff --git a/lib/postrunner/Main.rb b/lib/postrunner/Main.rb index 652dd49..6754582 100644 --- a/lib/postrunner/Main.rb +++ b/lib/postrunner/Main.rb @@ -193,6 +193,10 @@ delete list List all FIT files stored in the data base. +monthly [ ] + Print a table with various statistics for each day of the specified + month. + records List all personal records. @@ -302,9 +306,11 @@ EOT when 'daily' # Get the date of requested day in 'YY-MM-DD' format. If no argument # is given, use the current date. - day = (args.empty? ? Time.now : Time.parse(args[0])). - localtime.strftime('%Y-%m-%d') - @ffs.daily_report(day) + @ffs.daily_report(day_in_localtime(args, '%Y-%m-%d')) + when 'monthly' + # Get the date of requested day in 'YY-MM-DD' format. If no argument + # is given, use the current date. + @ffs.monthly_report(day_in_localtime(args, '%Y-%m-01')) when 'delete' process_activities(args, :delete) when 'dump' @@ -548,6 +554,15 @@ EOT end end + def day_in_localtime(args, format) + begin + (args.empty? ? Time.now : Time.parse(args[0])). + localtime.strftime(format) + rescue ArgumentError + Log.abort("#{args[0]} is not a valid date. Use YYYY-MM-DD format.") + end + end + def handle_version_update if @db['config']['version'] != VERSION Log.warn "PostRunner version upgrade detected." diff --git a/lib/postrunner/SleepStatistics.rb b/lib/postrunner/SleepStatistics.rb index 514733b..0825ab9 100644 --- a/lib/postrunner/SleepStatistics.rb +++ b/lib/postrunner/SleepStatistics.rb @@ -63,6 +63,54 @@ module PostRunner "Sleep Statistics for #{day}\n\n#{ti}\n#{tt}" end + def monthly(day) + day_as_time = Time.parse(day) + year = day_as_time.year + month = day_as_time.month + last_day_of_month = Date.new(year, month, -1).day + + t = FlexiTable.new + left = { :halign => :left } + right = { :halign => :right } + t.set_column_attributes([ left, right, right, right ]) + t.head + t.row([ 'Date', 'Total Sleep', 'Deep Sleep', 'Light Sleep' ]) + t.body + totals = Hash.new(0) + counted_days = 0 + + 1.upto(last_day_of_month).each do |dom| + day_str = Time.new(year, month, dom).strftime('%Y-%m-%d') + t.cell(day_str) + + analyzer = DailySleepAnalyzer.new(@monitoring_files, day_str) + + if analyzer.sleep_intervals.empty? + t.cell('-') + t.cell('-') + t.cell('-') + else + totals[:total_sleep] += analyzer.total_sleep + totals[:deep_sleep] += analyzer.deep_sleep + totals[:light_sleep] += analyzer.light_sleep + counted_days += 1 + + t.cell(secsToHM(analyzer.total_sleep)) + t.cell(secsToHM(analyzer.deep_sleep)) + t.cell(secsToHM(analyzer.light_sleep)) + end + t.new_row + end + t.foot + t.cell('Averages') + t.cell(secsToHM(totals[:total_sleep] / counted_days)) + t.cell(secsToHM(totals[:deep_sleep] / counted_days)) + t.cell(secsToHM(totals[:light_sleep] / counted_days)) + t.new_row + + "Sleep Statistics for #{day_as_time.strftime('%B')} #{year}\n\n#{t}" + end + end end -- cgit v1.2.3