fit4ruby 3.3.0 → 3.4.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.
- 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.
|