fit4ruby 3.9.0 → 3.11.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 +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.
|