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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f0a74c755c07cbbcfd9b17b9efeb16a62696fd9076c9ece178e00e51b3ce075
4
- data.tar.gz: 81ee48cea068828a6ad08c5f4f274270ec96179159e585ecc9068eccbf1be3a4
3
+ metadata.gz: 550fffeb71313287a1a1037974608c23b738da5a34c6aaca39374fea562b7426
4
+ data.tar.gz: 923417ab9520777208f4bd830696d7012c68b8ad2e7d39572749bad42301d560
5
5
  SHA512:
6
- metadata.gz: 0f140497b1f269075e912da5988238db3a279ef5baf20e4ce29f3b960307c3b87a4ada116283f17f5965a7e0e25e9b3e5bcdce7306b14ae49cb16d837692b239
7
- data.tar.gz: 829a3ff7cee37f26218915d8370a0dd44fe6c24152c634f073fb0d25a543c3e50783188fe81f6d5cbbb00af42974eba1aed51f59ee25a108718773b7a65f8ad8
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.0'
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')
@@ -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
-
@@ -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
- unless factors.include?(from_unit)
28
- Log.fatal "No conversion factors defined for unit " +
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 = factors[from_unit][to_unit]
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
- "defined."
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.rb'
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 = [ 'user_data', 'user_profile',
25
- 'device_info', 'data_sources', 'event',
26
- 'record', 'lap', 'length', 'session', 'heart_rate_zones',
27
- 'personal_records' ]
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, field|
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 = '@' + 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 = '@' + 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 ==(fdr)
89
- @message.each_field(field_values_as_hash) do |number, field|
90
- ivar_name = '@' + field.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(fdr.instance_variable_get(ivar_name))
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 <=>(fdr)
104
- @timestamp == fdr.timestamp ?
101
+ def <=>(other)
102
+ @timestamp == other.timestamp ?
105
103
  RecordOrder.index(@message.name) <=>
106
- RecordOrder.index(fdr.message.name) :
107
- @timestamp <=> fdr.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 |number, field|
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 = [ bin_data_type, field_name ]
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] ? [ value ] :
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 = [ :array, field_name,
161
- { :type => bin_data_type,
162
- :initial_length => values[field.name].size } ]
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(:endian => :little, :fields => fields)
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 |number, field|
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 = '@' + field.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('@' + name)
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('@' + name, nil)
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, 'basketball'
27
- entry 7, 'soccer'
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', 'undocumented_field_178'
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', 'undocumented_field_181'
468
- field 183, 'uint16', 'undocumented_field_183'
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 187, 'float32', 'undocumented_field_187'
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', 'undefined_value_87' # first seen on F3 FW6.80
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 => 'activity_type'
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
- # Not part of the official ANT SDK doc.
1073
- message 160, 'undocumented_160'
1074
- field 3, 'uint32', 'undocumented_field_3'
1075
- field 4, 'uint32', 'undocumented_field_4'
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
- # Not part of the official ANT SDK doc.
1078
- message 188, 'undocumented_188'
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
+
@@ -1,4 +1,4 @@
1
1
  module Fit4Ruby
2
2
  # The version number of the library.
3
- VERSION = '3.9.0'
3
+ VERSION = '3.11.0'
4
4
  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.9.0
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: 2021-11-17 00:00:00.000000000 Z
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.0'
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.2.22
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.