summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Schlaeger <chris@linux.com>2015-10-31 21:34:24 +0100
committerChris Schlaeger <chris@linux.com>2015-10-31 21:34:24 +0100
commitfde5c1c0bb7187f6a39a86f0a394d2f196f3e670 (patch)
tree36ee6dbd975f56544db5de8836a4276a8e8a650c
parentaceaa003792f4fe1c2e9c7590d106be875c875de (diff)
downloadpostrunner-fde5c1c0bb7187f6a39a86f0a394d2f196f3e670.zip
New: Show event log in activity view.
-rw-r--r--lib/postrunner/Activity.rb21
-rw-r--r--lib/postrunner/ActivityView.rb3
-rw-r--r--lib/postrunner/DataSources.rb15
-rw-r--r--lib/postrunner/EventList.rb149
-rw-r--r--lib/postrunner/Main.rb7
-rw-r--r--spec/PostRunner_spec.rb8
6 files changed, 189 insertions, 14 deletions
diff --git a/lib/postrunner/Activity.rb b/lib/postrunner/Activity.rb
index 13f2cd9..07dd999 100644
--- a/lib/postrunner/Activity.rb
+++ b/lib/postrunner/Activity.rb
@@ -14,6 +14,7 @@ require 'fit4ruby'
require 'postrunner/ActivitySummary'
require 'postrunner/DataSources'
+require 'postrunner/EventList'
require 'postrunner/ActivityView'
require 'postrunner/Schema'
require 'postrunner/QueryResult'
@@ -196,6 +197,11 @@ module PostRunner
QueryResult.new(value, schema)
end
+ def events
+ @fit_activity = load_fit_file unless @fit_activity
+ puts EventList.new(self, @db.cfg[:unit_system]).to_s
+ end
+
def show
generate_html_view #unless File.exists?(@html_file)
@@ -374,6 +380,21 @@ module PostRunner
ActivitySubTypes[@sub_sport] || 'Undefined'
end
+ def distance(timestamp, unit_system)
+ @fit_activity = load_fit_file unless @fit_activity
+
+ @fit_activity.records.each do |record|
+ if record.timestamp >= timestamp
+ unit = { :metric => 'km', :statute => 'mi'}[unit_system]
+ value = record.get_as('distance', unit)
+ return '-' unless value
+ return "#{'%.2f %s' % [value, unit]}"
+ end
+ end
+
+ '-'
+ end
+
private
def load_fit_file(filter = nil)
diff --git a/lib/postrunner/ActivityView.rb b/lib/postrunner/ActivityView.rb
index a1bbc3b..9474089 100644
--- a/lib/postrunner/ActivityView.rb
+++ b/lib/postrunner/ActivityView.rb
@@ -14,7 +14,9 @@ require 'fit4ruby'
require 'postrunner/View'
require 'postrunner/ActivitySummary'
+require 'postrunner/EventList'
require 'postrunner/DeviceList'
+require 'postrunner/DataSources'
require 'postrunner/UserProfileView'
require 'postrunner/TrackView'
require 'postrunner/ChartView'
@@ -73,6 +75,7 @@ module PostRunner
}
doc.div({ :class => 'right_col' }) {
ChartView.new(@activity, @unit_system).to_html(doc)
+ EventList.new(@activity, @unit_system).to_html(doc)
}
}
doc.div({ :class => 'two_col' }) {
diff --git a/lib/postrunner/DataSources.rb b/lib/postrunner/DataSources.rb
index 01ed9a8..c90a405 100644
--- a/lib/postrunner/DataSources.rb
+++ b/lib/postrunner/DataSources.rb
@@ -55,7 +55,7 @@ module PostRunner
start_time = session.start_time
@fit_activity.data_sources.each do |source|
t.cell(secsToHMS(source.timestamp - start_time))
- t.cell(distance(source.timestamp))
+ t.cell(@activity.distance(source.timestamp, @unit_system))
t.cell(source.mode)
t.cell(device_name(source.distance))
t.cell(device_name(source.speed))
@@ -81,19 +81,6 @@ module PostRunner
''
end
- def distance(timestamp)
- @fit_activity.records.each do |record|
- if record.timestamp >= timestamp
- unit = { :metric => 'km', :statute => 'mi'}[@unit_system]
- value = record.get_as('distance', unit)
- return '-' unless value
- return "#{'%.2f %s' % [value, unit]}"
- end
- end
-
- '-'
- end
-
end
end
diff --git a/lib/postrunner/EventList.rb b/lib/postrunner/EventList.rb
new file mode 100644
index 0000000..d248001
--- /dev/null
+++ b/lib/postrunner/EventList.rb
@@ -0,0 +1,149 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+#
+# = EventList.rb -- PostRunner - Manage the data from your Garmin sport devices.
+#
+# Copyright (c) 2015 by Chris Schlaeger <cs@taskjuggler.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+
+require 'fit4ruby'
+
+require 'postrunner/FlexiTable'
+require 'postrunner/ViewFrame'
+require 'postrunner/DeviceList'
+
+module PostRunner
+
+ # The EventList objects can generate a table that lists all the recorded
+ # FIT file events in chronological order.
+ class EventList
+
+ include Fit4Ruby::Converters
+
+ # Create a DataSources object.
+ # @param activity [Activity] The activity to analyze.
+ # @param unit_system [Symbol] The unit system to use (:metric or
+ # :imperial )
+ def initialize(activity, unit_system)
+ @activity = activity
+ @fit_activity = activity.fit_activity
+ @unit_system = unit_system
+ end
+
+ # Return the list as ASCII table
+ def to_s
+ list.to_s
+ end
+
+ # Add the list as HTML table to the specified doc.
+ # @param doc [HTMLBuilder] HTML document
+ def to_html(doc)
+ ViewFrame.new("Events", 600, list).to_html(doc)
+ end
+
+ private
+
+ def list
+ session = @fit_activity.sessions[0]
+
+ t = FlexiTable.new
+ t.enable_frame(false)
+ t.body
+ t.row([ 'Time', 'Distance', 'Description', 'Value' ])
+ t.set_column_attributes([
+ { :halign => :right },
+ { :halign => :right },
+ { :halign => :left },
+ { :halign => :right }
+ ])
+ start_time = session.start_time
+ @fit_activity.events.each do |event|
+ t.cell(secsToHMS(event.timestamp - start_time))
+ t.cell(@activity.distance(event.timestamp, @unit_system))
+ event_name_and_value(t, event)
+ t.new_row
+ end
+
+ t
+ end
+
+ def event_name_and_value(table, event)
+ case event.event
+ when 'timer'
+ name = "Timer (#{event.event_type.gsub(/_/, ' ')})"
+ value = event.timer_trigger
+ when 'course_point'
+ name = 'Course Point'
+ value = event.message_index
+ when 'battery'
+ name = 'Battery Level'
+ value = event.battery_level
+ when 'hr_high_alert'
+ name = 'HR high alert'
+ value = event.hr_high_alert
+ when 'hr_low_alert'
+ name = 'HR low alert'
+ value = event.hr_low_alert
+ when 'speed_high_alert'
+ name = 'Speed high alert'
+ value = event.speed_high_alert
+ when 'speed_low_alert'
+ name = 'Speed low alert'
+ value = event.speed_low_alert
+ when 'cad_high_alert'
+ name = 'Cadence high alert'
+ value = event.cad_high_alert
+ when 'cad_low_alert'
+ name = 'Cadence low alert'
+ value = event.cad_low_alert
+ when 'power_high_alert'
+ name = 'Power high alert'
+ value = event.power_high_alert
+ when 'power_low_alert'
+ name = 'Power low alert'
+ value = event.power_low_alert
+ when 'time_duration_alert'
+ name 'Time duration alert'
+ value = event.time_duration_alert
+ when 'calorie_duration_alert'
+ name = 'Calorie duration alert'
+ value = event.calorie_duration_alert
+ when 'fitness_equipment'
+ name = 'Fitness equipment state'
+ value = event.fitness_equipment_state
+ when 'rider_position'
+ name 'Rider position changed'
+ value = event.rider_position
+ when 'comm_timeout'
+ name 'Communication timeout'
+ value = event.comm_timeout
+ when 'recovery_hr'
+ name = 'Recovery heart rate'
+ value = "#{event.recovery_hr} bpm"
+ when 'recovery_time'
+ name = 'Recovery time'
+ value = "#{secsToDHMS(event.recovery_time * 60)}"
+ when 'recovery_info'
+ name = 'Recovery info'
+ mins = event.recovery_info
+ value = "#{secsToDHMS(mins * 60)} (#{mins < 24 * 60 ? 'Good' : 'Poor'})"
+ when 'vo2max'
+ name = 'VO2Max'
+ value = event.vo2max
+ else
+ name = event.event
+ value = event.data
+ end
+
+ table.cell(name)
+ table.cell(value)
+ end
+
+ end
+
+end
+
diff --git a/lib/postrunner/Main.rb b/lib/postrunner/Main.rb
index 7dbb6be..c388910 100644
--- a/lib/postrunner/Main.rb
+++ b/lib/postrunner/Main.rb
@@ -119,6 +119,9 @@ check [ <fit file> | <ref> ... ]
dump <fit file> | <ref>
Dump the content of the FIT file.
+events [ <ref> ]
+ List all the events of the specified activies.
+
import [ <fit file> | <directory> ]
Import the provided FIT file(s) into the postrunner database. If no
file or directory is provided, the directory that was used for the
@@ -205,6 +208,8 @@ EOT
when 'dump'
@filter = Fit4Ruby::FitFilter.new unless @filter
process_files_or_activities(args, :dump)
+ when 'events'
+ process_files_or_activities(args, :events)
when 'import'
if args.empty?
# If we have no file or directory for the import command, we get the
@@ -351,6 +356,8 @@ EOT
@activities.delete(activity)
when :dump
activity.dump(@filter)
+ when :events
+ activity.events
when :rename
@activities.rename(activity, @name)
when :set
diff --git a/spec/PostRunner_spec.rb b/spec/PostRunner_spec.rb
index 59c5d0e..f4dd33b 100644
--- a/spec/PostRunner_spec.rb
+++ b/spec/PostRunner_spec.rb
@@ -131,6 +131,14 @@ describe PostRunner::Main do
list.index('Cycling').should be_a(Fixnum)
end
+ it 'should list the events of an activity' do
+ postrunner(%w( events :1 ))
+ end
+
+ it 'should list the data sources of an activity' do
+ postrunner(%w( sources :1 ))
+ end
+
it 'should fail when setting bad activity type' do
lambda { postrunner(%w( set type foobar :1)) }.should raise_error Fit4Ruby::Error
end