fit4ruby 3.3.0 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Gemfile.lock +30 -6
- data/fit4ruby.gemspec +2 -0
- data/lib/fit4ruby/Activity.rb +57 -9
- data/lib/fit4ruby/FitDataRecord.rb +1 -1
- data/lib/fit4ruby/GlobalFitDictionaries.rb +2 -1
- data/lib/fit4ruby/GlobalFitMessages.rb +14 -7
- data/lib/fit4ruby/Lap.rb +29 -3
- data/lib/fit4ruby/Length.rb +53 -0
- data/lib/fit4ruby/version.rb +1 -1
- data/spec/FitFile_spec.rb +57 -11
- metadata +32 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: '0478b4abeb404d3c3dfab616289182d37b280c0090cb3be1771e9acd78a38ae0'
|
4
|
+
data.tar.gz: 11e8f45f61cb2780bdd155eb2cf87e0d7952a5b4a079d5fdf8b3f6df0849a9b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fbd0bcb013b1736e18b307f389f95967b3cb34b96c0ed113fef48add5604d5ef39c745e53a7612b69b61cf1a16a8ce688d3bbcddd136985b8a6a79b24943c120
|
7
|
+
data.tar.gz: 8de75daacdbb990b3fc2334891d9fa39f20911255a788ab5c7863610ea7f0eb344612bf24fe740f143110477a04b4bad46398d6575944dca89a7bba3feb7591c
|
data/Gemfile.lock
CHANGED
@@ -1,15 +1,34 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
fit4ruby (
|
5
|
-
bindata (
|
4
|
+
fit4ruby (3.3.0)
|
5
|
+
bindata (= 2.3.0)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
bindata (2.
|
10
|
+
bindata (2.3.0)
|
11
|
+
coderay (1.1.2)
|
12
|
+
diff-lcs (1.3)
|
13
|
+
method_source (0.9.2)
|
14
|
+
pry (0.12.2)
|
15
|
+
coderay (~> 1.1.0)
|
16
|
+
method_source (~> 0.9.0)
|
11
17
|
rake (0.9.6)
|
12
|
-
|
18
|
+
rspec (3.8.0)
|
19
|
+
rspec-core (~> 3.8.0)
|
20
|
+
rspec-expectations (~> 3.8.0)
|
21
|
+
rspec-mocks (~> 3.8.0)
|
22
|
+
rspec-core (3.8.2)
|
23
|
+
rspec-support (~> 3.8.0)
|
24
|
+
rspec-expectations (3.8.4)
|
25
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
26
|
+
rspec-support (~> 3.8.0)
|
27
|
+
rspec-mocks (3.8.1)
|
28
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
29
|
+
rspec-support (~> 3.8.0)
|
30
|
+
rspec-support (3.8.2)
|
31
|
+
yard (0.9.20)
|
13
32
|
|
14
33
|
PLATFORMS
|
15
34
|
ruby
|
@@ -17,5 +36,10 @@ PLATFORMS
|
|
17
36
|
DEPENDENCIES
|
18
37
|
bundler (>= 1.6.4)
|
19
38
|
fit4ruby!
|
20
|
-
|
21
|
-
|
39
|
+
pry (>= 0.12)
|
40
|
+
rake (~> 0.9.6)
|
41
|
+
rspec (>= 3.8)
|
42
|
+
yard (~> 0.9.20)
|
43
|
+
|
44
|
+
BUNDLED WITH
|
45
|
+
2.0.2
|
data/fit4ruby.gemspec
CHANGED
@@ -28,4 +28,6 @@ EOT
|
|
28
28
|
spec.add_development_dependency('yard', '~>0.9.20')
|
29
29
|
spec.add_development_dependency('rake', '~>0.9.6')
|
30
30
|
spec.add_development_dependency('bundler', '>=1.6.4')
|
31
|
+
spec.add_development_dependency('rspec', '>=3.8')
|
32
|
+
spec.add_development_dependency('pry', '>=0.12')
|
31
33
|
end
|
data/lib/fit4ruby/Activity.rb
CHANGED
@@ -24,6 +24,7 @@ require 'fit4ruby/UserProfile'
|
|
24
24
|
require 'fit4ruby/PhysiologicalMetrics'
|
25
25
|
require 'fit4ruby/Session'
|
26
26
|
require 'fit4ruby/Lap'
|
27
|
+
require 'fit4ruby/Length'
|
27
28
|
require 'fit4ruby/Record'
|
28
29
|
require 'fit4ruby/HRV'
|
29
30
|
require 'fit4ruby/HeartRateZones'
|
@@ -40,7 +41,7 @@ module Fit4Ruby
|
|
40
41
|
attr_accessor :file_id, :field_descriptions, :developer_data_ids, :epo_data,
|
41
42
|
:file_creator, :device_infos, :sensor_settings, :data_sources,
|
42
43
|
:user_data, :user_profiles, :physiological_metrics,
|
43
|
-
:sessions, :laps, :records, :hrv,
|
44
|
+
:sessions, :laps, :records, :lengths, :hrv,
|
44
45
|
:heart_rate_zones, :events, :personal_records
|
45
46
|
|
46
47
|
# Create a new Activity object.
|
@@ -65,15 +66,21 @@ module Fit4Ruby
|
|
65
66
|
@events = []
|
66
67
|
@sessions = []
|
67
68
|
@laps = []
|
69
|
+
@lengths = []
|
68
70
|
@records = []
|
69
71
|
@hrv = []
|
70
72
|
@heart_rate_zones = []
|
71
73
|
@personal_records = []
|
72
74
|
|
73
75
|
@cur_session_laps = []
|
76
|
+
|
74
77
|
@cur_lap_records = []
|
78
|
+
@cur_lap_lengths = []
|
79
|
+
|
80
|
+
@cur_length_records = []
|
75
81
|
|
76
82
|
@lap_counter = 1
|
83
|
+
@length_counter = 1
|
77
84
|
|
78
85
|
set_field_values(field_values)
|
79
86
|
end
|
@@ -141,11 +148,20 @@ module Fit4Ruby
|
|
141
148
|
|
142
149
|
# Laps must have a consecutively growing message index.
|
143
150
|
@laps.each.with_index do |lap, index|
|
144
|
-
lap.check(index)
|
151
|
+
lap.check(index, self)
|
145
152
|
# If we have heart rate zone records, there should be one for each
|
146
153
|
# lap
|
147
154
|
@heart_rate_zones[index].check(index) if @heart_rate_zones[index]
|
148
155
|
end
|
156
|
+
|
157
|
+
# Lengths must have a consecutively growing message index.
|
158
|
+
@lengths.each.with_index do |length, index|
|
159
|
+
length.check(index)
|
160
|
+
# If we have heart rate zone records, there should be one for each
|
161
|
+
# length
|
162
|
+
@heart_rate_zones[index].check(index) if @heart_rate_zones[index]
|
163
|
+
end
|
164
|
+
|
149
165
|
@sessions.each { |s| s.check(self) }
|
150
166
|
end
|
151
167
|
|
@@ -206,17 +222,22 @@ module Fit4Ruby
|
|
206
222
|
d
|
207
223
|
end
|
208
224
|
|
209
|
-
# Call this method to update the aggregated data fields stored in Lap
|
210
|
-
# Session objects.
|
225
|
+
# Call this method to update the aggregated data fields stored in Lap,
|
226
|
+
# Length, and Session objects.
|
211
227
|
def aggregate
|
212
228
|
@laps.each { |l| l.aggregate }
|
229
|
+
@lengths.each { |l| l.aggregate }
|
213
230
|
@sessions.each { |s| s.aggregate }
|
214
231
|
end
|
215
232
|
|
216
233
|
# Convenience method that averages the speed over all sessions.
|
217
234
|
def avg_speed
|
218
235
|
speed = 0.0
|
219
|
-
@sessions.each
|
236
|
+
@sessions.each do |s|
|
237
|
+
if (spd = s.avg_speed || s.enhanced_avg_speed)
|
238
|
+
speed += spd
|
239
|
+
end
|
240
|
+
end
|
220
241
|
speed / @sessions.length
|
221
242
|
end
|
222
243
|
|
@@ -292,8 +313,8 @@ module Fit4Ruby
|
|
292
313
|
@device_infos + @sensor_settings +
|
293
314
|
@data_sources + @user_profiles +
|
294
315
|
@physiological_metrics + @events +
|
295
|
-
@sessions + @laps + @records + @
|
296
|
-
@personal_records).sort.each do |s|
|
316
|
+
@sessions + @laps + @records + @lengths +
|
317
|
+
@heart_rate_zones + @personal_records).sort.each do |s|
|
297
318
|
s.write(io, id_mapper)
|
298
319
|
end
|
299
320
|
super
|
@@ -404,6 +425,16 @@ module Fit4Ruby
|
|
404
425
|
new_fit_data_record('lap', field_values)
|
405
426
|
end
|
406
427
|
|
428
|
+
# Add a new Length to the Activity. All previoulsy added Record objects are
|
429
|
+
# associated with this Length unless they have been associated with another
|
430
|
+
# Length before.
|
431
|
+
# @param field_values [Hash] A Hash that provides initial values for
|
432
|
+
# certain fields of the FitDataRecord.
|
433
|
+
# @return [Length]
|
434
|
+
def new_length(field_values = {})
|
435
|
+
new_fit_data_record('length', field_values)
|
436
|
+
end
|
437
|
+
|
407
438
|
# Add a new HeartRateZones record to the Activity.
|
408
439
|
# @param field_values [Heash] A Hash that provides initial values for
|
409
440
|
# certain fields of the FitDataRecord.
|
@@ -496,8 +527,12 @@ module Fit4Ruby
|
|
496
527
|
@cur_session_laps = []
|
497
528
|
when 'lap'
|
498
529
|
record = create_new_lap(field_values)
|
530
|
+
when 'length'
|
531
|
+
record = create_new_length(field_values)
|
499
532
|
when 'record'
|
500
|
-
|
533
|
+
record = Record.new(field_values)
|
534
|
+
@cur_lap_records << record
|
535
|
+
@cur_length_records << record
|
501
536
|
@records << record
|
502
537
|
when 'hrv'
|
503
538
|
@hrv << (record = HRV.new(field_values))
|
@@ -515,16 +550,29 @@ module Fit4Ruby
|
|
515
550
|
private
|
516
551
|
|
517
552
|
def create_new_lap(field_values)
|
518
|
-
lap = Lap.new(@cur_lap_records, @laps.last,
|
553
|
+
lap = Lap.new(@cur_lap_records, @laps.last,
|
554
|
+
field_values,
|
555
|
+
@length_counter, @cur_lap_lengths)
|
519
556
|
lap.message_index = @lap_counter - 1
|
520
557
|
@lap_counter += 1
|
521
558
|
@cur_session_laps << lap
|
522
559
|
@laps << lap
|
523
560
|
@cur_lap_records = []
|
561
|
+
@cur_lap_lengths = []
|
524
562
|
|
525
563
|
lap
|
526
564
|
end
|
527
565
|
|
566
|
+
def create_new_length(field_values)
|
567
|
+
length = Length.new(@cur_length_records, @lengths.last, field_values)
|
568
|
+
length.message_index = @length_counter - 1
|
569
|
+
@length_counter += 1
|
570
|
+
@cur_lap_lengths << length
|
571
|
+
@lengths << length
|
572
|
+
@cur_length_records = []
|
573
|
+
|
574
|
+
length
|
575
|
+
end
|
528
576
|
end
|
529
577
|
|
530
578
|
end
|
@@ -21,7 +21,7 @@ module Fit4Ruby
|
|
21
21
|
|
22
22
|
RecordOrder = [ 'user_data', 'user_profile',
|
23
23
|
'device_info', 'data_sources', 'event',
|
24
|
-
'record', 'lap', 'session', 'heart_rate_zones',
|
24
|
+
'record', 'lap', 'length', 'session', 'heart_rate_zones',
|
25
25
|
'personal_records' ]
|
26
26
|
|
27
27
|
attr_reader :message
|
@@ -355,6 +355,7 @@ module Fit4Ruby
|
|
355
355
|
entry 2697, 'fenix5'
|
356
356
|
entry 2957, 'fenix5_gps_galileo' # Just a guess
|
357
357
|
entry 3111, 'fenix5x_plus'
|
358
|
+
entry 3126, 'instinct'
|
358
359
|
entry 10007, 'sdm4'
|
359
360
|
entry 20119, 'training_center'
|
360
361
|
entry 65532, 'android_antplus_plugin'
|
@@ -593,7 +594,7 @@ module Fit4Ruby
|
|
593
594
|
dict 'swim_stroke'
|
594
595
|
entry 0, 'freestyle'
|
595
596
|
entry 1, 'backstroke'
|
596
|
-
entry 2, '
|
597
|
+
entry 2, 'breaststroke'
|
597
598
|
entry 3, 'butterfly'
|
598
599
|
entry 4, 'drill'
|
599
600
|
entry 5, 'mixed'
|
@@ -131,6 +131,7 @@ module Fit4Ruby
|
|
131
131
|
field 144, 'enum', 'true_up_enabled'
|
132
132
|
field 148, 'enum', 'undocumented_field_148'
|
133
133
|
field 149, 'enum', 'undocumented_field_149'
|
134
|
+
field 168, 'enum', 'undocumented_field_168'
|
134
135
|
|
135
136
|
message 3, 'user_profile'
|
136
137
|
field 0, 'string', 'friendly_name'
|
@@ -161,7 +162,7 @@ module Fit4Ruby
|
|
161
162
|
field 34, 'uint16', 'undocumented_field_34'
|
162
163
|
field 35, 'uint32', 'undocumented_field_35'
|
163
164
|
field 36, 'uint8', 'undocumented_field_36'
|
164
|
-
field 37, 'uint16', '
|
165
|
+
field 37, 'uint16', 'functional_threshold_speed', :scale => 36, :unit => 'm/s'
|
165
166
|
field 38, 'uint16', 'undocumented_field_38'
|
166
167
|
field 39, 'float32', 'undocumented_field_39'
|
167
168
|
field 40, 'float32', 'undocumented_field_40'
|
@@ -372,7 +373,7 @@ module Fit4Ruby
|
|
372
373
|
field 44, 'uint16', 'pool_length', :scale => 100, :unit => 'm'
|
373
374
|
field 45, 'uint16', 'undefined_value_45'
|
374
375
|
field 46, 'enum', 'pool_length_unit', :dict => 'display_measure'
|
375
|
-
field 47, 'uint16', '
|
376
|
+
field 47, 'uint16', 'num_active_lengths', :unit => 'lengths'
|
376
377
|
field 48, 'uint32', 'total_work', :unit => 'J'
|
377
378
|
field 57, 'sint8', 'avg_temperature', :unit => 'C'
|
378
379
|
field 58, 'sint8', 'max_temperature', :unit => 'C'
|
@@ -445,6 +446,8 @@ module Fit4Ruby
|
|
445
446
|
field 185, 'uint8', 'undocumented_field_185'
|
446
447
|
field 187, 'float32', 'undocumented_field_187'
|
447
448
|
field 188, 'enum', 'undocumented_field_188'
|
449
|
+
field 189, 'uint16', 'undocumented_field_189'
|
450
|
+
field 190, 'uint16', 'undocumented_field_190'
|
448
451
|
field 253, 'uint32', 'timestamp', :type => 'date_time'
|
449
452
|
field 254, 'uint16', 'message_index'
|
450
453
|
|
@@ -496,7 +499,7 @@ module Fit4Ruby
|
|
496
499
|
field 37, 'uint16', 'avg_stroke_distance', :scale => 100, :unit => 'm'
|
497
500
|
field 38, 'enum', 'swim_stroke', :dict => 'swim_stroke'
|
498
501
|
field 39, 'enum', 'sub_sport', :dict => 'sub_sport'
|
499
|
-
field 40, 'uint16', '
|
502
|
+
field 40, 'uint16', 'num_active_lengths', :unit => 'lengths'
|
500
503
|
field 41, 'uint32', 'total_work', :unit => 'J'
|
501
504
|
field 50, 'sint8', 'avg_temperature', :unit => 'C'
|
502
505
|
field 51, 'sint8', 'max_temperature', :unit => 'C'
|
@@ -808,7 +811,7 @@ module Fit4Ruby
|
|
808
811
|
field 10, 'uint8', 'avg_resting_heart_rate', :unit => 'bpm'
|
809
812
|
field 11, 'uint16', 'running_lactate_threshold_heart_rate', :unit => 'bpm'
|
810
813
|
field 12, 'uint16', 'functional_threshold_power', :unit => 'W'
|
811
|
-
field 13, 'uint16', '
|
814
|
+
field 13, 'uint16', 'functional_threshold_speed', :scale => 36, :unit => 'm/s'
|
812
815
|
field 14, 'uint8', 'undocumented_field_14'
|
813
816
|
field 15, 'uint8', 'undocumented_field_15'
|
814
817
|
field 16, 'uint32', 'undocumented_field_16'
|
@@ -821,7 +824,7 @@ module Fit4Ruby
|
|
821
824
|
message 101, 'length'
|
822
825
|
field 0, 'enum', 'event', :dict => 'event'
|
823
826
|
field 1, 'enum', 'event_type', :dict => 'event_type'
|
824
|
-
field 2, 'uint32', '
|
827
|
+
field 2, 'uint32', 'start_time', :type => 'date_time'
|
825
828
|
field 3, 'uint32', 'total_elapsed_time', :scale => 1000, :unit => 's'
|
826
829
|
field 4, 'uint32', 'total_timer_time', :scale => 1000, :unit => 's'
|
827
830
|
field 5, 'uint16', 'total_strokes', :unit => 'strokes'
|
@@ -833,6 +836,8 @@ module Fit4Ruby
|
|
833
836
|
field 12, 'enum', 'length_type', :dict => 'length_type'
|
834
837
|
field 18, 'uint16', 'player_score'
|
835
838
|
field 19, 'uint16', 'opponent_score'
|
839
|
+
field 20, 'uint16', 'stroke_count', :unit => 'counts'
|
840
|
+
field 21, 'uint16', 'zone_count', :unit => 'counts'
|
836
841
|
field 253, 'uint32', 'timestamp', :type => 'date_time'
|
837
842
|
field 254, 'uint16', 'message_index'
|
838
843
|
|
@@ -901,8 +906,8 @@ module Fit4Ruby
|
|
901
906
|
field 12, 'enum', 'undocumented_field_12'
|
902
907
|
field 13, 'uint8', 'undocumented_field_13'
|
903
908
|
field 14, 'uint16', 'running_lactate_threshold_heart_rate', :unit => 'bpm'
|
904
|
-
field 15, 'uint16', '
|
905
|
-
field 16, 'uint16', '
|
909
|
+
field 15, 'uint16', 'undocumented_field_15'
|
910
|
+
field 16, 'uint16', 'running_lactate_threshold_speed', :scale => 36, :unit => 'm/s'
|
906
911
|
field 17, 'sint8', 'performance_condition'
|
907
912
|
field 18, 'uint8', 'undocumented_field_18'
|
908
913
|
field 19, 'uint8', 'undocumented_field_19'
|
@@ -1008,6 +1013,7 @@ module Fit4Ruby
|
|
1008
1013
|
field 65, 'uint32', 'undocumented_field_65'
|
1009
1014
|
field 70, 'uint32', 'undocumented_field_70'
|
1010
1015
|
field 71, 'enum', 'undocumented_field_71'
|
1016
|
+
field 73, 'uint16z', 'undocumented_field_73'
|
1011
1017
|
field 254, 'uint16', 'message_index'
|
1012
1018
|
|
1013
1019
|
# Not part of the official ANT SDK doc.
|
@@ -1120,6 +1126,7 @@ module Fit4Ruby
|
|
1120
1126
|
message 269, 'undocumented_269'
|
1121
1127
|
field 0, 'uint8', 'undocumented_field_0'
|
1122
1128
|
field 1, 'uint8', 'undocumented_field_1'
|
1129
|
+
field 2, 'uint8', 'undocumented_field_2'
|
1123
1130
|
field 253, 'uint32', 'timestamp', :type => 'date_time'
|
1124
1131
|
|
1125
1132
|
# Not part of the official ANT SDK doc.
|
data/lib/fit4ruby/Lap.rb
CHANGED
@@ -19,13 +19,24 @@ module Fit4Ruby
|
|
19
19
|
|
20
20
|
include RecordAggregator
|
21
21
|
|
22
|
-
attr_reader :records
|
22
|
+
attr_reader :records, :lengths
|
23
23
|
|
24
|
-
|
24
|
+
# Create a new Lap object.
|
25
|
+
# @param records [Array of Records] Records to associate with the Lap.
|
26
|
+
# @param lengths [Array of Lengths] Lengths to associate with the Lap.
|
27
|
+
# @param first_length_index [Fixnum] Index of the first Length in this Lap.
|
28
|
+
# @param previous_lap [Lap] Previous Lap on same Session.
|
29
|
+
# @param field_values [Hash] Hash that provides initial values for certain
|
30
|
+
# fields.
|
31
|
+
def initialize(records, previous_lap, field_values, first_length_index, lengths)
|
25
32
|
super('lap')
|
33
|
+
@lengths = lengths
|
26
34
|
@meta_field_units['avg_stride_length'] = 'm'
|
27
35
|
@records = records
|
28
36
|
@previous_lap = previous_lap
|
37
|
+
@lengths.each { |length| @records += length.records }
|
38
|
+
@first_length_index = first_length_index
|
39
|
+
@num_lengths = @lengths.length
|
29
40
|
|
30
41
|
if previous_lap && previous_lap.records && previous_lap.records.last
|
31
42
|
# Set the start time of the new lap to the timestamp of the last record
|
@@ -43,10 +54,25 @@ module Fit4Ruby
|
|
43
54
|
set_field_values(field_values)
|
44
55
|
end
|
45
56
|
|
46
|
-
def check(index)
|
57
|
+
def check(index, activity)
|
47
58
|
unless @message_index == index
|
48
59
|
Log.fatal "message_index must be #{index}, not #{@message_index}"
|
49
60
|
end
|
61
|
+
|
62
|
+
return if @num_lengths.zero?
|
63
|
+
|
64
|
+
unless @first_length_index
|
65
|
+
Log.fatal 'first_length_index is not set'
|
66
|
+
end
|
67
|
+
|
68
|
+
@first_length_index.upto(@first_length_index - @num_lengths) do |i|
|
69
|
+
if (length = activity.lengths[i])
|
70
|
+
@lengths << length
|
71
|
+
else
|
72
|
+
Log.fatal "Lap references length #{i} which is not contained in "
|
73
|
+
"the FIT file."
|
74
|
+
end
|
75
|
+
end
|
50
76
|
end
|
51
77
|
|
52
78
|
# Compute the average stride length for this Session.
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# = Length.rb -- Fit4Ruby - FIT file processing library for Ruby
|
5
|
+
#
|
6
|
+
# Copyright (c) 2014, 2015 by Chris Schlaeger <cs@taskjuggler.org>
|
7
|
+
#
|
8
|
+
# This program is free software; you can redistribute it and/or modify
|
9
|
+
# it under the terms of version 2 of the GNU General Public License as
|
10
|
+
# published by the Free Software Foundation.
|
11
|
+
#
|
12
|
+
|
13
|
+
require 'fit4ruby/FitDataRecord'
|
14
|
+
require 'fit4ruby/RecordAggregator'
|
15
|
+
|
16
|
+
module Fit4Ruby
|
17
|
+
|
18
|
+
class Length < FitDataRecord
|
19
|
+
|
20
|
+
include RecordAggregator
|
21
|
+
|
22
|
+
attr_reader :records
|
23
|
+
|
24
|
+
def initialize(records, previous_length, field_values)
|
25
|
+
super('length')
|
26
|
+
@records = records
|
27
|
+
@previous_length = previous_length
|
28
|
+
|
29
|
+
if previous_length && previous_length.records && previous_length.records.last
|
30
|
+
# Set the start time of the new length to the timestamp of the last record
|
31
|
+
# of the previous length.
|
32
|
+
@start_time = previous_length.records.last.timestamp
|
33
|
+
elsif records.first
|
34
|
+
# Or to the timestamp of the first record.
|
35
|
+
@start_time = records.first.timestamp
|
36
|
+
end
|
37
|
+
|
38
|
+
if records.last
|
39
|
+
@total_elapsed_time = records.last.timestamp - @start_time
|
40
|
+
end
|
41
|
+
|
42
|
+
set_field_values(field_values)
|
43
|
+
end
|
44
|
+
|
45
|
+
def check(index)
|
46
|
+
unless @message_index == index
|
47
|
+
Log.fatal "message_index must be #{index}, not #{@message_index}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/lib/fit4ruby/version.rb
CHANGED
data/spec/FitFile_spec.rb
CHANGED
@@ -17,9 +17,10 @@ require 'fit4ruby'
|
|
17
17
|
ENV['TZ'] = 'UTC'
|
18
18
|
|
19
19
|
describe Fit4Ruby do
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
let(:fit_file) { 'test.fit' }
|
21
|
+
let(:timestamp) { Time.now }
|
22
|
+
let(:activity) do
|
23
|
+
ts = timestamp
|
23
24
|
a = Fit4Ruby::Activity.new
|
24
25
|
a.total_timer_time = 30 * 60.0
|
25
26
|
a.new_user_data({ :age => 33, :height => 1.78, :weight => 73.0,
|
@@ -99,20 +100,65 @@ describe Fit4Ruby do
|
|
99
100
|
:event_type => 'marker', :recovery_hr => 132 })
|
100
101
|
|
101
102
|
a.aggregate
|
103
|
+
a
|
104
|
+
end
|
102
105
|
|
103
|
-
|
106
|
+
before do
|
107
|
+
File.delete(fit_file) if File.exist?(fit_file)
|
108
|
+
expect(File.exist?(fit_file)).to be false
|
104
109
|
end
|
105
110
|
|
106
|
-
|
107
|
-
fit_file = 'test.fit'
|
111
|
+
after { File.delete(fit_file) }
|
108
112
|
|
109
|
-
|
110
|
-
Fit4Ruby.write(fit_file,
|
111
|
-
expect(File.
|
113
|
+
it 'should write an Activity FIT file and read it back' do
|
114
|
+
Fit4Ruby.write(fit_file, activity)
|
115
|
+
expect(File.exist?(fit_file)).to be true
|
112
116
|
|
113
117
|
b = Fit4Ruby.read(fit_file)
|
114
|
-
expect(b.
|
115
|
-
|
118
|
+
expect(b.laps.count).to eq 6
|
119
|
+
expect(b.lengths.count).to eq 0
|
120
|
+
expect(b.inspect).to eq(activity.inspect)
|
121
|
+
end
|
122
|
+
|
123
|
+
context 'activity with Lengths' do
|
124
|
+
let(:activity) do
|
125
|
+
ts = timestamp
|
126
|
+
laps = 0
|
127
|
+
lengths = 0
|
128
|
+
a = Fit4Ruby::Activity.new
|
129
|
+
|
130
|
+
a.total_timer_time = 30 * 60.0
|
131
|
+
a.new_device_info({ :timestamp => ts,
|
132
|
+
:device_index => 0, :manufacturer => 'garmin',
|
133
|
+
:serial_number => 123456789 })
|
134
|
+
|
135
|
+
0.upto(a.total_timer_time / 60) do |mins|
|
136
|
+
ts += 60
|
137
|
+
if mins > 0 && mins % 5 == 0
|
138
|
+
a.new_lap({ :timestamp => ts, :sport => 'swimming',
|
139
|
+
:message_index => laps, :total_cycles => 195 })
|
140
|
+
laps += 1
|
141
|
+
|
142
|
+
a.new_length({ :timestamp => ts, :event => 'length',
|
143
|
+
:message_index => lengths, :total_strokes => 45 })
|
144
|
+
lengths += 1
|
145
|
+
end
|
146
|
+
end
|
147
|
+
a
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'should write an Activity FIT file and read it back' do
|
151
|
+
Fit4Ruby.write(fit_file, activity)
|
152
|
+
expect(File.exist?(fit_file)).to be true
|
153
|
+
|
154
|
+
b = Fit4Ruby.read(fit_file)
|
155
|
+
expect(b.laps.count).to eq 6
|
156
|
+
expect(b.lengths.count).to eq 6
|
157
|
+
expect(b.laps.select { |l| l.sport == 'swimming' }.count).to eq 6
|
158
|
+
expect(b.lengths.select { |l| l.total_strokes == 45 }.count).to eq 6
|
159
|
+
expect(b.inspect).to eq(activity.inspect)
|
160
|
+
end
|
161
|
+
|
116
162
|
end
|
117
163
|
|
118
164
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fit4ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Schlaeger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bindata
|
@@ -66,6 +66,34 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 1.6.4
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.8'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.8'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.12'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.12'
|
69
97
|
description: |
|
70
98
|
This library can read and write FIT files and convert them into a Ruby data
|
71
99
|
structure for easy processing. This library was written for Garmin devices
|
@@ -118,6 +146,7 @@ files:
|
|
118
146
|
- lib/fit4ruby/HRV.rb
|
119
147
|
- lib/fit4ruby/HeartRateZones.rb
|
120
148
|
- lib/fit4ruby/Lap.rb
|
149
|
+
- lib/fit4ruby/Length.rb
|
121
150
|
- lib/fit4ruby/Log.rb
|
122
151
|
- lib/fit4ruby/Metrics.rb
|
123
152
|
- lib/fit4ruby/Monitoring.rb
|
@@ -161,7 +190,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
161
190
|
version: '0'
|
162
191
|
requirements: []
|
163
192
|
rubyforge_project:
|
164
|
-
rubygems_version: 2.2
|
193
|
+
rubygems_version: 2.7.6.2
|
165
194
|
signing_key:
|
166
195
|
specification_version: 4
|
167
196
|
summary: Library to read and write GARMIN FIT files.
|