teich-hrmparser 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,6 @@
1
+ 0.6.0 - August 15, 2009
2
+ Add support for Timex
3
+
1
4
  0.5.0 - July 25, 2009
2
5
  Handle stop time in GPX
3
6
 
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :patch: 0
3
3
  :major: 0
4
- :minor: 5
4
+ :minor: 6
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{hrmparser}
5
- s.version = "0.5.0"
5
+ s.version = "0.6.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Oren Teich"]
9
- s.date = %q{2009-07-25}
9
+ s.date = %q{2009-08-15}
10
10
  s.description = %q{Parses Polar and Garmin HRM files.}
11
11
  s.email = %q{oren@teich.net}
12
12
  s.extra_rdoc_files = [
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
26
26
  "lib/hrmparser/importer/gpx.rb",
27
27
  "lib/hrmparser/importer/polar.rb",
28
28
  "lib/hrmparser/importer/suunto.rb",
29
+ "lib/hrmparser/importer/timex.rb",
29
30
  "lib/hrmparser/trackpoint.rb",
30
31
  "lib/hrmparser/workout.rb",
31
32
  "spec/arraymath_spec.rb",
@@ -2,6 +2,7 @@ require 'importer/garmin'
2
2
  require 'importer/polar'
3
3
  require 'importer/suunto'
4
4
  require 'importer/gpx'
5
+ require 'importer/timex'
5
6
 
6
7
  module Importer
7
8
  def Importer.file_type(name)
@@ -14,6 +15,15 @@ module Importer
14
15
  return "SUUNTO"
15
16
  when /\.gpx$/i
16
17
  return "GPX"
18
+ when /\.csv$/i
19
+ f = File.new(name)
20
+ first_line = f.readline
21
+ f.close
22
+ if first_line.chomp == "[Timex Trainer Data File]"
23
+ return "TIMEX"
24
+ else
25
+ return "UNKNOWN CSV"
26
+ end
17
27
  end
18
28
  end
19
29
 
@@ -0,0 +1,118 @@
1
+ module Importer
2
+ class Timex
3
+ attr_reader :time_zone
4
+
5
+ def initialize(opts = {:data => nil, :time_zone => "UTC"})
6
+ @data = opts[:data]
7
+ @time_zone = opts[:time_zone]
8
+ end
9
+
10
+ def restore
11
+ workout = HRMParser::Workout.new(:duration => 0)
12
+
13
+ params = parse_params("session data")
14
+
15
+ dt = DateTime.strptime(params["Sessiondate"], "%d/%m/%Y %H:%M:%S")
16
+ time_for_parse = dt.strftime("%b %d %H:%M:%S @time_zone %Y")
17
+
18
+ workout.time = Time.parse(time_for_parse)
19
+ workout.duration = params["duration"].to_f
20
+
21
+ workout.trackpoints = get_trackpoints(workout.time)
22
+
23
+ workout.calc_average_hr!
24
+ workout.calc_altitude_gain!
25
+ workout.calc_average_speed!
26
+ workout.set_distance_from_trackpoints!
27
+
28
+ return workout
29
+
30
+ end
31
+
32
+
33
+ private
34
+
35
+ def parse_params(string)
36
+ hash = {}
37
+ param_block = find_block(string)
38
+ param_block.each do |param|
39
+ # /=/ in case that doesn't work
40
+ key, value = param.split("=", 2)
41
+ key = key.strip unless key.nil?
42
+ value = value.strip unless value.nil?
43
+ hash[key] = value unless key.nil?
44
+ end
45
+ return hash
46
+ end
47
+
48
+ def find_block(header)
49
+ found = false
50
+ block = []
51
+ @data.each do |line|
52
+ line.chomp!
53
+ found = false if line =~ /^\[.*\]$/
54
+ block << line if found
55
+ found = true if line =~ /\[#{header}\]/
56
+ end
57
+ return block
58
+ end
59
+
60
+ def parse_data(string)
61
+ data = []
62
+ block_text = find_block(string)
63
+ block_text.each do |block_line|
64
+ data << block_line.chomp
65
+ end
66
+ return data
67
+ end
68
+
69
+ def get_trackpoints(base_time)
70
+ trackpoints = []
71
+ have_gps = false
72
+ logs = parse_data("recorded")
73
+ fields = logs[0].split(/,/)
74
+ have_gps = true if fields.size > 5
75
+
76
+ for line in logs do
77
+ if have_gps
78
+ if line =~ /^".*"/ then line.gsub!(/"(.*?)"/,'\1') end # remove double-quotes at string beginning & end
79
+ seconds, hr, speed_imperial, distance_imperial, data_flag, lng, lat, altitude, acqs, trueh, magh = line.split(/,/)
80
+ else
81
+ seconds, hr, speed_imperial, distance_imperial, data_flag = line.split(/,/)
82
+ end
83
+
84
+
85
+ ## Convert speed and distance to metric - meters specifically
86
+ distance = distance_imperial.to_f * 1609.344
87
+ speed = speed_imperial.to_f * 0.44704
88
+
89
+
90
+ trackpoint = HRMParser::TrackPoint.new
91
+
92
+ points_f = %w[speed distance lat lng altitude]
93
+ points_i = %w[hr]
94
+
95
+
96
+ points_f.each do |p|
97
+ value = (eval p).to_f
98
+ value = nil if value == 0.0
99
+ trackpoint.send("#{p}=".to_sym, value)
100
+ end
101
+
102
+ points_i.each do |p|
103
+ value = (eval p).to_i
104
+ value = nil if value == 0
105
+ trackpoint.send("#{p}=".to_sym, value)
106
+ end
107
+
108
+ trackpoint.time = base_time + seconds.to_i
109
+
110
+ trackpoints << trackpoint
111
+ end
112
+ return trackpoints
113
+ end
114
+
115
+
116
+
117
+ end
118
+ end
@@ -50,197 +50,249 @@ module HRMParser
50
50
  type = Importer.file_type("spec/samples/polarRS400.hrm")
51
51
  type.should == "POLAR_HRM"
52
52
  end
53
- end
54
-
55
- context "Parse a GPS file" do
56
- # it "finds the duration, time" do
57
- # filename = "spec/samples/gps-with-suunto.gpx"
58
- # data = File.read(filename)
59
- # importer = Importer::GPX.new(:data => data)
60
- # workout = importer.restore
61
- # workout.time.should == Time.parse("Thu May 07 21:32:31 UTC 2009")
62
- #
63
- # # Duration is actualy less, but we don't account for stopped time right now
64
- # workout.duration.should be_close(6284,1)
65
- # end
66
- # it "calculates the distance and speed" do
67
- # filename = "spec/samples/gps-with-suunto.gpx"
68
- # data = File.read(filename)
69
- # importer = Importer::GPX.new(:data => data)
70
- # workout = importer.restore
71
- # workout.average_speed.should be_close(6.7, 0.2)
72
- # workout.distance.should be_close(26427, 1)
73
- # end
74
- # it "handles files with drops" do
75
- # filename = "spec/samples/gps-flat-run.gpx"
76
- # data = File.read(filename)
77
- # importer = Importer::GPX.new(:data => data)
78
- # workout = importer.restore
79
- # workout.average_speed.should be_close(2.9, 0.2)
80
- # workout.distance.should be_close(11453, 1)
81
- # workout.altitude_gain.should be_close(325, 10)
82
- # end
83
- it "deals with stopping and calculates duration correctly" do
84
- filename = "spec/samples/gps-with-stops.gpx"
85
- data = File.read(filename)
86
- importer = Importer::GPX.new(:data => data)
87
- workout = importer.restore
88
- workout.average_speed.should be_close(6.5, 0.2)
89
- workout.distance.should be_close(5230, 1)
90
- workout.altitude_gain.should be_close(11, 10)
91
- workout.duration.should be_close(1149, 1)
92
- end
93
-
94
- it "deals with stopping and calculates duration correctly" do
95
- filename = "spec/samples/gps-with-stops-2.gpx"
96
- data = File.read(filename)
97
- importer = Importer::GPX.new(:data => data)
98
- workout = importer.restore
99
- workout.average_speed.should be_close(5.7, 0.2)
100
- workout.distance.should be_close(3099, 1)
101
- workout.altitude_gain.should be_close(24, 10)
102
- workout.duration.should be_close(564, 1)
53
+ it "identifies timex" do
54
+ type = Importer.file_type("spec/samples/timex/HR.csv")
55
+ type.should == "TIMEX"
103
56
  end
104
-
105
57
  end
106
58
 
107
- # context "Parse garmin file" do
108
- # it "finds workout start time on a short workout" do
109
- # filename = "spec/samples/indoor-garmin-405.TCX"
110
- # data = File.read(filename)
111
- # importer = Importer::Garmin.new(:data => data)
112
- # workout = importer.restore
113
- # workout.time.should == Time.parse("Fri Aug 22 01:04:55 UTC 2008")
114
- # end
115
- # it "finds the duration on a short workout" do
116
- # filename = "spec/samples/indoor-garmin-405.TCX"
59
+ # context "Parse a GPS file" do
60
+ # it "finds the duration, time" do
61
+ # filename = "spec/samples/gps-with-suunto.gpx"
117
62
  # data = File.read(filename)
118
- # importer = Importer::Garmin.new(:data => data)
63
+ # importer = Importer::GPX.new(:data => data)
119
64
  # workout = importer.restore
120
- # workout.duration.should be_close(755, 1)
65
+ # workout.time.should == Time.parse("Thu May 07 21:32:31 UTC 2009")
66
+ #
67
+ # # Duration is actualy less, but we don't account for stopped time right now
68
+ # workout.duration.should be_close(6284,1)
121
69
  # end
122
- # it "indoor workout has no trackpoints" do
123
- # filename = "spec/samples/indoor-garmin-405.TCX"
70
+ # it "calculates the distance and speed" do
71
+ # filename = "spec/samples/gps-with-suunto.gpx"
124
72
  # data = File.read(filename)
125
- # importer = Importer::Garmin.new(:data => data)
73
+ # importer = Importer::GPX.new(:data => data)
126
74
  # workout = importer.restore
127
- # workout.distance.should be_nil
128
- # workout.average_hr.should be_nil
129
- # workout.average_speed.should be_nil
130
- # workout.altitude_gain.should be_nil
131
- # workout.trackpoints.should == {}
75
+ # workout.average_speed.should be_close(6.7, 0.2)
76
+ # workout.distance.should be_close(26427, 1)
132
77
  # end
133
- # it "parses files with only LAT and LNG" do
134
- # filename = "spec/samples/garmin-only-lat-lng.tcx"
78
+ # it "handles files with drops" do
79
+ # filename = "spec/samples/gps-flat-run.gpx"
135
80
  # data = File.read(filename)
136
- # importer = Importer::Garmin.new(:data => data)
81
+ # importer = Importer::GPX.new(:data => data)
137
82
  # workout = importer.restore
138
- # workout.distance.should be_close(172052, 1)
139
- # workout.average_hr.should be_nil
140
- # workout.average_speed.should be_close(5.93, 0.1)
141
- # workout.altitude_gain.should be_close(372, 10)
83
+ # workout.average_speed.should be_close(2.9, 0.2)
84
+ # workout.distance.should be_close(11453, 1)
85
+ # workout.altitude_gain.should be_close(325, 10)
142
86
  # end
143
- #
144
- # # Parsing the full XML is just slow. Commenting out for now.
145
- # it "gets workout level settings for outdoor workout" do
146
- # filename = "spec/samples/outdoor-garmin-405.TCX"
87
+ # it "deals with stopping and calculates duration correctly" do
88
+ # filename = "spec/samples/gps-with-stops.gpx"
147
89
  # data = File.read(filename)
148
- # importer = Importer::Garmin.new(:data => data)
90
+ # importer = Importer::GPX.new(:data => data)
149
91
  # workout = importer.restore
150
- # workout.distance.should be_close(11740, 5)
151
- # workout.average_hr.should be_close(149.7, 0.5)
152
- # workout.average_speed.should be_close(1.5, 0.2)
153
- # workout.altitude_gain.should be_close(580, 25)
92
+ # workout.average_speed.should be_close(6.5, 0.2)
93
+ # workout.distance.should be_close(5230, 1)
94
+ # workout.altitude_gain.should be_close(11, 10)
95
+ # workout.duration.should be_close(1149, 1)
154
96
  # end
155
- #
156
- # it "gets workout level settings for weird distance workout" do
157
- # filename = "spec/samples/garmin-405-dies-distance.TCX"
97
+ #
98
+ # it "deals with stopping and calculates duration correctly" do
99
+ # filename = "spec/samples/gps-with-stops-2.gpx"
158
100
  # data = File.read(filename)
159
- # importer = Importer::Garmin.new(:data => data)
101
+ # importer = Importer::GPX.new(:data => data)
160
102
  # workout = importer.restore
161
- # workout.distance.should be_close(9426, 1)
162
- # workout.average_hr.should == nil
163
- # workout.average_speed.should be_close(6.7, 0.2)
164
- # workout.altitude_gain.should be_close(40, 10)
103
+ # workout.average_speed.should be_close(5.7, 0.2)
104
+ # workout.distance.should be_close(3099, 1)
105
+ # workout.altitude_gain.should be_close(24, 10)
106
+ # workout.duration.should be_close(564, 1)
165
107
  # end
166
- #
167
- # it "doesn't have any 0 in latitude" do
168
- # filename = "spec/samples/garmin-405-with-0-0.TCX"
169
- # data = File.read(filename)
170
- # importer = Importer::Garmin.new(:data => data)
171
- # workout = importer.restore
172
- # workout.trackpoints.map {|tp| tp.lat.should_not == 0.0}
173
- # workout.trackpoints.map {|tp| tp.lat.should_not == "undefined"}
174
- # end
175
- #
176
- # it "handles files with INSANE duration" do
177
- # filename = "spec/samples/insane-duration.TCX"
178
- # data = File.read(filename)
179
- # importer = Importer::Garmin.new(:data => data)
180
- # workout = importer.restore
181
- # workout.duration.should be_close(4996, 0.2)
182
- # end
108
+ #
183
109
  # end
184
110
  #
185
- # context "Parse polar RS400 file" do
186
- # it "finds the duration and time" do
187
- # filename ="spec/samples/polarRS400.hrm"
111
+ # context "Parse garmin file" do
112
+ # it "finds workout start time on a short workout" do
113
+ # filename = "spec/samples/indoor-garmin-405.TCX"
188
114
  # data = File.read(filename)
189
- # importer = Importer::Polar.new(:data => data, :time_zone => "Pacific Time (US & Canada)")
115
+ # importer = Importer::Garmin.new(:data => data)
190
116
  # workout = importer.restore
191
- # workout.duration.should be_close(3569,1)
192
- # workout.time.should == Time.parse("Thu Apr 16 12:01:55 -0700 2009")
117
+ # workout.time.should == Time.parse("Fri Aug 22 01:04:55 UTC 2008")
193
118
  # end
194
- # it "calculates the average heartrate" do
195
- # filename ="spec/samples/polarRS400.hrm"
119
+ # it "finds the duration on a short workout" do
120
+ # filename = "spec/samples/indoor-garmin-405.TCX"
196
121
  # data = File.read(filename)
197
- # importer = Importer::Polar.new(:data => data, :time_zone => "Pacific Time (US & Canada)")
122
+ # importer = Importer::Garmin.new(:data => data)
198
123
  # workout = importer.restore
199
- # workout.average_hr.should be_close(145, 1)
124
+ # workout.duration.should be_close(755, 1)
200
125
  # end
201
- # end
202
- #
203
- # context "Parse a Polar RR file" do
204
- # it "calculates the heart rate from RR" do
205
- # filename ="spec/samples/polarRS800-RR.hrm"
126
+ # it "indoor workout has no trackpoints" do
127
+ # filename = "spec/samples/indoor-garmin-405.TCX"
206
128
  # data = File.read(filename)
207
- # importer = Importer::Polar.new(:data => data, :time_zone => "Pacific Time (US & Canada)")
129
+ # importer = Importer::Garmin.new(:data => data)
208
130
  # workout = importer.restore
209
- # workout.trackpoints.each {|tp| tp.hr.should < 220 && tp.hr.should > 30}
210
- # workout.average_hr.should be_close(115, 1)
211
- # workout.average_speed.should == nil
131
+ # workout.distance.should be_nil
132
+ # workout.average_hr.should be_nil
133
+ # workout.average_speed.should be_nil
134
+ # workout.altitude_gain.should be_nil
135
+ # workout.trackpoints.should == {}
212
136
  # end
213
- # end
214
- #
215
- # context "Parse a Suunto T6C RR file" do
216
- # it "finds the duration and time" do
217
- # filename = "spec/samples/suunto-t6-RR-stops.sdf"
137
+ # it "parses files with only LAT and LNG" do
138
+ # filename = "spec/samples/garmin-only-lat-lng.tcx"
218
139
  # data = File.read(filename)
219
- # importer = Importer::Suunto.new(:data => data, :time_zone => "Pacific Time (US & Canada)")
140
+ # importer = Importer::Garmin.new(:data => data)
220
141
  # workout = importer.restore
221
- # workout.duration.should be_close(4781,1)
222
- # workout.time.should == Time.parse("Thu May 07 14:16:07 -0700 2009")
142
+ # workout.distance.should be_close(172052, 1)
143
+ # workout.average_hr.should be_nil
144
+ # workout.average_speed.should be_close(5.93, 0.1)
145
+ # workout.altitude_gain.should be_close(372, 10)
223
146
  # end
224
- # it "calculates the average HR & altitude" do
225
- # filename = "spec/samples/suunto-t6-RR-stops.sdf"
147
+ #
148
+ # # Parsing the full XML is just slow. Commenting out for now.
149
+ # it "gets workout level settings for outdoor workout" do
150
+ # filename = "spec/samples/outdoor-garmin-405.TCX"
226
151
  # data = File.read(filename)
227
- # importer = Importer::Suunto.new(:data => data, :time_zone => "Pacific Time (US & Canada)")
152
+ # importer = Importer::Garmin.new(:data => data)
228
153
  # workout = importer.restore
229
- # workout.average_hr.should be_close(152,1)
230
- # workout.average_speed.should == nil
231
- # workout.trackpoints.each { |tp| tp.speed.should == nil }
232
- # workout.altitude_gain.should be_close(115, 10)
154
+ # workout.distance.should be_close(11740, 5)
155
+ # workout.average_hr.should be_close(149.7, 0.5)
156
+ # workout.average_speed.should be_close(1.5, 0.2)
157
+ # workout.altitude_gain.should be_close(580, 25)
233
158
  # end
234
- # it "calculates the speed and distance" do
235
- # filename = "spec/samples/suunto-with-cadence-speed-distance.sdf"
159
+ #
160
+ # it "gets workout level settings for weird distance workout" do
161
+ # filename = "spec/samples/garmin-405-dies-distance.TCX"
236
162
  # data = File.read(filename)
237
- # importer = Importer::Suunto.new(:data => data, :time_zone => "Pacific Time (US & Canada)")
163
+ # importer = Importer::Garmin.new(:data => data)
238
164
  # workout = importer.restore
239
- # workout.average_hr.should be_close(131,1)
240
- # workout.average_speed.should be_close(9.3, 0.1)
241
- # workout.altitude_gain.should be_close(75, 15)
242
- # workout.distance.should == 124597
165
+ # workout.distance.should be_close(9426, 1)
166
+ # workout.average_hr.should == nil
167
+ # workout.average_speed.should be_close(6.7, 0.2)
168
+ # workout.altitude_gain.should be_close(40, 10)
243
169
  # end
170
+ #
171
+ # it "doesn't have any 0 in latitude" do
172
+ # filename = "spec/samples/garmin-405-with-0-0.TCX"
173
+ # data = File.read(filename)
174
+ # importer = Importer::Garmin.new(:data => data)
175
+ # workout = importer.restore
176
+ # workout.trackpoints.map {|tp| tp.lat.should_not == 0.0}
177
+ # workout.trackpoints.map {|tp| tp.lat.should_not == "undefined"}
178
+ # end
179
+ #
180
+ # it "handles files with INSANE duration" do
181
+ # filename = "spec/samples/insane-duration.TCX"
182
+ # data = File.read(filename)
183
+ # importer = Importer::Garmin.new(:data => data)
184
+ # workout = importer.restore
185
+ # workout.duration.should be_close(4996, 0.2)
186
+ # end
244
187
  # end
188
+ #
189
+ # context "Parse polar RS400 file" do
190
+ # it "finds the duration and time" do
191
+ # filename ="spec/samples/polarRS400.hrm"
192
+ # data = File.read(filename)
193
+ # importer = Importer::Polar.new(:data => data, :time_zone => "Pacific Time (US & Canada)")
194
+ # workout = importer.restore
195
+ # workout.duration.should be_close(3569,1)
196
+ # workout.time.should == Time.parse("Thu Apr 16 12:01:55 -0700 2009")
197
+ # end
198
+ # it "calculates the average heartrate" do
199
+ # filename ="spec/samples/polarRS400.hrm"
200
+ # data = File.read(filename)
201
+ # importer = Importer::Polar.new(:data => data, :time_zone => "Pacific Time (US & Canada)")
202
+ # workout = importer.restore
203
+ # workout.average_hr.should be_close(145, 1)
204
+ # end
205
+ # end
206
+ #
207
+ # context "Parse a Polar RR file" do
208
+ # it "calculates the heart rate from RR" do
209
+ # filename ="spec/samples/polarRS800-RR.hrm"
210
+ # data = File.read(filename)
211
+ # importer = Importer::Polar.new(:data => data, :time_zone => "Pacific Time (US & Canada)")
212
+ # workout = importer.restore
213
+ # workout.trackpoints.each {|tp| tp.hr.should < 220 && tp.hr.should > 30}
214
+ # workout.average_hr.should be_close(115, 1)
215
+ # workout.average_speed.should == nil
216
+ # end
217
+ # end
218
+ #
219
+ # context "Parse a Suunto T6C RR file" do
220
+ # it "finds the duration and time" do
221
+ # filename = "spec/samples/suunto-t6-RR-stops.sdf"
222
+ # data = File.read(filename)
223
+ # importer = Importer::Suunto.new(:data => data, :time_zone => "Pacific Time (US & Canada)")
224
+ # workout = importer.restore
225
+ # workout.duration.should be_close(4781,1)
226
+ # workout.time.should == Time.parse("Thu May 07 14:16:07 -0700 2009")
227
+ # end
228
+ # it "calculates the average HR & altitude" do
229
+ # filename = "spec/samples/suunto-t6-RR-stops.sdf"
230
+ # data = File.read(filename)
231
+ # importer = Importer::Suunto.new(:data => data, :time_zone => "Pacific Time (US & Canada)")
232
+ # workout = importer.restore
233
+ # workout.average_hr.should be_close(152,1)
234
+ # workout.average_speed.should == nil
235
+ # workout.trackpoints.each { |tp| tp.speed.should == nil }
236
+ # workout.altitude_gain.should be_close(115, 10)
237
+ # end
238
+ # it "calculates the speed and distance" do
239
+ # filename = "spec/samples/suunto-with-cadence-speed-distance.sdf"
240
+ # data = File.read(filename)
241
+ # importer = Importer::Suunto.new(:data => data, :time_zone => "Pacific Time (US & Canada)")
242
+ # workout = importer.restore
243
+ # workout.average_hr.should be_close(131,1)
244
+ # workout.average_speed.should be_close(9.3, 0.1)
245
+ # workout.altitude_gain.should be_close(75, 15)
246
+ # workout.distance.should == 124597
247
+ # end
248
+ # end
249
+
250
+ context "Parse Timex CSV" do
251
+ it "handles HR only" do
252
+ filename = "spec/samples/timex/HR.csv"
253
+ data = File.read(filename)
254
+ importer = Importer::Timex.new(:data => data, :time_zone => "Pacific Time (US & Canada)")
255
+ workout = importer.restore
256
+ workout.duration.should be_close(3298, 1)
257
+ workout.time.should == Time.parse("Jan 01 09:27:26 -0800 2009")
258
+ workout.average_hr.should be_close(81,1)
259
+ end
260
+
261
+ it "does speed and distance" do
262
+ filename = "spec/samples/timex/Speed+Distance.csv"
263
+ data = File.read(filename)
264
+ importer = Importer::Timex.new(:data => data, :time_zone => "Pacific Time (US & Canada)")
265
+ workout = importer.restore
266
+ workout.duration.should be_close(2580, 1)
267
+ workout.time.should == Time.parse("Feb 01 08:27:02 -0800 2009")
268
+ workout.average_hr.should == nil
269
+ workout.distance.should be_close(8391, 1)
270
+ workout.average_speed.should be_close(3.2, 0.2)
271
+ end
272
+
273
+ it "handles a GPS only file" do
274
+ filename = "spec/samples/timex/GPS.csv"
275
+ data = File.read(filename)
276
+ importer = Importer::Timex.new(:data => data, :time_zone => "Pacific Time (US & Canada)")
277
+ workout = importer.restore
278
+ workout.duration.should be_close(1937, 1)
279
+ workout.time.should == Time.parse("Jun 01 12:03:12 -0700 2009")
280
+ workout.average_hr.should == nil
281
+ workout.distance.should be_close(6035, 1)
282
+ workout.average_speed.should be_close(3.05, 0.05)
283
+ end
284
+
285
+ it "handles GPS & HR" do
286
+ filename = "spec/samples/timex/GPS+HR.csv"
287
+ data = File.read(filename)
288
+ importer = Importer::Timex.new(:data => data, :time_zone => "Pacific Time (US & Canada)")
289
+ workout = importer.restore
290
+ workout.duration.should be_close(2677.0, 1)
291
+ workout.time.should == Time.parse("Jul 01 12:00:43 -0700 2009")
292
+ workout.average_hr.should be_close(169,1)
293
+ workout.distance.should be_close(6435, 1)
294
+ workout.average_speed.should be_close(2.34, 0.05)
295
+ end
296
+ end
245
297
  end
246
298
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: teich-hrmparser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oren Teich
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-07-25 00:00:00 -07:00
12
+ date: 2009-08-15 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -35,6 +35,7 @@ files:
35
35
  - lib/hrmparser/importer/gpx.rb
36
36
  - lib/hrmparser/importer/polar.rb
37
37
  - lib/hrmparser/importer/suunto.rb
38
+ - lib/hrmparser/importer/timex.rb
38
39
  - lib/hrmparser/trackpoint.rb
39
40
  - lib/hrmparser/workout.rb
40
41
  - spec/arraymath_spec.rb
@@ -43,6 +44,7 @@ files:
43
44
  - spec/spec_helper.rb
44
45
  has_rdoc: false
45
46
  homepage: http://github.com/teich/hrmparser
47
+ licenses:
46
48
  post_install_message:
47
49
  rdoc_options:
48
50
  - --charset=UTF-8
@@ -63,7 +65,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
65
  requirements: []
64
66
 
65
67
  rubyforge_project:
66
- rubygems_version: 1.2.0
68
+ rubygems_version: 1.3.5
67
69
  signing_key:
68
70
  specification_version: 3
69
71
  summary: Heart Rate Monitor Parser