fit4ruby 3.9.0 → 3.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/fit4ruby.gemspec +1 -1
- data/lib/fit4ruby/Activity.rb +35 -2
- data/lib/fit4ruby/Converters.rb +27 -16
- data/lib/fit4ruby/FitDataRecord.rb +33 -39
- data/lib/fit4ruby/GlobalFitDictionaries.rb +113 -45
- data/lib/fit4ruby/GlobalFitMessages.rb +83 -15
- data/lib/fit4ruby/Workout.rb +31 -0
- data/lib/fit4ruby/WorkoutStep.rb +32 -0
- data/lib/fit4ruby/version.rb +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 550fffeb71313287a1a1037974608c23b738da5a34c6aaca39374fea562b7426
|
4
|
+
data.tar.gz: 923417ab9520777208f4bd830696d7012c68b8ad2e7d39572749bad42301d560
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 990ce2d227826d09a114e55652bbc4287dc1b8c2e1a4a534a6ade8bbcc2baed3a321a4508ca6b880a6af745c007f58a60649b0f32bf75a6782f0e7df1498f26d
|
7
|
+
data.tar.gz: 3e6fe4df5bda73caa364937a13b1e4a764a65a55723026260f381d9a108441a030dc8ec8ff2876e7ece8527575571933164f8c23eae485e8f1ea09c479fe6924
|
data/README.md
CHANGED
@@ -10,7 +10,7 @@ me comments and patches. It was developed to form the back-end of
|
|
10
10
|
|
11
11
|
## Supported Devices
|
12
12
|
|
13
|
-
Tested devices: Garmin FR620
|
13
|
+
Tested devices: Garmin FR620, Fenix 3, Fenix 5, Fenix 5X, Fenix 6X
|
14
14
|
|
15
15
|
Other Garmin devices that generate FIT files may work as well. Since I
|
16
16
|
don't have any other devices, I can't add support for them.
|
data/fit4ruby.gemspec
CHANGED
@@ -22,7 +22,7 @@ EOT
|
|
22
22
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
23
23
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
24
24
|
spec.require_paths = ["lib"]
|
25
|
-
spec.required_ruby_version = '>=2.
|
25
|
+
spec.required_ruby_version = '>=2.3'
|
26
26
|
|
27
27
|
spec.add_dependency('bindata', '~>2.4.8')
|
28
28
|
spec.add_development_dependency('yard', '~>0.9.20')
|
data/lib/fit4ruby/Activity.rb
CHANGED
@@ -30,6 +30,8 @@ require 'fit4ruby/HRV'
|
|
30
30
|
require 'fit4ruby/HeartRateZones'
|
31
31
|
require 'fit4ruby/Event'
|
32
32
|
require 'fit4ruby/PersonalRecords'
|
33
|
+
require 'fit4ruby/Workout'
|
34
|
+
require 'fit4ruby/WorkoutStep'
|
33
35
|
|
34
36
|
module Fit4Ruby
|
35
37
|
|
@@ -54,6 +56,8 @@ module Fit4Ruby
|
|
54
56
|
:epo_data,
|
55
57
|
:user_profiles,
|
56
58
|
:user_data,
|
59
|
+
:workouts,
|
60
|
+
:workout_steps,
|
57
61
|
:sensor_settings,
|
58
62
|
:developer_data_ids,
|
59
63
|
:field_descriptions,
|
@@ -184,7 +188,7 @@ module Fit4Ruby
|
|
184
188
|
# sessions.
|
185
189
|
def total_distance
|
186
190
|
d = 0.0
|
187
|
-
@sessions.each { |s| d += s.total_distance }
|
191
|
+
@sessions.each { |s| d += (s.total_distance || 0) }
|
188
192
|
d
|
189
193
|
end
|
190
194
|
|
@@ -311,11 +315,21 @@ module Fit4Ruby
|
|
311
315
|
@sessions[0].sport
|
312
316
|
end
|
313
317
|
|
318
|
+
# Sets the sport type of this activity.
|
319
|
+
def sport=(sport)
|
320
|
+
@sessions[0].sport = sport
|
321
|
+
end
|
322
|
+
|
314
323
|
# Returns the sport subtype of this activity.
|
315
324
|
def sub_sport
|
316
325
|
@sessions[0].sub_sport
|
317
326
|
end
|
318
327
|
|
328
|
+
# Sets the sport subtype of this activity.
|
329
|
+
def sub_sport=(sub_sport)
|
330
|
+
@sessions[0].sub_sport = sub_sport
|
331
|
+
end
|
332
|
+
|
319
333
|
# Write the Activity data to a file.
|
320
334
|
# @param io [IO] File reference
|
321
335
|
# @param id_mapper [FitMessageIdMapper] Maps global FIT record types to
|
@@ -405,6 +419,22 @@ module Fit4Ruby
|
|
405
419
|
new_fit_data_record('user_profile', field_values)
|
406
420
|
end
|
407
421
|
|
422
|
+
# Add a new Workout to the Activity.
|
423
|
+
# @param field_values [Hash] A Hash that provides initial values for
|
424
|
+
# certain fields of the FitDataRecord.
|
425
|
+
# @return [UserProfile]
|
426
|
+
def new_workout(field_values = {})
|
427
|
+
new_fit_data_record('workout', field_values)
|
428
|
+
end
|
429
|
+
|
430
|
+
# Add a new WorkoutSet to the Activity.
|
431
|
+
# @param field_values [Hash] A Hash that provides initial values for
|
432
|
+
# certain fields of the FitDataRecord.
|
433
|
+
# @return [UserProfile]
|
434
|
+
def new_workout_set(field_values = {})
|
435
|
+
new_fit_data_record('workout_set', field_values)
|
436
|
+
end
|
437
|
+
|
408
438
|
# Add a new PhysiologicalMetrics to the Activity.
|
409
439
|
# @param field_values [Hash] A Hash that provides initial values for
|
410
440
|
# certain fields of the FitDataRecord.
|
@@ -522,6 +552,10 @@ module Fit4Ruby
|
|
522
552
|
@data_sources << (record = DataSources.new(field_values))
|
523
553
|
when 'user_data'
|
524
554
|
@user_data << (record = UserData.new(field_values))
|
555
|
+
when 'workout'
|
556
|
+
@workouts << (record = Workout.new(field_values))
|
557
|
+
when 'workout_step'
|
558
|
+
@workout_steps << (record = WorkoutStep.new(field_values))
|
525
559
|
when 'user_profile'
|
526
560
|
@user_profiles << (record = UserProfile.new(field_values))
|
527
561
|
when 'physiological_metrics'
|
@@ -615,4 +649,3 @@ module Fit4Ruby
|
|
615
649
|
end
|
616
650
|
|
617
651
|
end
|
618
|
-
|
data/lib/fit4ruby/Converters.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
#!/usr/bin/env ruby -w
|
2
|
-
# encoding: UTF-8
|
3
2
|
#
|
4
3
|
# = Converters.rb -- Fit4Ruby - FIT file processing library for Ruby
|
5
4
|
#
|
@@ -9,34 +8,47 @@
|
|
9
8
|
# it under the terms of version 2 of the GNU General Public License as
|
10
9
|
# published by the Free Software Foundation.
|
11
10
|
#
|
11
|
+
# frozen_string_literal: true
|
12
12
|
|
13
13
|
module Fit4Ruby
|
14
|
-
|
15
14
|
module Converters
|
15
|
+
FACTORS = {
|
16
|
+
'm' => { 'km' => 0.001, 'in' => 39.3701, 'ft' => 3.28084,
|
17
|
+
'mi' => 0.000621371 },
|
18
|
+
'mm' => { 'cm' => 0.1, 'in' => 0.0393701 },
|
19
|
+
'm/s' => { 'km/h' => 3.6, 'mph' => 2.23694 },
|
20
|
+
'min/km' => { 'min/mi' => 1.60934 },
|
21
|
+
'kg' => { 'lbs' => 2.20462262 },
|
22
|
+
'C' => { 'F' => 9.0 / 5.0 }
|
23
|
+
}.freeze
|
24
|
+
OFFSETS = {
|
25
|
+
'C' => { 'F' => 32 }
|
26
|
+
}.freeze
|
16
27
|
|
17
28
|
def conversion_factor(from_unit, to_unit)
|
18
|
-
factors = {
|
19
|
-
'm' => { 'km' => 0.001, 'in' => 39.3701, 'ft' => 3.28084,
|
20
|
-
'mi' => 0.000621371 },
|
21
|
-
'mm' => { 'cm' => 0.1, 'in' => 0.0393701 },
|
22
|
-
'm/s' => { 'km/h' => 3.6, 'mph' => 2.23694 },
|
23
|
-
'min/km' => { 'min/mi' => 1.60934 },
|
24
|
-
'kg' => { 'lbs' => 0.453592 }
|
25
|
-
}
|
26
29
|
return 1.0 if from_unit == to_unit
|
27
|
-
|
28
|
-
|
30
|
+
|
31
|
+
unless FACTORS.include?(from_unit)
|
32
|
+
Log.fatal 'No conversion factors defined for unit ' \
|
29
33
|
"'#{from_unit}' to '#{to_unit}'"
|
30
34
|
end
|
31
35
|
|
32
|
-
factor =
|
36
|
+
factor = FACTORS[from_unit][to_unit]
|
33
37
|
if factor.nil?
|
34
|
-
Log.fatal "No conversion factor from '#{from_unit}' to '#{to_unit}' "
|
35
|
-
|
38
|
+
Log.fatal "No conversion factor from '#{from_unit}' to '#{to_unit}' " \
|
39
|
+
'defined.'
|
36
40
|
end
|
41
|
+
|
37
42
|
factor
|
38
43
|
end
|
39
44
|
|
45
|
+
def conversion_offset(from_unit, to_unit)
|
46
|
+
return 0.0 if from_unit == to_unit || !OFFSETS.include?(from_unit) ||
|
47
|
+
!OFFSETS[from_unit].include?(to_unit)
|
48
|
+
|
49
|
+
OFFSETS[from_unit][to_unit]
|
50
|
+
end
|
51
|
+
|
40
52
|
def speedToPace(speed, distance = 1000.0)
|
41
53
|
if speed && speed > 0.01
|
42
54
|
# We only show 2 fractional digits, so make sure we round accordingly
|
@@ -89,4 +101,3 @@ module Fit4Ruby
|
|
89
101
|
end
|
90
102
|
|
91
103
|
end
|
92
|
-
|
@@ -1,30 +1,28 @@
|
|
1
1
|
#!/usr/bin/env ruby -w
|
2
|
-
# encoding: UTF-8
|
3
2
|
#
|
4
3
|
# = FitDataRecord.rb -- Fit4Ruby - FIT file processing library for Ruby
|
5
4
|
#
|
6
|
-
# Copyright (c) 2014, 2015, 2020 by Chris Schlaeger <cs@taskjuggler.org>
|
5
|
+
# Copyright (c) 2014, 2015, 2020, 2021 by Chris Schlaeger <cs@taskjuggler.org>
|
7
6
|
#
|
8
7
|
# This program is free software; you can redistribute it and/or modify
|
9
8
|
# it under the terms of version 2 of the GNU General Public License as
|
10
9
|
# published by the Free Software Foundation.
|
11
10
|
#
|
11
|
+
# frozen_string_literal: true
|
12
12
|
|
13
13
|
require 'fit4ruby/FitMessageIdMapper'
|
14
|
-
require 'fit4ruby/GlobalFitMessages
|
14
|
+
require 'fit4ruby/GlobalFitMessages'
|
15
15
|
require 'fit4ruby/BDFieldNameTranslator'
|
16
16
|
|
17
17
|
module Fit4Ruby
|
18
|
-
|
19
18
|
class FitDataRecord
|
20
|
-
|
21
19
|
include Converters
|
22
20
|
include BDFieldNameTranslator
|
23
21
|
|
24
|
-
RecordOrder = [
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
RecordOrder = ['user_data', 'user_profile', 'workout', 'workout_set',
|
23
|
+
'device_info', 'data_sources', 'event',
|
24
|
+
'record', 'lap', 'length', 'session', 'heart_rate_zones',
|
25
|
+
'personal_records']
|
28
26
|
|
29
27
|
attr_reader :message, :timestamp
|
30
28
|
|
@@ -33,7 +31,7 @@ module Fit4Ruby
|
|
33
31
|
|
34
32
|
# Create instance variables that correspond to every field of the
|
35
33
|
# corresponding FIT data record.
|
36
|
-
@message.fields_by_name.each do |name,
|
34
|
+
@message.fields_by_name.each do |name, _|
|
37
35
|
create_instance_variable(name)
|
38
36
|
end
|
39
37
|
|
@@ -51,9 +49,9 @@ module Fit4Ruby
|
|
51
49
|
end
|
52
50
|
|
53
51
|
def set(name, value)
|
54
|
-
ivar_name =
|
52
|
+
ivar_name = "@#{name}"
|
55
53
|
unless instance_variable_defined?(ivar_name)
|
56
|
-
Log.debug("Unknown FIT record field '#{name}' in global message "
|
54
|
+
Log.debug("Unknown FIT record field '#{name}' in global message " \
|
57
55
|
"#{@message.name} (#{@message.number}).")
|
58
56
|
return
|
59
57
|
end
|
@@ -62,7 +60,7 @@ module Fit4Ruby
|
|
62
60
|
|
63
61
|
def get(name)
|
64
62
|
# This is a request for a native FIT field.
|
65
|
-
ivar_name =
|
63
|
+
ivar_name = "@#{name}"
|
66
64
|
return nil unless instance_variable_defined?(ivar_name)
|
67
65
|
|
68
66
|
instance_variable_get(ivar_name)
|
@@ -82,17 +80,17 @@ module Fit4Ruby
|
|
82
80
|
end
|
83
81
|
end
|
84
82
|
|
85
|
-
value * conversion_factor(unit, to_unit)
|
83
|
+
conversion_offset(unit, to_unit) + value * conversion_factor(unit, to_unit)
|
86
84
|
end
|
87
85
|
|
88
|
-
def ==(
|
89
|
-
@message.each_field(field_values_as_hash) do |
|
90
|
-
ivar_name =
|
86
|
+
def ==(other)
|
87
|
+
@message.each_field(field_values_as_hash) do |_, field|
|
88
|
+
ivar_name = "@#{field.name}"
|
91
89
|
# Comparison of values is done in the fit file format as the accuracy
|
92
90
|
# of native formats is better and could lead to wrong results if a
|
93
91
|
# value hasn't been read back from a fit file yet.
|
94
92
|
v1 = field.native_to_fit(instance_variable_get(ivar_name))
|
95
|
-
v2 = field.native_to_fit(
|
93
|
+
v2 = field.native_to_fit(other.instance_variable_get(ivar_name))
|
96
94
|
|
97
95
|
return false unless v1 == v2
|
98
96
|
end
|
@@ -100,16 +98,15 @@ module Fit4Ruby
|
|
100
98
|
true
|
101
99
|
end
|
102
100
|
|
103
|
-
def <=>(
|
104
|
-
@timestamp ==
|
101
|
+
def <=>(other)
|
102
|
+
@timestamp == other.timestamp ?
|
105
103
|
RecordOrder.index(@message.name) <=>
|
106
|
-
RecordOrder.index(
|
107
|
-
@timestamp <=>
|
104
|
+
RecordOrder.index(other.message.name) :
|
105
|
+
@timestamp <=> other.timestamp
|
108
106
|
end
|
109
107
|
|
110
108
|
def write(io, id_mapper)
|
111
|
-
global_fit_message = @message.construct(
|
112
|
-
field_values = field_values_as_hash)
|
109
|
+
global_fit_message = @message.construct(field_values = field_values_as_hash)
|
113
110
|
|
114
111
|
# Map the global message number to the current local message number.
|
115
112
|
unless (local_message_number = id_mapper.get_local(global_fit_message))
|
@@ -134,10 +131,10 @@ module Fit4Ruby
|
|
134
131
|
|
135
132
|
# Fill the BinData::Struct object with the values from the corresponding
|
136
133
|
# instance variables.
|
137
|
-
global_fit_message.each_field(field_values) do |
|
134
|
+
global_fit_message.each_field(field_values) do |_, field|
|
138
135
|
bin_data_type = FitDefinitionFieldBase.fit_type_to_bin_data(field.type)
|
139
136
|
field_name = to_bd_field_name(field.name)
|
140
|
-
field_def = [
|
137
|
+
field_def = [bin_data_type, field_name]
|
141
138
|
|
142
139
|
iv = "@#{field.name}"
|
143
140
|
if instance_variable_defined?(iv) &&
|
@@ -147,7 +144,7 @@ module Fit4Ruby
|
|
147
144
|
# If we don't have a corresponding variable or the variable is nil
|
148
145
|
# we write the 'undefined' value instead.
|
149
146
|
value = FitDefinitionFieldBase.undefined_value(field.type)
|
150
|
-
values[field.name] = field.opts[:array] ? [
|
147
|
+
values[field.name] = field.opts[:array] ? [value] :
|
151
148
|
field.type == 'string' ? '' : value
|
152
149
|
end
|
153
150
|
|
@@ -157,17 +154,17 @@ module Fit4Ruby
|
|
157
154
|
values[field.name] += "\0"
|
158
155
|
elsif field.opts[:array]
|
159
156
|
# For Arrays we use a BinData::Array to write them.
|
160
|
-
field_def = [
|
161
|
-
|
162
|
-
|
157
|
+
field_def = [:array, field_name,
|
158
|
+
{ type: bin_data_type,
|
159
|
+
initial_length: values[field.name].size }]
|
163
160
|
end
|
164
161
|
fields << field_def
|
165
162
|
end
|
166
|
-
bd = BinData::Struct.new(:
|
163
|
+
bd = BinData::Struct.new(endian: :little, fields: fields)
|
167
164
|
|
168
165
|
# Fill the BinData::Struct object with the values from the corresponding
|
169
166
|
# instance variables.
|
170
|
-
global_fit_message.each_field(field_values) do |
|
167
|
+
global_fit_message.each_field(field_values) do |_, field|
|
171
168
|
bd[to_bd_field_name(field.name)] = values[field.name]
|
172
169
|
end
|
173
170
|
|
@@ -183,13 +180,13 @@ module Fit4Ruby
|
|
183
180
|
}
|
184
181
|
|
185
182
|
@message.each_field(field_values_as_hash) do |number, field|
|
186
|
-
ivar_name =
|
183
|
+
ivar_name = "@#{field.name}"
|
187
184
|
fit_value = field.native_to_fit(instance_variable_get(ivar_name))
|
188
185
|
unless field.is_undefined?(fit_value)
|
189
186
|
fld = {
|
190
187
|
'number' => number,
|
191
188
|
'value' => field.fit_to_native(fit_value),
|
192
|
-
#'human' => field.to_human(fit_value),
|
189
|
+
# 'human' => field.to_human(fit_value),
|
193
190
|
'type' => field.type
|
194
191
|
}
|
195
192
|
fld['unit'] = field.opts[:unit] if field.opts[:unit]
|
@@ -214,7 +211,7 @@ module Fit4Ruby
|
|
214
211
|
# set of fields. It does not contain any AltField objects.
|
215
212
|
field_values = {}
|
216
213
|
@message.fields_by_name.each_key do |name|
|
217
|
-
field_values[name] = instance_variable_get(
|
214
|
+
field_values[name] = instance_variable_get("@#{name}")
|
218
215
|
end
|
219
216
|
|
220
217
|
field_values
|
@@ -223,12 +220,9 @@ module Fit4Ruby
|
|
223
220
|
def create_instance_variable(name)
|
224
221
|
# Create a new instance variable for 'name'. We initialize it with a
|
225
222
|
# provided default value or nil.
|
226
|
-
instance_variable_set(
|
223
|
+
instance_variable_set("@#{name}", nil)
|
227
224
|
# And create an accessor method for it as well.
|
228
225
|
self.class.__send__(:attr_accessor, name)
|
229
226
|
end
|
230
|
-
|
231
227
|
end
|
232
|
-
|
233
228
|
end
|
234
|
-
|
@@ -3,7 +3,7 @@
|
|
3
3
|
#
|
4
4
|
# = GlobalFitDictionaries.rb -- Fit4Ruby - FIT file processing library for Ruby
|
5
5
|
#
|
6
|
-
# Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
|
6
|
+
# Copyright (c) 2014, 2021 by Chris Schlaeger <cs@taskjuggler.org>
|
7
7
|
#
|
8
8
|
# This program is free software; you can redistribute it and/or modify
|
9
9
|
# it under the terms of version 2 of the GNU General Public License as
|
@@ -16,6 +16,10 @@ module Fit4Ruby
|
|
16
16
|
|
17
17
|
GlobalFitDictionaries = GlobalFitDictList.new do
|
18
18
|
|
19
|
+
dict 'activity'
|
20
|
+
entry 0, 'manual'
|
21
|
+
entry 1, 'auto_multi_sport'
|
22
|
+
|
19
23
|
dict 'activity_type'
|
20
24
|
entry 0, 'generic'
|
21
25
|
entry 1, 'running'
|
@@ -23,50 +27,8 @@ module Fit4Ruby
|
|
23
27
|
entry 3, 'transition'
|
24
28
|
entry 4, 'fitness_equipment'
|
25
29
|
entry 5, 'swimming'
|
26
|
-
entry 6, '
|
27
|
-
entry
|
28
|
-
entry 8, 'tennis'
|
29
|
-
entry 9, 'american_football'
|
30
|
-
entry 10, 'training'
|
31
|
-
entry 11, 'walking'
|
32
|
-
entry 12, 'cross_country_skiing'
|
33
|
-
entry 13, 'alpine_skiing'
|
34
|
-
entry 14, 'snowboarding'
|
35
|
-
entry 15, 'rowing'
|
36
|
-
entry 16, 'mountaineering'
|
37
|
-
entry 17, 'hiking'
|
38
|
-
entry 18, 'multisport'
|
39
|
-
entry 19, 'paddling'
|
40
|
-
entry 20, 'flying'
|
41
|
-
entry 21, 'e_biking'
|
42
|
-
entry 22, 'motorcycling'
|
43
|
-
entry 23, 'boating'
|
44
|
-
entry 24, 'driving'
|
45
|
-
entry 25, 'golf'
|
46
|
-
entry 26, 'hang_gliding'
|
47
|
-
entry 27, 'horseback_riding'
|
48
|
-
entry 28, 'hunting'
|
49
|
-
entry 29, 'fishing'
|
50
|
-
entry 30, 'inline_skating'
|
51
|
-
entry 31, 'rock_climbing'
|
52
|
-
entry 32, 'sailing'
|
53
|
-
entry 33, 'ice_skating'
|
54
|
-
entry 34, 'sky_diving'
|
55
|
-
entry 35, 'snowshoeing'
|
56
|
-
entry 36, 'snowmobiling'
|
57
|
-
entry 37, 'stand_up_paddleboarding'
|
58
|
-
entry 38, 'surfing'
|
59
|
-
entry 39, 'wakeboarding'
|
60
|
-
entry 40, 'water_skiing'
|
61
|
-
entry 41, 'kayaking'
|
62
|
-
entry 42, 'rafting'
|
63
|
-
entry 43, 'windsurfing'
|
64
|
-
entry 44, 'kitesurfing'
|
65
|
-
entry 45, 'tactical'
|
66
|
-
entry 46, 'jumpmaster'
|
67
|
-
entry 47, 'boxing'
|
68
|
-
entry 48, 'floor_climbing'
|
69
|
-
entry 53, 'diving'
|
30
|
+
entry 6, 'walking'
|
31
|
+
entry 8, 'sedentary'
|
70
32
|
entry 254, 'all'
|
71
33
|
|
72
34
|
dict 'activity_level'
|
@@ -714,6 +676,9 @@ module Fit4Ruby
|
|
714
676
|
entry 1, 'rest'
|
715
677
|
entry 2, 'warmup'
|
716
678
|
entry 3, 'cooldown'
|
679
|
+
entry 4, 'recovery'
|
680
|
+
entry 5, 'interval'
|
681
|
+
entry 6, 'other'
|
717
682
|
|
718
683
|
dict 'hr_zone_calc'
|
719
684
|
entry 0, 'custom'
|
@@ -933,6 +898,36 @@ module Fit4Ruby
|
|
933
898
|
entry 17, 'hiking'
|
934
899
|
entry 18, 'multisport'
|
935
900
|
entry 19, 'paddling'
|
901
|
+
entry 20, 'flying'
|
902
|
+
entry 21, 'e_biking'
|
903
|
+
entry 22, 'motorcycling'
|
904
|
+
entry 23, 'boating'
|
905
|
+
entry 24, 'driving'
|
906
|
+
entry 25, 'golf'
|
907
|
+
entry 26, 'hang_gliding'
|
908
|
+
entry 27, 'horseback_riding'
|
909
|
+
entry 28, 'hunting'
|
910
|
+
entry 29, 'fishing'
|
911
|
+
entry 30, 'inline_skating'
|
912
|
+
entry 31, 'rock_climbing'
|
913
|
+
entry 32, 'sailing'
|
914
|
+
entry 33, 'ice_skating'
|
915
|
+
entry 34, 'sky_diving'
|
916
|
+
entry 35, 'snowshoeing'
|
917
|
+
entry 36, 'snowmobiling'
|
918
|
+
entry 37, 'stand_up_paddleboarding'
|
919
|
+
entry 38, 'surfing'
|
920
|
+
entry 39, 'wakeboarding'
|
921
|
+
entry 40, 'water_skiing'
|
922
|
+
entry 41, 'kayaking'
|
923
|
+
entry 42, 'rafting'
|
924
|
+
entry 43, 'windsurfing'
|
925
|
+
entry 44, 'kitesurfing'
|
926
|
+
entry 45, 'tactical'
|
927
|
+
entry 46, 'jumpmaster'
|
928
|
+
entry 47, 'boxing'
|
929
|
+
entry 48, 'floor_climbing'
|
930
|
+
entry 53, 'diving'
|
936
931
|
entry 254, 'all'
|
937
932
|
|
938
933
|
dict 'swim_stroke'
|
@@ -1023,6 +1018,79 @@ module Fit4Ruby
|
|
1023
1018
|
entry 2, 'maintaining'
|
1024
1019
|
entry 3, 'up'
|
1025
1020
|
|
1021
|
+
dict 'wkt_step_duration'
|
1022
|
+
entry 0, 'time'
|
1023
|
+
entry 1, 'distance'
|
1024
|
+
entry 2, 'hr_less_than'
|
1025
|
+
entry 3, 'hr_greater_than'
|
1026
|
+
entry 4, 'calories'
|
1027
|
+
entry 5, 'open'
|
1028
|
+
entry 6, 'repeat_until_steps_cmplt'
|
1029
|
+
entry 7, 'repeat_until_time'
|
1030
|
+
entry 8, 'repeat_until_distance'
|
1031
|
+
entry 9, 'repeat_until_calories'
|
1032
|
+
entry 10, 'repeat_until_hr_less_than'
|
1033
|
+
entry 11, 'repeat_until_hr_greater_than'
|
1034
|
+
entry 12, 'repeat_until_power_less_than'
|
1035
|
+
entry 13, 'repeat_until_power_greater_than'
|
1036
|
+
entry 14, 'power_less_than'
|
1037
|
+
entry 15, 'power_greater_than'
|
1038
|
+
entry 16, 'training_peaks_tss'
|
1039
|
+
entry 17, 'repeat_until_power_last_lap_less_than'
|
1040
|
+
entry 18, 'repeat_until_max_power_last_lap_less_than'
|
1041
|
+
entry 19, 'power_3s_less_than'
|
1042
|
+
entry 20, 'power_10s_less_than'
|
1043
|
+
entry 21, 'power_30s_less_than'
|
1044
|
+
entry 22, 'power_3s_greater_than'
|
1045
|
+
entry 23, 'power_10s_greater_than'
|
1046
|
+
entry 24, 'power_30s_greater_than'
|
1047
|
+
entry 25, 'power_lap_less_than'
|
1048
|
+
entry 26, 'power_lap_greater_than'
|
1049
|
+
entry 27, 'repeat_until_training_peaks_tss'
|
1050
|
+
entry 28, 'repetition_time'
|
1051
|
+
entry 29, 'reps'
|
1052
|
+
entry 31, 'time_only'
|
1053
|
+
|
1054
|
+
dict 'wkt_step_target'
|
1055
|
+
entry 0, 'speed'
|
1056
|
+
entry 1, 'heart_rate'
|
1057
|
+
entry 2, 'open'
|
1058
|
+
entry 3, 'cadence'
|
1059
|
+
entry 4, 'power'
|
1060
|
+
entry 5, 'grade'
|
1061
|
+
entry 6, 'resistance'
|
1062
|
+
entry 7, 'power_3s'
|
1063
|
+
entry 8, 'power_10s'
|
1064
|
+
entry 9, 'power_30s'
|
1065
|
+
entry 10, 'power_lap'
|
1066
|
+
entry 11, 'swim_stroke'
|
1067
|
+
entry 12, 'speed_lap'
|
1068
|
+
entry 13, 'heart_rate_lap'
|
1069
|
+
|
1070
|
+
dict 'workout_capabilities'
|
1071
|
+
entry 0x1, 'interval'
|
1072
|
+
entry 0x2, 'custom'
|
1073
|
+
entry 0x4, 'fitness_equipment'
|
1074
|
+
entry 0x8, 'firstbeat'
|
1075
|
+
entry 0x10, 'new_leaf'
|
1076
|
+
entry 0x20, 'tcx'
|
1077
|
+
entry 0x80, 'speed'
|
1078
|
+
entry 0x100, 'heart_rate'
|
1079
|
+
entry 0x200, 'distance'
|
1080
|
+
entry 0x400, 'cadence'
|
1081
|
+
entry 0x800, 'power'
|
1082
|
+
entry 0x1000, 'grade'
|
1083
|
+
entry 0x2000, 'resistance'
|
1084
|
+
entry 0x4000, 'protected'
|
1085
|
+
|
1086
|
+
dict 'workout_equipment'
|
1087
|
+
entry 0, 'none'
|
1088
|
+
entry 1, 'swim_fins'
|
1089
|
+
entry 2, 'swim_kickboard'
|
1090
|
+
entry 3, 'swim_paddles'
|
1091
|
+
entry 4, 'swim_pull_buoy'
|
1092
|
+
entry 5, 'swim_snorkel'
|
1093
|
+
|
1026
1094
|
end
|
1027
1095
|
|
1028
1096
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
#
|
4
4
|
# = GlobalFitMessages.rb -- Fit4Ruby - FIT file processing library for Ruby
|
5
5
|
#
|
6
|
-
# Copyright (c) 2014, 2015, 2020 by Chris Schlaeger <cs@taskjuggler.org>
|
6
|
+
# Copyright (c) 2014, 2015, 2020, 2021 by Chris Schlaeger <cs@taskjuggler.org>
|
7
7
|
#
|
8
8
|
# This program is free software; you can redistribute it and/or modify
|
9
9
|
# it under the terms of version 2 of the GNU General Public License as
|
@@ -461,19 +461,23 @@ module Fit4Ruby
|
|
461
461
|
field 169, 'uint16', 'undocumented_field_169'
|
462
462
|
field 170, 'uint16', 'undocumented_field_170'
|
463
463
|
field 177, 'uint16', 'undocumented_field_177'
|
464
|
-
field 178, 'uint16', '
|
464
|
+
field 178, 'uint16', 'est_sweat_loss', :unit => 'ml' # guessed
|
465
465
|
field 179, 'uint16', 'undocumented_field_179'
|
466
466
|
field 180, 'uint16', 'undocumented_field_180'
|
467
|
-
field 181, 'float32', '
|
468
|
-
field
|
467
|
+
field 181, 'float32', 'total_grit', :unit => 'kGrit'
|
468
|
+
field 182, 'float32', 'total_flow', :unit => 'Flow'
|
469
|
+
field 183, 'uint16', 'jump_count'
|
469
470
|
field 184, 'enum', 'undocumented_field_184'
|
470
471
|
field 185, 'uint8', 'undocumented_field_185'
|
471
|
-
field
|
472
|
+
field 186, 'float32', 'avg_grit', :unit => 'kGrit'
|
473
|
+
field 187, 'float32', 'avg_flow', :unit => 'Flow'
|
472
474
|
field 188, 'enum', 'undocumented_field_188'
|
473
475
|
field 189, 'uint16', 'undocumented_field_189'
|
474
476
|
field 190, 'uint16', 'undocumented_field_190'
|
475
477
|
field 194, 'uint8', 'undocumented_field_194'
|
476
478
|
field 195, 'uint8', 'undocumented_field_195'
|
479
|
+
field 199, 'uint8', 'total_fractional_ascent', :scale => 100, :unit => 'm'
|
480
|
+
field 200, 'uint8', 'total_fractional_descent', :scale => 100, :unit => 'm'
|
477
481
|
field 253, 'uint32', 'timestamp', :type => 'date_time'
|
478
482
|
field 254, 'uint16', 'message_index'
|
479
483
|
|
@@ -638,7 +642,7 @@ module Fit4Ruby
|
|
638
642
|
field 83, 'uint16', 'vertical_ratio', :scale => 100, :unit => '%' # guessed
|
639
643
|
field 84, 'uint16', 'gct_balance', :scale => 100, :unit => '%' # guessed
|
640
644
|
field 85, 'uint16', 'stride_length', :scale => 10000, :unit => 'm' # guessed
|
641
|
-
field 87, 'uint16', '
|
645
|
+
field 87, 'uint16', 'stroke_distance', :scale => 100, :unit => 'm'
|
642
646
|
field 88, 'uint16', 'undefined_value_88' # first seen on F3HR FW3.60
|
643
647
|
field 90, 'sint8', 'performance_condition' # guessed
|
644
648
|
field 100, 'sint32', 'undocumented_field_100'
|
@@ -745,6 +749,48 @@ module Fit4Ruby
|
|
745
749
|
# counter.
|
746
750
|
field 2, 'byte', 'undocumented_field_2', :array => true
|
747
751
|
|
752
|
+
message 26, 'workout'
|
753
|
+
field 4, 'enum', 'sport', :dict => 'sport'
|
754
|
+
field 5, 'uint32z', 'capabilities', :dict => 'workout_capabilities'
|
755
|
+
field 6, 'uint16', 'num_valid_step'
|
756
|
+
field 8, 'string', 'wkt_name'
|
757
|
+
field 11, 'enum', 'sub_sport', :dict => 'sub_sport'
|
758
|
+
field 14, 'uint16', 'pool_length', :scale => 100, :unit => 'm'
|
759
|
+
field 15, 'enum', 'pool_length_unit'
|
760
|
+
|
761
|
+
message 27, 'workout_step'
|
762
|
+
field 0, 'string', 'wkt_step_name'
|
763
|
+
field 1, 'enum', 'duration_type', :dict => 'wkt_step_duration'
|
764
|
+
alt_field 2, 'duration_type' do
|
765
|
+
field :default, 'uint32', 'duration_value'
|
766
|
+
field 'distance', 'uint32', 'duration_distance', :scale => 100, :unit => 'm'
|
767
|
+
field 'time', 'uint32', 'duration_time', :scale => 1000, :unit => 's'
|
768
|
+
field 'repeat_until_steps_cmplt', 'uint32', 'duration_reps'
|
769
|
+
end
|
770
|
+
field 3, 'enum', 'target_type', :dict => 'wkt_step_target'
|
771
|
+
alt_field 4, 'target_type' do
|
772
|
+
field :default, 'uint32', 'target_value'
|
773
|
+
field 'speed', 'uint32', 'target_speed_zone'
|
774
|
+
field 'cadence', 'uint32', 'target_cadence_zone'
|
775
|
+
field 'power', 'uint32', 'target_power_zone'
|
776
|
+
end
|
777
|
+
alt_field 5, 'target_type' do
|
778
|
+
field :default, 'uint32', 'custom_target_value_low'
|
779
|
+
field 'speed', 'uint32', 'custom_target_speed_low', :scale => 1000, :unit => 'm/s'
|
780
|
+
end
|
781
|
+
alt_field 6, 'target_type' do
|
782
|
+
field :default, 'uint32', 'custom_target_value_high'
|
783
|
+
field 'speed', 'uint32', 'custom_target_speed_high', :scale => 1000, :unit => 'm/s'
|
784
|
+
end
|
785
|
+
field 7, 'enum', 'intensity', :dict => 'intensity'
|
786
|
+
field 8, 'string', 'notes'
|
787
|
+
field 9, 'enum', 'equipment', :dict => 'workout_equipment'
|
788
|
+
field 10, 'uint16', 'exercise_category'
|
789
|
+
field 11, 'uint16', 'exercise_name'
|
790
|
+
field 12, 'uint16', 'exercise_weight', :scale => 100, :unit => 'kg'
|
791
|
+
field 13, 'uint16', 'weight_display_unit'
|
792
|
+
field 254, 'uint16', 'message_index'
|
793
|
+
|
748
794
|
# Message 29 is just a guess. It's not officially documented.
|
749
795
|
# Found in LCTNS.FIT on Fenix 3
|
750
796
|
message 29, 'location'
|
@@ -771,7 +817,7 @@ module Fit4Ruby
|
|
771
817
|
message 34, 'activity'
|
772
818
|
field 0, 'uint32', 'total_timer_time', :type => 'duration', :scale => 1000
|
773
819
|
field 1, 'uint16', 'num_sessions'
|
774
|
-
field 2, 'enum', 'type', :dict => '
|
820
|
+
field 2, 'enum', 'type', :dict => 'activity'
|
775
821
|
field 3, 'enum', 'event', :dict => 'event'
|
776
822
|
field 4, 'enum', 'event_type', :dict => 'event_type'
|
777
823
|
field 5, 'uint32', 'local_timestamp', :type => 'date_time'
|
@@ -1069,14 +1115,19 @@ module Fit4Ruby
|
|
1069
1115
|
field 73, 'uint16z', 'undocumented_field_73'
|
1070
1116
|
field 254, 'uint16', 'message_index'
|
1071
1117
|
|
1072
|
-
|
1073
|
-
|
1074
|
-
field
|
1075
|
-
field
|
1118
|
+
message 160, 'gps_metadata'
|
1119
|
+
field 0, 'uint16', 'timestamp_ms'
|
1120
|
+
field 1, 'sint32', 'position_lat'
|
1121
|
+
field 2, 'sint32', 'position_long'
|
1122
|
+
field 3, 'uint32', 'enhanced_altitude', :scale => 5, :offset => 500, :unit => 'm'
|
1123
|
+
field 4, 'uint32', 'enhanced_speed', :unit => 'm/s', :scale => 1000
|
1124
|
+
field 5, 'uint16', 'heading', :unit => 'degrees', :scale => 100
|
1125
|
+
field 6, 'uint32', 'utc_timestamp', :type => 'date_time'
|
1126
|
+
field 7, 'sint16', 'velocity', :array => true, :scale => 100, :unit => 'm/s'
|
1127
|
+
field 253, 'uint32', 'timestamp', :type => 'date_time'
|
1076
1128
|
|
1077
|
-
|
1078
|
-
|
1079
|
-
field 0, 'enum', 'undocumented_field_0'
|
1129
|
+
message 188, 'ohr_settings'
|
1130
|
+
field 0, 'enum', 'switch'
|
1080
1131
|
field 253, 'uint32', 'timestamp', :type => 'date_time'
|
1081
1132
|
|
1082
1133
|
message 206, 'field_description'
|
@@ -1217,6 +1268,24 @@ module Fit4Ruby
|
|
1217
1268
|
field 252, 'uint8', 'undocumented_field_252'
|
1218
1269
|
field 253, 'uint32', 'timestamp', :type => 'date_time'
|
1219
1270
|
|
1271
|
+
# Not part of the official ANT SDK doc.
|
1272
|
+
message 312, 'undocumented_312'
|
1273
|
+
field 0, 'enum', 'undocumented_field_0'
|
1274
|
+
field 9, 'uint32', 'interval_start', :type => 'date_time'
|
1275
|
+
field 15, 'uint8', 'min_heart_rate', :unit => 'bpm'
|
1276
|
+
field 16, 'uint8', 'max_heart_rate', :unit => 'bpm'
|
1277
|
+
field 21, 'sint32', 'position_lat', :type => 'coordinate'
|
1278
|
+
field 22, 'sint32', 'position_long', :type => 'coordinate'
|
1279
|
+
field 27, 'uint32', 'interval_end', :type => 'date_time'
|
1280
|
+
field 32, 'sint8', 'avg_temperature', :unit => 'C'
|
1281
|
+
field 33, 'sint8', 'max_temperature', :unit => 'C'
|
1282
|
+
field 34, 'sint8', 'min_temperature', :unit => 'C'
|
1283
|
+
field 37, 'uint16', 'undocumented_field_37'
|
1284
|
+
field 38, 'uint16', 'undocumented_field_38'
|
1285
|
+
field 39, 'uint16', 'undocumented_field_39'
|
1286
|
+
field 253, 'uint32', 'timestamp', :type => 'date_time'
|
1287
|
+
field 254, 'uint16', 'message_index'
|
1288
|
+
|
1220
1289
|
# Not part of the official ANT SDK doc.
|
1221
1290
|
message 325, 'undocumented_325'
|
1222
1291
|
field 0, 'uint8', 'undocumented_field_0'
|
@@ -1259,4 +1328,3 @@ module Fit4Ruby
|
|
1259
1328
|
end
|
1260
1329
|
|
1261
1330
|
end
|
1262
|
-
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# = Workout.rb -- Fit4Ruby - FIT file processing library for Ruby
|
5
|
+
#
|
6
|
+
# Copyright (c) 2021 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
|
+
|
15
|
+
module Fit4Ruby
|
16
|
+
|
17
|
+
class Workout < FitDataRecord
|
18
|
+
|
19
|
+
def initialize(field_values = {})
|
20
|
+
super('workout')
|
21
|
+
set_field_values(field_values)
|
22
|
+
end
|
23
|
+
|
24
|
+
def check(index)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# = WorkoutStep.rb -- Fit4Ruby - FIT file processing library for Ruby
|
5
|
+
#
|
6
|
+
# Copyright (c) 2021 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
|
+
|
15
|
+
module Fit4Ruby
|
16
|
+
|
17
|
+
class WorkoutStep < FitDataRecord
|
18
|
+
|
19
|
+
def initialize(field_values = {})
|
20
|
+
super('workout_step')
|
21
|
+
set_field_values(field_values)
|
22
|
+
end
|
23
|
+
|
24
|
+
def check(index)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
|
data/lib/fit4ruby/version.rb
CHANGED
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.11.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: 2023-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bindata
|
@@ -164,6 +164,8 @@ files:
|
|
164
164
|
- lib/fit4ruby/TrainingStatus.rb
|
165
165
|
- lib/fit4ruby/UserData.rb
|
166
166
|
- lib/fit4ruby/UserProfile.rb
|
167
|
+
- lib/fit4ruby/Workout.rb
|
168
|
+
- lib/fit4ruby/WorkoutStep.rb
|
167
169
|
- lib/fit4ruby/version.rb
|
168
170
|
- spec/FileNameCoder_spec.rb
|
169
171
|
- spec/FitFile_spec.rb
|
@@ -184,14 +186,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
184
186
|
requirements:
|
185
187
|
- - ">="
|
186
188
|
- !ruby/object:Gem::Version
|
187
|
-
version: '2.
|
189
|
+
version: '2.3'
|
188
190
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
189
191
|
requirements:
|
190
192
|
- - ">="
|
191
193
|
- !ruby/object:Gem::Version
|
192
194
|
version: '0'
|
193
195
|
requirements: []
|
194
|
-
rubygems_version: 3.
|
196
|
+
rubygems_version: 3.4.10
|
195
197
|
signing_key:
|
196
198
|
specification_version: 4
|
197
199
|
summary: Library to read and write GARMIN FIT files.
|