fit4ruby 3.2.0 → 3.7.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 +4 -2
- data/lib/fit4ruby/Activity.rb +57 -9
- data/lib/fit4ruby/DeviceInfo.rb +37 -0
- data/lib/fit4ruby/FieldDescription.rb +7 -1
- data/lib/fit4ruby/FitDataRecord.rb +3 -3
- data/lib/fit4ruby/FitDefinitionField.rb +2 -2
- data/lib/fit4ruby/FitMessageRecord.rb +3 -3
- data/lib/fit4ruby/GlobalFitDictionaries.rb +278 -22
- data/lib/fit4ruby/GlobalFitMessage.rb +6 -1
- data/lib/fit4ruby/GlobalFitMessages.rb +213 -9
- data/lib/fit4ruby/Lap.rb +29 -3
- data/lib/fit4ruby/Length.rb +53 -0
- data/lib/fit4ruby/Record.rb +4 -4
- data/lib/fit4ruby/version.rb +1 -1
- data/spec/FitFile_spec.rb +59 -11
- metadata +36 -7
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/Record.rb
CHANGED
@@ -38,14 +38,14 @@ module Fit4Ruby
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
# Convert the 'speed' field into a running pace. The
|
42
|
-
# minutes per Kilometer.
|
41
|
+
# Convert the 'speed' or 'enhanced_speed' field into a running pace. The
|
42
|
+
# pace is measured in minutes per Kilometer.
|
43
43
|
# @return [Float or nil] pace for this Record in m/s or nil if not
|
44
44
|
# available.
|
45
45
|
def pace
|
46
|
-
return nil unless @speed
|
46
|
+
return nil unless @speed || @enhanced_speed
|
47
47
|
|
48
|
-
1000.0 / (@speed * 60.0)
|
48
|
+
1000.0 / ((@speed || @enhanced_speed) * 60.0)
|
49
49
|
end
|
50
50
|
|
51
51
|
end
|
data/lib/fit4ruby/version.rb
CHANGED
data/spec/FitFile_spec.rb
CHANGED
@@ -14,10 +14,13 @@ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
14
14
|
|
15
15
|
require 'fit4ruby'
|
16
16
|
|
17
|
-
|
17
|
+
ENV['TZ'] = 'UTC'
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
describe Fit4Ruby do
|
20
|
+
let(:fit_file) { 'test.fit' }
|
21
|
+
let(:timestamp) { Time.now }
|
22
|
+
let(:activity) do
|
23
|
+
ts = timestamp
|
21
24
|
a = Fit4Ruby::Activity.new
|
22
25
|
a.total_timer_time = 30 * 60.0
|
23
26
|
a.new_user_data({ :age => 33, :height => 1.78, :weight => 73.0,
|
@@ -97,20 +100,65 @@ describe Fit4Ruby do
|
|
97
100
|
:event_type => 'marker', :recovery_hr => 132 })
|
98
101
|
|
99
102
|
a.aggregate
|
103
|
+
a
|
104
|
+
end
|
100
105
|
|
101
|
-
|
106
|
+
before do
|
107
|
+
File.delete(fit_file) if File.exist?(fit_file)
|
108
|
+
expect(File.exist?(fit_file)).to be false
|
102
109
|
end
|
103
110
|
|
104
|
-
|
105
|
-
fit_file = 'test.fit'
|
111
|
+
after { File.delete(fit_file) }
|
106
112
|
|
107
|
-
|
108
|
-
Fit4Ruby.write(fit_file,
|
109
|
-
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
|
110
116
|
|
111
117
|
b = Fit4Ruby.read(fit_file)
|
112
|
-
expect(b).to eq
|
113
|
-
|
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
|
+
|
114
162
|
end
|
115
163
|
|
116
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.7.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:
|
11
|
+
date: 2020-09-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bindata
|
@@ -30,28 +30,28 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.9.
|
33
|
+
version: 0.9.20
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.9.
|
40
|
+
version: 0.9.20
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.
|
47
|
+
version: 12.0.0
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.
|
54
|
+
version: 12.0.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: bundler
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -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.
|