teich-hrmparser 0.3.0 → 0.3.1
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.
- data/CHANGELOG.txt +3 -0
- data/VERSION.yml +2 -2
- data/lib/hrmparser/importer/garmin.rb +24 -10
- data/spec/hrmparser_spec.rb +137 -125
- metadata +2 -2
data/CHANGELOG.txt
CHANGED
data/VERSION.yml
CHANGED
|
@@ -24,26 +24,32 @@ module Importer
|
|
|
24
24
|
(@xml/:Trackpoint).each do |t|
|
|
25
25
|
found = true
|
|
26
26
|
trackpoint = HRMParser::TrackPoint.new
|
|
27
|
-
|
|
28
|
-
trackpoint.hr = (t/:HeartRateBpm/:Value).innerHTML.to_i
|
|
27
|
+
|
|
29
28
|
trackpoint.time = Time.parse((t/:Time).innerHTML)
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
|
|
30
|
+
hr = (t/:HeartRateBpm/:Value).innerHTML
|
|
31
|
+
alt = (t/:AltitudeMeters).innerHTML
|
|
32
|
+
dis = (t/:DistanceMeters).innerHTML
|
|
33
|
+
|
|
34
|
+
trackpoint.hr = hr != "" ? hr.to_i : nil
|
|
35
|
+
trackpoint.altitude = alt != "" ? alt.to_f : nil
|
|
36
|
+
trackpoint.distance = dis != "" ? dis.to_f : nil
|
|
32
37
|
|
|
33
38
|
(t/:Position).each do |p|
|
|
34
|
-
trackpoint.lat = (p/:LatitudeDegrees).innerHTML
|
|
35
|
-
trackpoint.lng = (p/:LongitudeDegrees).innerHTML
|
|
39
|
+
trackpoint.lat = (p/:LatitudeDegrees).innerHTML
|
|
40
|
+
trackpoint.lng = (p/:LongitudeDegrees).innerHTML
|
|
36
41
|
end
|
|
37
42
|
|
|
38
|
-
|
|
39
43
|
trackpoints << trackpoint
|
|
40
44
|
|
|
41
45
|
|
|
46
|
+
## CALCULATE SPEED. ICK.
|
|
42
47
|
if distance_one.nil?
|
|
43
48
|
distance_one = trackpoint.distance
|
|
44
49
|
time_one = trackpoint.time
|
|
45
50
|
else
|
|
46
51
|
distance_two = trackpoint.distance
|
|
52
|
+
next if distance_two.nil?
|
|
47
53
|
time_two = trackpoint.time
|
|
48
54
|
time_delta = time_two - time_one
|
|
49
55
|
distance_delta = distance_two - distance_one
|
|
@@ -51,17 +57,25 @@ module Importer
|
|
|
51
57
|
trackpoint.speed = distance_delta / time_delta
|
|
52
58
|
distance_one = distance_two
|
|
53
59
|
time_one = time_two
|
|
54
|
-
else
|
|
60
|
+
else
|
|
61
|
+
trackpoint.speed = nil
|
|
55
62
|
end
|
|
56
63
|
end
|
|
57
64
|
end
|
|
58
|
-
|
|
65
|
+
|
|
59
66
|
if found
|
|
60
67
|
workout.trackpoints = trackpoints
|
|
61
|
-
workout.distance = trackpoints.last.distance if !trackpoints.last.distance.nil?
|
|
62
68
|
workout.calc_average_speed!
|
|
63
69
|
workout.calc_altitude_gain!
|
|
64
70
|
workout.calc_average_hr!
|
|
71
|
+
trackpoints.reverse_each do |tp|
|
|
72
|
+
if !tp.distance.nil?
|
|
73
|
+
workout.distance = tp.distance
|
|
74
|
+
break
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
# workout.distance = trackpoints.last.distance if !trackpoints.last.nil? && !trackpoints.last.distance.nil?
|
|
78
|
+
|
|
65
79
|
end
|
|
66
80
|
|
|
67
81
|
return workout
|
data/spec/hrmparser_spec.rb
CHANGED
|
@@ -3,130 +3,142 @@ require File.dirname(__FILE__) + '/spec_helper.rb'
|
|
|
3
3
|
# Time to add your specs!
|
|
4
4
|
# http://rspec.info/
|
|
5
5
|
module HRMParser
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
describe "Workout" do
|
|
21
|
-
context "new workout" do
|
|
22
|
-
it "has no variables set" do
|
|
23
|
-
workout = Workout.new
|
|
24
|
-
workout.distance.should == nil
|
|
25
|
-
workout.duration.should == nil
|
|
26
|
-
workout.average_hr.should == nil
|
|
27
|
-
workout.name.should == nil
|
|
28
|
-
workout.file_name.should == nil
|
|
29
|
-
end
|
|
30
|
-
it "set name through initializer" do
|
|
31
|
-
workout = Workout.new(:name => "test workout")
|
|
32
|
-
workout.name.should == "test workout"
|
|
33
|
-
end
|
|
34
|
-
it "can not set average_hr during init" do
|
|
35
|
-
workout = Workout.new(:average_hr => 150)
|
|
36
|
-
workout.average_hr.should == nil
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
context "Identifies files" do
|
|
41
|
-
it "identify file as garmin" do
|
|
42
|
-
type = Importer.file_type("spec/samples/small-garmin.TCX")
|
|
43
|
-
type.should == "GARMIN_XML"
|
|
44
|
-
end
|
|
45
|
-
it "identification returns nil if no file specified" do
|
|
46
|
-
type = Importer.file_type("")
|
|
47
|
-
type.should == nil
|
|
48
|
-
end
|
|
49
|
-
it "identify file as polar" do
|
|
50
|
-
type = Importer.file_type("spec/samples/polarRS200.hrm")
|
|
51
|
-
type.should == "POLAR_HRM"
|
|
52
|
-
end
|
|
53
|
-
end
|
|
6
|
+
describe "TrackPoint" do
|
|
7
|
+
context "new trackpoint" do
|
|
8
|
+
it "has no variables set" do
|
|
9
|
+
hrm = TrackPoint.new
|
|
10
|
+
hrm.speed == nil
|
|
11
|
+
hrm.distance == nil
|
|
12
|
+
hrm.lat.should == nil
|
|
13
|
+
hrm.lng.should == nil
|
|
14
|
+
hrm.altitude.should == nil
|
|
15
|
+
hrm.hr.should == nil
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
54
19
|
|
|
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
|
-
|
|
20
|
+
describe "Workout" do
|
|
21
|
+
context "new workout" do
|
|
22
|
+
it "has no variables set" do
|
|
23
|
+
workout = Workout.new
|
|
24
|
+
workout.distance.should == nil
|
|
25
|
+
workout.duration.should == nil
|
|
26
|
+
workout.average_hr.should == nil
|
|
27
|
+
workout.name.should == nil
|
|
28
|
+
workout.file_name.should == nil
|
|
29
|
+
end
|
|
30
|
+
it "set name through initializer" do
|
|
31
|
+
workout = Workout.new(:name => "test workout")
|
|
32
|
+
workout.name.should == "test workout"
|
|
33
|
+
end
|
|
34
|
+
it "can not set average_hr during init" do
|
|
35
|
+
workout = Workout.new(:average_hr => 150)
|
|
36
|
+
workout.average_hr.should == nil
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context "Identifies files" do
|
|
41
|
+
it "identify file as garmin" do
|
|
42
|
+
type = Importer.file_type("spec/samples/small-garmin.TCX")
|
|
43
|
+
type.should == "GARMIN_XML"
|
|
44
|
+
end
|
|
45
|
+
it "identification returns nil if no file specified" do
|
|
46
|
+
type = Importer.file_type("")
|
|
47
|
+
type.should == nil
|
|
48
|
+
end
|
|
49
|
+
it "identify file as polar" do
|
|
50
|
+
type = Importer.file_type("spec/samples/polarRS200.hrm")
|
|
51
|
+
type.should == "POLAR_HRM"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
context "Parse garmin file" do
|
|
56
|
+
it "finds workout start time on a short workout" do
|
|
57
|
+
filename = "spec/samples/indoor-garmin-405.TCX"
|
|
58
|
+
data = File.read(filename)
|
|
59
|
+
importer = Importer::Garmin.new(:data => data)
|
|
60
|
+
workout = importer.restore
|
|
61
|
+
workout.time.should == Time.parse("Fri Aug 22 01:04:55 UTC 2008")
|
|
62
|
+
end
|
|
63
|
+
it "finds the duration on a short workout" do
|
|
64
|
+
filename = "spec/samples/indoor-garmin-405.TCX"
|
|
65
|
+
data = File.read(filename)
|
|
66
|
+
importer = Importer::Garmin.new(:data => data)
|
|
67
|
+
workout = importer.restore
|
|
68
|
+
workout.duration.should be_close(755, 1)
|
|
69
|
+
end
|
|
70
|
+
it "indoor workout has no trackpoints" do
|
|
71
|
+
filename = "spec/samples/indoor-garmin-405.TCX"
|
|
72
|
+
data = File.read(filename)
|
|
73
|
+
importer = Importer::Garmin.new(:data => data)
|
|
74
|
+
workout = importer.restore
|
|
75
|
+
workout.distance.should be_nil
|
|
76
|
+
workout.average_hr.should be_nil
|
|
77
|
+
workout.average_speed.should be_nil
|
|
78
|
+
workout.altitude_gain.should be_nil
|
|
79
|
+
workout.trackpoints.should == {}
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Parsing the full XML is just slow. Commenting out for now.
|
|
83
|
+
it "gets workout level settings for outdoor workout" do
|
|
84
|
+
filename = "spec/samples/outdoor-garmin-405.TCX"
|
|
85
|
+
data = File.read(filename)
|
|
86
|
+
importer = Importer::Garmin.new(:data => data)
|
|
87
|
+
workout = importer.restore
|
|
88
|
+
workout.distance.should be_close(11740, 5)
|
|
89
|
+
workout.average_hr.should be_close(149.7, 0.5)
|
|
90
|
+
workout.average_speed.should be_close(1.5, 0.2)
|
|
91
|
+
workout.altitude_gain.should be_close(583, 1.0)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "gets workout level settings for weird distance workout" do
|
|
95
|
+
filename = "spec/samples/garmin-405-dies-distance.TCX"
|
|
96
|
+
data = File.read(filename)
|
|
97
|
+
importer = Importer::Garmin.new(:data => data)
|
|
98
|
+
workout = importer.restore
|
|
99
|
+
workout.distance.should be_close(9426, 1)
|
|
100
|
+
workout.average_hr.should == nil
|
|
101
|
+
workout.average_speed.should be_close(6.7, 0.2)
|
|
102
|
+
workout.altitude_gain.should be_close(40, 1.0)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "doesn't have any 0 in latitude" do
|
|
106
|
+
filename = "spec/samples/garmin-405-with-0-0.TCX"
|
|
107
|
+
data = File.read(filename)
|
|
108
|
+
importer = Importer::Garmin.new(:data => data)
|
|
109
|
+
workout = importer.restore
|
|
110
|
+
workout.trackpoints.map {|tp| tp.lat.should_not == 0.0}
|
|
111
|
+
workout.trackpoints.map {|tp| tp.lat.should_not == "undefined"}
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
context "Parse polar RS200 file" do
|
|
116
|
+
it "finds the duration and time" do
|
|
117
|
+
filename ="spec/samples/polarRS200.hrm"
|
|
118
|
+
data = File.read(filename)
|
|
119
|
+
importer = Importer::Polar.new(:data => data, :time_zone => "UTC")
|
|
120
|
+
workout = importer.restore
|
|
121
|
+
workout.duration.should be_close(3569,1)
|
|
122
|
+
workout.time.should == Time.parse("Thu Apr 16 12:01:55 UTC 2009")
|
|
123
|
+
end
|
|
124
|
+
it "calculates the average heartrate" do
|
|
125
|
+
filename ="spec/samples/polarRS200.hrm"
|
|
126
|
+
data = File.read(filename)
|
|
127
|
+
importer = Importer::Polar.new(:data => data, :time_zone => "UTC")
|
|
128
|
+
workout = importer.restore
|
|
129
|
+
workout.average_hr.should be_close(145, 1)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
context "Parse a Polar RR file" do
|
|
133
|
+
it "calculates the heart rate from RR" do
|
|
134
|
+
filename ="spec/samples/polarRS800-RR.hrm"
|
|
135
|
+
data = File.read(filename)
|
|
136
|
+
importer = Importer::Polar.new(:data => data, :time_zone => "UTC")
|
|
137
|
+
workout = importer.restore
|
|
138
|
+
workout.trackpoints.each {|tp| tp.hr.should < 220 && tp.hr.should > 30}
|
|
139
|
+
workout.average_hr.should be_close(115, 1)
|
|
140
|
+
workout.average_speed.should == nil
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
132
144
|
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.3.
|
|
4
|
+
version: 0.3.1
|
|
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-05-
|
|
12
|
+
date: 2009-05-06 00:00:00 -07:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies: []
|
|
15
15
|
|