fit4ruby 3.1.0 → 3.2.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
  SHA1:
3
- metadata.gz: d789b2e373decc4dfff48739b65a320c66da88fd
4
- data.tar.gz: 1a40f4aac55b45f66cb082b6ffef4ca6e3c3ed9e
3
+ metadata.gz: 247b4e5fd81ffc3c5e12bc1d3235196126fdb8cc
4
+ data.tar.gz: b493e5b073e63d977ed28edc3600dac73519d0b6
5
5
  SHA512:
6
- metadata.gz: 2ec0e96be6dd2d0cf44b03a5ac41197a693d4a4b8861063a55f7d37e98252656f380d8cb57bb4d77476d7f805fdab1668c598f5ec81208e7225102e151b12e8a
7
- data.tar.gz: d92c14c4af7c98c043d3a675bb8eefa741fe30b18a05d4606358cd69a49c05b4564355b1c213dac9c9196d1b1c2f0bf5122bca7808652db310fccf1c59fe92f1
6
+ metadata.gz: 88b2fe75bdf8a1bfb4a6f3d4892db4253f942a3a251118fc054f4671f9f3927960552fe9005334da6f884e95990babae029071edbf287740efaff2450748824b
7
+ data.tar.gz: f8aa4152a1d37f682d0ca526045d10a19628ba79bad41eebbf3b3e3e963fcb971fc82d38fef8756b2bfa50eaefd3eea80388c849cb1bc0bf34aa79d64754e7eb
@@ -264,7 +264,7 @@ module Fit4Ruby
264
264
  # Then check the user_data entries for a metmax entry. METmax * 3.5
265
265
  # is same value as VO2max.
266
266
  @user_data.each do |u|
267
- return ((u.metmax * 1000.0) * 3.5) / 1024.0 if u.metmax
267
+ return u.metmax * 3.5 if u.metmax
268
268
  end
269
269
 
270
270
  nil
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = FieldDescription.rb -- Fit4Ruby - FIT file processing library for Ruby
5
5
  #
6
- # Copyright (c) 2017, 2018 by Chris Schlaeger <cs@taskjuggler.org>
6
+ # Copyright (c) 2017, 2018, 2019 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
@@ -32,17 +32,20 @@ module Fit4Ruby
32
32
  unless (gfm = GlobalFitMessages[@native_mesg_num])
33
33
  Log.error "Developer field description references unknown global " +
34
34
  "message number #{@native_mesg_num}"
35
+ return
35
36
  end
36
37
 
37
38
  if @developer_data_index >=
38
39
  fit_entity.top_level_record.developer_data_ids.size
39
40
  Log.error "Developer data index #{@developer_data_index} is too large"
41
+ return
40
42
  end
41
43
 
42
44
  msg = messages[@native_mesg_num] ||
43
45
  messages.message(@native_mesg_num, gfm.name)
44
46
  unless (@fit_base_type_id & 0x7F) < FIT_TYPE_DEFS.size
45
47
  Log.error "fit_base_type_id #{@fit_base_type_id} is too large"
48
+ return
46
49
  end
47
50
  options = {}
48
51
  options[:scale] = @scale if @scale
@@ -58,4 +61,3 @@ module Fit4Ruby
58
61
 
59
62
  end
60
63
 
61
-
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = FitDeveloperDataFieldDefinition.rb -- Fit4Ruby - FIT file processing library for Ruby
5
5
  #
6
- # Copyright (c) 2017, 2018 by Chris Schlaeger <cs@taskjuggler.org>
6
+ # Copyright (c) 2017, 2018, 2019 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
@@ -41,22 +41,56 @@ module Fit4Ruby
41
41
  size_in_bytes
42
42
  end
43
43
 
44
- private
44
+ def undefined_value
45
+ FIT_TYPE_DEFS[checked_base_type_number][2]
46
+ end
45
47
 
46
48
  def find_field_definition
49
+ return @field_definition if @field_definition
50
+
47
51
  tlr = parent.parent.fit_entity.top_level_record
48
- field = tlr.field_descriptions.find do |fd|
52
+ @field_definition = tlr.field_descriptions.find do |fd|
49
53
  fd.field_definition_number == field_number.snapshot &&
50
54
  fd.developer_data_index == developer_data_index.snapshot
51
55
  end
52
- unless field
56
+ unless @field_definition
53
57
  Log.error "Unknown developer field #{field_number.snapshot} " +
54
58
  "for developer #{developer_data_index.snapshot}"
59
+ return nil
55
60
  end
56
61
 
57
- field
62
+ @field_definition
63
+ end
64
+
65
+ def to_s(value)
66
+ return '' if value.nil?
67
+
68
+ if (field_definition = find_field_definition)
69
+ "#{value} #{find_field_definition.units}"
70
+ else
71
+ if value.kind_of?(Array)
72
+ s = '[ '
73
+ value.each do |v|
74
+ v /= @field_def.scale.to_f if @field_def.scale
75
+ v -= @fielid_def.offset if @field_def.offset
76
+ s << to_s(v) + ' '
77
+ end
78
+ s + ']'
79
+
80
+ return s
81
+ else
82
+ field_number = field_definition_number.snapshot
83
+
84
+ value /= @field_def.scale.to_f if @field_def.scale
85
+ value -= @fielid_def.offset if @field_def.offset
86
+
87
+ return value.to_s
88
+ end
89
+ end
58
90
  end
59
91
 
92
+ private
93
+
60
94
  def checked_base_type_number
61
95
  field = find_field_definition
62
96
  base_type_number = field.fit_base_type_id & 0x7F
@@ -13,6 +13,7 @@
13
13
  require 'fit4ruby/Activity'
14
14
  require 'fit4ruby/Monitoring_B'
15
15
  require 'fit4ruby/GlobalFitMessage'
16
+ require 'fit4ruby/Metrics'
16
17
 
17
18
  module Fit4Ruby
18
19
 
@@ -49,6 +50,9 @@ module Fit4Ruby
49
50
  when 32, 'monitoring_b'
50
51
  @top_level_record = Monitoring_B.new
51
52
  @type = 'monitoring_b'
53
+ when 44, 'metrics'
54
+ @top_level_record = Metrics.new
55
+ @type = 'metrics'
52
56
  else
53
57
  Log.error "Unsupported FIT file type #{type}"
54
58
  return nil
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = FitMessageRecord.rb -- Fit4Ruby - FIT file processing library for Ruby
5
5
  #
6
- # Copyright (c) 2014, 2015 by Chris Schlaeger <cs@taskjuggler.org>
6
+ # Copyright (c) 2014, 2015, 2018, 2019 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
@@ -98,6 +98,39 @@ module Fit4Ruby
98
98
  end
99
99
  end
100
100
 
101
+ @definition.developer_fields.each do |field|
102
+ # Find the corresponding field description for the given developer and
103
+ # field number.
104
+ field_number = field.field_number.snapshot
105
+
106
+ unless (field_description = field.find_field_definition)
107
+ Log.error "There is no field definition for developer " +
108
+ "#{field.developer_data_index} field #{field_number}"
109
+ next
110
+ end
111
+
112
+ field_name = field_description.field_name
113
+ units = field_description.units
114
+ type = field.type
115
+ native_message_number = field_description.native_mesg_num
116
+ native_field_number = field_description.native_field_num
117
+
118
+ value = @message_record[field.name].snapshot
119
+ value = nil if value == field.undefined_value
120
+
121
+ if filter && fields_dump &&
122
+ (filter.field_names.nil? ||
123
+ filter.field_names.include?(field_name)) &&
124
+ !(((value.respond_to?('count') &&
125
+ (value.count(field.undefined_value) == value.length)) ||
126
+ value == field.undefined_value) && filter.ignore_undef)
127
+ fields_dump << DumpedField.new(
128
+ native_message_number,
129
+ 256 * (1 + field.developer_data_index) + field_number,
130
+ field_name, type, field.to_s(value))
131
+ end
132
+ end
133
+
101
134
  if @name == 'field_description'
102
135
  obj.create_global_definition(fit_entity)
103
136
  end
@@ -75,6 +75,10 @@ module Fit4Ruby
75
75
  entry 4, 'low'
76
76
  entry 5, 'critical'
77
77
 
78
+ dict 'date_mode'
79
+ entry 0, 'day_month'
80
+ entry 1, 'month_day'
81
+
78
82
  dict 'body_location'
79
83
  entry 0, 'left_leg'
80
84
  entry 1, 'left_calf'
@@ -245,6 +249,7 @@ module Fit4Ruby
245
249
  entry 45, 'elev_high_alert'
246
250
  entry 46, 'elev_low_alert'
247
251
  entry 47, 'comm_timeout'
252
+ entry 48, 'functional_threshold_power' # guess (in Watt)
248
253
  entry 49, 'lactate_threshold_heart_rate' # guess (in BPM)
249
254
  entry 50, 'lactate_threshold_speed' # guess (in m/s)
250
255
 
@@ -276,6 +281,10 @@ module Fit4Ruby
276
281
  entry 20, 'activity_summary'
277
282
  entry 28, 'monitoring_daily'
278
283
  entry 32, 'monitoring_b'
284
+ entry 34, 'segment'
285
+ entry 35, 'segment_list'
286
+ entry 40, 'exd_configuration'
287
+ entry 44, 'metrics'
279
288
 
280
289
  dict 'fitness_equipment_state'
281
290
  entry 0, 'ready'
@@ -344,6 +353,8 @@ module Fit4Ruby
344
353
  entry 2593, 'running_dynamics_pod'
345
354
  entry 2691, 'fr935'
346
355
  entry 2697, 'fenix5'
356
+ entry 2957, 'fenix5_gps_galileo' # Just a guess
357
+ entry 3111, 'fenix5x_plus'
347
358
  entry 10007, 'sdm4'
348
359
  entry 20119, 'training_center'
349
360
  entry 65532, 'android_antplus_plugin'
@@ -651,6 +662,22 @@ module Fit4Ruby
651
662
  entry 59, 'obstacle '
652
663
  entry 254, 'all'
653
664
 
665
+ dict 'training_status'
666
+ entry 0, 'overreaching'
667
+ entry 1, 'detraining'
668
+ entry 2, 'unproductive'
669
+ entry 3, 'recovery'
670
+ entry 4, 'maintaining'
671
+ entry 5, 'productive'
672
+ entry 6, 'peaking'
673
+ entry 7, 'productive'
674
+
675
+ dict 'training_status_trend'
676
+ entry 0, 'undefined'
677
+ entry 1, 'down'
678
+ entry 2, 'maintaining'
679
+ entry 3, 'up'
680
+
654
681
  end
655
682
 
656
683
  end
@@ -44,8 +44,12 @@ module Fit4Ruby
44
44
  field 14, 'uint8', 'undocumented_field_14'
45
45
  field 15, 'uint8', 'undocumented_field_15'
46
46
  field 22, 'enum', 'undocumented_field_22'
47
+ field 23, 'enum', 'undocumented_field_23'
48
+ field 25, 'enum', 'undocumented_field_25'
47
49
  field 26, 'enum', 'undocumented_field_26'
48
50
  field 28, 'enum', 'undocumented_field_28'
51
+ field 30, 'enum', 'undocumented_field_30'
52
+ field 31, 'enum', 'undocumented_field_31'
49
53
  field 34, 'enum', 'undocumented_field_34'
50
54
  field 35, 'enum', 'undocumented_field_35'
51
55
  field 36, 'enum', 'activity_tracker_enabled'
@@ -56,6 +60,7 @@ module Fit4Ruby
56
60
  field 44, 'enum', 'undocumented_field_44'
57
61
  field 45, 'enum', 'undocumented_field_45'
58
62
  field 46, 'enum', 'move_alert_enabled'
63
+ field 47, 'enum', 'date_mode'
59
64
  field 48, 'enum', 'undocumented_field_48'
60
65
  field 49, 'uint16', 'undocumented_field_49'
61
66
  field 51, 'enum', 'undocumented_field_51'
@@ -75,6 +80,8 @@ module Fit4Ruby
75
80
  field 68, 'enum', 'undocumented_field_68'
76
81
  field 69, 'enum', 'undocumented_field_69'
77
82
  field 75, 'enum', 'undocumented_field_75'
83
+ field 76, 'enum', 'undocumented_field_76'
84
+ field 77, 'enum', 'undocumented_field_77'
78
85
  field 80, 'enum', 'lactate_threshold_autodetect_enabled'
79
86
  field 81, 'enum', 'undocumented_field_81'
80
87
  field 82, 'enum', 'undocumented_field_82'
@@ -84,6 +91,7 @@ module Fit4Ruby
84
91
  field 87, 'enum', 'undocumented_field_87'
85
92
  field 90, 'uint32', 'auto_activity_detect'
86
93
  field 94, 'uint8', 'number_of_screens'
94
+ field 96, 'enum', 'undocumented_field_96'
87
95
  field 97, 'uint8z', 'undocumented_field_97'
88
96
  field 101, 'enum', 'undocumented_field_101'
89
97
  field 104, 'enum', 'undocumented_field_104'
@@ -93,14 +101,27 @@ module Fit4Ruby
93
101
  field 110, 'enum', 'undocumented_field_110'
94
102
  field 111, 'enum', 'undocumented_field_111'
95
103
  field 112, 'enum', 'undocumented_field_112'
104
+ field 116, 'enum', 'undocumented_field_116'
105
+ field 117, 'enum', 'undocumented_field_117'
96
106
  field 124, 'uint8', 'undocumented_field_124'
97
107
  field 125, 'uint8', 'undocumented_field_125'
98
108
  field 126, 'enum', 'undocumented_field_126'
99
109
  field 127, 'enum', 'undocumented_field_127'
100
110
  field 128, 'enum', 'undocumented_field_128'
111
+ field 129, 'enum', 'undocumented_field_129'
112
+ field 130, 'enum', 'undocumented_field_130'
113
+ field 131, 'enum', 'undocumented_field_131'
114
+ field 132, 'enum', 'undocumented_field_132'
101
115
  field 133, 'enum', 'undocumented_field_133'
116
+ field 137, 'enum', 'undocumented_field_137'
102
117
  field 138, 'enum', 'undocumented_field_138'
118
+ field 139, 'enum', 'undocumented_field_139'
119
+ field 141, 'uint8', 'undocumented_field_141'
120
+ field 142, 'uint8', 'undocumented_field_142'
121
+ field 143, 'uint8', 'undocumented_field_143'
103
122
  field 144, 'enum', 'true_up_enabled'
123
+ field 148, 'enum', 'undocumented_field_148'
124
+ field 149, 'enum', 'undocumented_field_149'
104
125
 
105
126
  message 3, 'user_profile'
106
127
  field 0, 'string', 'friendly_name'
@@ -124,7 +145,7 @@ module Fit4Ruby
124
145
  field 30, 'enum', 'height_setting', :dict => 'display_measure'
125
146
  field 31, 'uint16', 'user_running_step_length'
126
147
  field 32, 'uint16', 'user_walking_step_length'
127
- field 33, 'uint16', 'undocumented_field_33'
148
+ field 33, 'uint16', 'undocumented_field_33' # varies between 800 to 1600, seems VO2max related
128
149
  field 34, 'uint16', 'undocumented_field_34'
129
150
  field 35, 'uint32', 'undocumented_field_35'
130
151
  field 36, 'uint8', 'undocumented_field_36'
@@ -132,11 +153,54 @@ module Fit4Ruby
132
153
  field 38, 'uint16', 'undocumented_field_38'
133
154
  field 39, 'float32', 'undocumented_field_39'
134
155
  field 40, 'float32', 'undocumented_field_40'
135
- field 41, 'uint32', 'undocumented_field_41'
156
+ field 41, 'uint32', 'time_last_lthr_update', :type => 'date_time'
136
157
  field 42, 'uint32', 'undocumented_field_42'
137
158
  field 43, 'enum', 'undocumented_field_43'
159
+ field 47, 'enum', 'undocumented_field_47'
138
160
  field 253, 'uint32', 'timestamp', :type => 'date_time'
139
161
 
162
+ message 5, 'sdm_profile'
163
+ field 0, 'bool', 'enabled'
164
+ field 1, 'uint16z', 'sdm_ant_id'
165
+ field 2, 'uint16', 'sdm_cal_factor', :scale => 10, :unit => '%'
166
+ field 3, 'uint32', 'odometer', :scale => 100, :unit => 'm'
167
+ field 4, 'bool', 'speed_source'
168
+ field 5, 'uint8z', 'sdm_ant_id_trans_type'
169
+ field 7, 'uint8', 'odometer_rollover'
170
+
171
+ message 6, 'bike_profile'
172
+ field 0, 'string', 'name'
173
+ field 1, 'sport', 'sport'
174
+ field 2, 'sub_sport', 'sub_sport'
175
+ field 3, 'uint32', 'odometer', :scale => 100, :unit => 'm'
176
+ field 4, 'uint16z', 'bike_spd_ant_id'
177
+ field 5, 'uint16z', 'bike_cad_ant_id'
178
+ field 6, 'uint16z', 'bike_spdcad_ant_id'
179
+ field 7, 'uint16z', 'bike_power_ant_id'
180
+ field 8, 'uint16', 'custom_wheelsize', :scale => 1000, :unit => 'm'
181
+ field 9, 'uint16', 'auto_wheelsize', :scale => 1000, :unit => 'm'
182
+ field 10, 'uint16', 'bike_weight', :scale => 10, :unit => 'kg'
183
+ field 11, 'uint16', 'power_cal_factor', :scale => 10, :unit => '%'
184
+ field 12, 'bool', 'auto_wheel_cal'
185
+ field 13, 'bool', 'auto_power_zero'
186
+ field 14, 'uint8', 'id'
187
+ field 15, 'bool', 'spd_enabled'
188
+ field 16, 'bool', 'cad_enabled'
189
+ field 17, 'bool', 'spdcad_enabled'
190
+ field 18, 'bool', 'power_enabled'
191
+ field 19, 'uint8', 'crank_length', :scale => 2, :offset => -110, :unit => 'mm'
192
+ field 20, 'bool', 'enabled'
193
+ field 21, 'uint8z', 'bike_spd_ant_id_trans_type'
194
+ field 22, 'uint8z', 'bike_cad_ant_id_trans_type'
195
+ field 23, 'uint8z', 'bike_spdcad_ant_id_trans_type'
196
+ field 24, 'uint8z', 'bike_power_ant_id_trans_type'
197
+ field 37, 'uint8', 'odometer_rollover'
198
+ field 38, 'uint8z', 'front_gear_num', :array => true
199
+ field 39, 'uint8z', 'front_gear'
200
+ field 40, 'uint8z', 'rear_gear_num', :array => true
201
+ field 41, 'uint8z', 'rear_gear'
202
+ field 44, 'bool', 'shimano_di2_enabled'
203
+
140
204
  message 7, 'zones_target'
141
205
  field 1, 'uint8', 'max_heart_rate'
142
206
  field 2, 'uint8', 'threshold_heart_rate'
@@ -157,10 +221,13 @@ module Fit4Ruby
157
221
  field 4, 'uint16', 'undocumented_field_4'
158
222
  field 5, 'enum', 'undocumented_field_5'
159
223
  field 6, 'enum', 'undocumented_field_6'
224
+ field 9, 'uint8', 'undocumented_field_9'
160
225
  field 10, 'uint8', 'undocumented_field_10', :array => true
161
226
  field 11, 'enum', 'undocumented_field_11'
162
- field 12, 'uint8', 'undocumented_field_12'
227
+ field 12, 'uint8', 'undocumented_field_12', :array => true
163
228
  field 13, 'enum', 'undocumented_field_13'
229
+ field 15, 'enum', 'undocumented_field_15'
230
+ field 19, 'enum', 'undocumented_field_19', :array => true
164
231
 
165
232
  # Not part of the official ANT SDK doc.
166
233
  message 13, 'undocumented_13'
@@ -198,14 +265,23 @@ module Fit4Ruby
198
265
  field 40, 'enum', 'undocumented_field_40'
199
266
  field 41, 'sint32', 'undocumented_field_41'
200
267
  field 42, 'uint8', 'undocumented_field_42'
268
+ field 43, 'enum', 'undocumented_field_43'
269
+ field 44, 'enum', 'undocumented_field_44'
270
+ field 45, 'enum', 'undocumented_field_45'
201
271
  field 46, 'enum', 'undocumented_field_46'
272
+ field 47, 'enum', 'undocumented_field_47'
273
+ field 48, 'enum', 'undocumented_field_48'
202
274
  field 53, 'enum', 'undocumented_field_53'
203
275
  field 54, 'uint32', 'undocumented_field_54'
204
276
  field 55, 'enum', 'undocumented_field_55'
205
277
  field 57, 'enum', 'undocumented_field_57'
206
278
  field 60, 'enum', 'undocumented_field_60'
279
+ field 62, 'enum', 'undocumented_field_62'
280
+ field 63, 'enum', 'undocumented_field_63'
281
+ field 64, 'uint16', 'undocumented_field_64'
207
282
  field 65, 'enum', 'undocumented_field_65'
208
283
  field 66, 'enum', 'undocumented_field_66'
284
+ field 76, 'enum', 'undocumented_field_76'
209
285
  field 254, 'uint16', 'message_index'
210
286
 
211
287
  message 18, 'session'
@@ -304,10 +380,15 @@ module Fit4Ruby
304
380
  field 121, 'uint16', 'max_power_position', :array => true, :unit => 'watts'
305
381
  field 122, 'uint8', 'avg_cadence_position', :array => true, :unit => 'rpm'
306
382
  field 123, 'uint8', 'max_cadence_position', :array => true, :unit => 'rpm'
383
+ field 124, 'uint32', 'enhanced_avg_speed', :scale => 1000, :unit => 'm/s'
384
+ field 125, 'uint32', 'enhanced_max_speed', :scale => 1000, :unit => 'm/s'
385
+ field 126, 'uint32', 'enhanced_avg_altitude', :scale => 5, :offset => 500, :unit => 'm'
386
+ field 127, 'uint32', 'enhanced_min_altitude', :scale => 5, :offset => 500, :unit => 'm'
387
+ field 128, 'uint32', 'enhanced_max_altitude', :scale => 5, :offset => 500, :unit => 'm'
307
388
  field 132, 'uint16', 'avg_vertical_ratio', :scale => 100, :unit => '%'
308
389
  field 133, 'uint16', 'avg_stance_time_balance', :scale => 100, :unit => '%'
309
- field 134, 'uint16', 'avg_step_length', :scale => 100, :unit => 'mm'
310
- field 137, 'uint8', 'g_effect', :scale => 10
390
+ field 134, 'uint16', 'avg_step_length', :scale => 10, :unit => 'mm'
391
+ field 137, 'uint8', 'total_anaerobic_training_effect', :scale => 10
311
392
  field 138, 'uint8', 'undocumented_field_138'
312
393
  field 150, 'sint8', 'min_temperature', :unit => 'C' # guessed
313
394
  field 151, 'uint16', 'undocumented_field_151'
@@ -316,6 +397,7 @@ module Fit4Ruby
316
397
  field 158, 'uint16', 'undocumented_field_158'
317
398
  field 153, 'enum', 'undocumented_field_153'
318
399
  field 154, 'enum', 'undocumented_field_154'
400
+ field 184, 'enum', 'undocumented_field_184'
319
401
  field 253, 'uint32', 'timestamp', :type => 'date_time'
320
402
  field 254, 'uint16', 'message_index'
321
403
 
@@ -403,9 +485,14 @@ module Fit4Ruby
403
485
  field 107, 'uint16', 'max_power_position', :array => true, :unit => 'watts'
404
486
  field 108, 'uint8', 'avg_cadence_position', :array => true, :unit => 'rpm'
405
487
  field 109, 'uint8', 'max_cadence_position', :array => true, :unit => 'rpm'
406
- field 118, 'uint16', 'vertical_ratio', :scale => 100, :unit => '%' # guessed
407
- field 119, 'uint16', 'avg_gct_balance', :scale => 100, :unit => '%' # guessed
408
- field 120, 'uint16', 'avg_stride_length', :scale => 10000, :unit => 'm' # guessed
488
+ field 110, 'uint32', 'enhanced_avg_speed', :scale => 1000, :unit => 'm/s'
489
+ field 111, 'uint32', 'enhanced_max_speed', :scale => 1000, :unit => 'm/s'
490
+ field 112, 'uint32', 'enhanced_avg_altitude', :scale => 5, :offset => 500, :unit => 'm'
491
+ field 113, 'uint32', 'enhanced_min_altitude', :scale => 5, :offset => 500, :unit => 'm'
492
+ field 114, 'uint32', 'enhanced_max_altitude', :scale => 5, :offset => 500, :unit => 'm'
493
+ field 118, 'uint16', 'avg_vertical_ratio', :scale => 100, :unit => '%'
494
+ field 119, 'uint16', 'avg_stance_time_balance', :scale => 100, :unit => '%'
495
+ field 120, 'uint16', 'avg_step_length', :scale => 10000, :unit => 'm'
409
496
  field 124, 'sint8', 'min_temperature', :unit => 'C' # guessed
410
497
  field 125, 'uint16', 'undocumented_field_125'
411
498
  field 126, 'uint16', 'undocumented_field_126'
@@ -488,6 +575,7 @@ module Fit4Ruby
488
575
  field 'recovery_time', 'uint32', 'recovery_time', :unit => 'min'
489
576
  field 'recovery_info', 'uint32', 'recovery_info', :unit => 'min'
490
577
  field 'vo2max', 'uint32', 'vo2max'
578
+ field 'functional_threshold_power', 'uint32', 'functional_threshold_power', :unit => 'W'
491
579
  field 'lactate_threshold_heart_rate', 'uint32', 'lactate_threshold_heart_rate', :unit => 'bpm'
492
580
  field 'lactate_threshold_speed', 'uint32', 'lactate_threshold_speed', :scale => 1000, :unit => 'm/s'
493
581
  end
@@ -495,6 +583,8 @@ module Fit4Ruby
495
583
  field 14, 'enum', 'undocumented_field_14'
496
584
  field 15, 'uint32', 'undocumented_field_15'
497
585
  field 16, 'enum', 'undocumented_field_16'
586
+ field 19, 'uint8', 'undocumented_field_19'
587
+ field 20, 'uint8', 'undocumented_field_20'
498
588
  field 253, 'uint32', 'timestamp', :type => 'date_time'
499
589
 
500
590
  # Possibly which device is used as metering source.
@@ -642,7 +732,7 @@ module Fit4Ruby
642
732
 
643
733
  # Not part of the official ANT SDK doc
644
734
  message 79, 'user_data'
645
- field 0, 'uint16', 'metmax', :scale => 1000, :unit => 'MET' # VO2max / 3.5
735
+ field 0, 'uint16', 'metmax', :scale => 1024, :unit => 'MET' # VO2max / 3.5
646
736
  field 1, 'uint8', 'age', :unit => 'years'
647
737
  field 2, 'uint8', 'height', :scale => 100, :unit => 'm'
648
738
  field 3, 'uint16', 'weight', :scale => 10, :unit => 'kg'
@@ -652,9 +742,9 @@ module Fit4Ruby
652
742
  field 7, 'sint8', 'undocumented_field_7' # seems to be always 1
653
743
  field 8, 'uint16', 'recovery_time', :scale => 60, :unit => 'hours'
654
744
  field 9, 'uint16', 'undocumented_field_9' # maybe activity measurement
655
- field 10, 'uint8', 'undocumented_field_10'
745
+ field 10, 'uint8', 'avg_resting_heart_rate', :unit => 'bpm'
656
746
  field 11, 'uint16', 'running_lactate_threshold_heart_rate', :unit => 'bpm'
657
- field 12, 'uint16', 'undocumented_field_12'
747
+ field 12, 'uint16', 'functional_threshold_power', :unit => 'W'
658
748
  field 13, 'uint16', 'undocumented_field_13'
659
749
  field 14, 'uint8', 'undocumented_field_14'
660
750
  field 15, 'uint8', 'undocumented_field_15'
@@ -722,18 +812,18 @@ module Fit4Ruby
722
812
  # All known fields so far seem to be physiological values. We'll use the
723
813
  # name physiological_metrics for now.
724
814
  message 140, 'physiological_metrics'
725
- field 0, 'uint8', 'max_heart_rate', :unit => 'bpm'
726
- field 1, 'uint8', 'undocumented_field_1'
815
+ field 0, 'uint8', 'min_heart_rate', :unit => 'bpm'
816
+ field 1, 'uint8', 'max_heart_rate', :unit => 'bpm'
727
817
  field 2, 'sint32', 'undocumented_field_2'
728
818
  field 3, 'sint32', 'undocumented_field_3'
729
819
  field 4, 'uint8', 'aerobic_training_effect', :scale => 10
730
820
  field 5, 'sint32', 'undocumented_field_5'
731
821
  field 6, 'sint32', 'undocumented_field_6'
732
- field 7, 'sint32', 'undocumented_field_7'
822
+ field 7, 'sint32', 'metmax', :scale => 65536, :unit => 'MET'
733
823
  # Field 8 used to be uint8 but recent devices use sint8. We model this
734
824
  # with an alt_field. The switch field is randomly picked as we have no
735
825
  # details why the type has been changed.
736
- alt_field 8, 'undocumented_field_1' do
826
+ alt_field 8, 'max_heart_rate' do
737
827
  field :default, 'sint8', 'undocumented_field_8s'
738
828
  field 255, 'uint8', 'undocumented_field_8u'
739
829
  end
@@ -755,9 +845,10 @@ module Fit4Ruby
755
845
  field 24, 'sint32', 'undocumented_field_24'
756
846
  field 25, 'uint8', 'undocumented_field_25'
757
847
  field 26, 'sint32', 'undocumented_field_26'
758
- field 29, 'sint32', 'undocumented_field_29'
848
+ field 29, 'sint32', 'metmax_running', :scale => 65536, :unit => 'MET'
759
849
  field 34, 'enum', 'undocumented_field_34'
760
850
  field 35, 'uint32', 'undocumented_field_35'
851
+ field 36, 'uint32', 'undocumented_field_36'
761
852
  field 253, 'uint32', 'timestamp', :type => 'date_time'
762
853
 
763
854
  # Not part of the official ANT SDK doc. The message name is guessed and
@@ -824,6 +915,9 @@ module Fit4Ruby
824
915
  field 58, 'enum', 'undocumented_field_58'
825
916
  field 59, 'uint8', 'undocumented_field_59'
826
917
  field 62, 'uint8', 'undocumented_field_62'
918
+ field 63, 'enum', 'undocumented_field_63'
919
+ field 64, 'uint32', 'undocumented_field_64'
920
+ field 65, 'uint32', 'undocumented_field_65'
827
921
  field 254, 'uint16', 'message_index'
828
922
 
829
923
  # Not part of the official ANT SDK doc.
@@ -881,6 +975,74 @@ module Fit4Ruby
881
975
  field 1, 'uint32', 'stress_level_time', :type => 'date_time'
882
976
  field 2, 'sint8', 'undocumented_field_2'
883
977
 
978
+ # Not part of the official ANT SDK doc.
979
+ message 229, 'undocumented_229'
980
+ field 0, 'uint32', 'time', :type => 'date_time'
981
+ field 1, 'sint32', 'metmax', :scale => 65536, :unit => 'MET'
982
+ field 2, 'uint16', 'vo2max', :scale => 10, :unit => 'ml/kg/min'
983
+ field 3, 'sint8', 'undocumented_field_3'
984
+ field 4, 'sint8', 'undocumented_field_4'
985
+ field 5, 'enum', 'undocumented_field_5'
986
+ field 6, 'enum', 'undocumented_field_6'
987
+ field 7, 'enum', 'undocumented_field_7'
988
+ field 8, 'enum', 'undocumented_field_8'
989
+ field 9, 'enum', 'undocumented_field_9'
990
+
991
+ # Not part of the official ANT SDK doc.
992
+ message 232, 'training_status'
993
+ field 0, 'enum', 'undocumented_0'
994
+ field 1, 'enum', 'undocumented_1'
995
+ field 2, 'enum', 'current_status', :dict => 'training_status'
996
+ field 3, 'enum', 'fitness', :dict => 'training_status_trend'
997
+ field 4, 'enum', 'load', :dict => 'training_status_trend'
998
+ field 5, 'uint16', 'training_load'
999
+ field 6, 'uint16', 'low_training_load'
1000
+ field 7, 'uint16', 'high_training_load'
1001
+ field 8, 'uint16', 'max_training_load'
1002
+ field 253, 'uint32', 'timestamp', :type => 'date_time'
1003
+
1004
+ # Not part of the official ANT SDK doc.
1005
+ message 233, 'undocumented_233'
1006
+ field 2, 'byte', 'undocumented_field_2'
1007
+
1008
+ # Not part of the official ANT SDK doc.
1009
+ message 241, 'metrics'
1010
+ field 0, 'uint32', 'localtime', :type => 'date_time'
1011
+ field 253, 'uint32', 'timestamp', :type => 'date_time'
1012
+
1013
+ # Not part of the official ANT SDK doc.
1014
+ message 243, 'media_player_info'
1015
+ field 0, 'uint32', 'undocumented_field_0'
1016
+ field 1, 'uint16', 'undocumented_field_1'
1017
+ field 2, 'string', 'track_1'
1018
+ field 3, 'string', 'track_2'
1019
+ field 4, 'string', 'track_3'
1020
+ field 5, 'uint16', 'undocumented_field_5'
1021
+ field 6, 'uint16', 'undocumented_field_6'
1022
+
1023
+ # Not part of the official ANT SDK doc.
1024
+ message 244, 'undocumented_244'
1025
+ field 0, 'uint32', 'undocumented_field_0'
1026
+ field 1, 'enum', 'undocumented_field_1'
1027
+ field 2, 'uint16', 'undocumented_field_2'
1028
+
1029
+ # Not part of the official ANT SDK doc.
1030
+ message 269, 'undocumented_269'
1031
+ field 0, 'uint8', 'undocumented_field_0'
1032
+ field 1, 'uint8', 'undocumented_field_1'
1033
+ field 253, 'uint32', 'timestamp', :type => 'date_time'
1034
+
1035
+ # Not part of the official ANT SDK doc.
1036
+ message 279, 'undocumented_279'
1037
+ field 0, 'uint32', 'undocumented_field_0'
1038
+ field 253, 'uint32', 'timestamp', :type => 'date_time'
1039
+
1040
+ # Not part of the official ANT SDK doc.
1041
+ message 284, 'training_load'
1042
+ field 0, 'uint16', 'load'
1043
+ field 1, 'uint32', 'timestamp', :type => 'date_time'
1044
+
1045
+ # Not part of the official ANT SDK doc.
884
1046
  message 1024, 'undocumented_1024'
885
1047
  field 0, 'enum', 'undocumented_field_0'
886
1048
  field 2, 'enum', 'undocumented_field_2'
@@ -890,10 +1052,6 @@ module Fit4Ruby
890
1052
  field 247, 'enum', 'undocumented_field_247'
891
1053
  field 255, 'enum', 'undocumented_field_255'
892
1054
 
893
- # Not part of the official ANT SDK doc.
894
- message 233, 'undocumented_233'
895
- field 2, 'byte', 'undocumented_field_2'
896
-
897
1055
  end
898
1056
 
899
1057
  end
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = Metrics.rb -- Fit4Ruby - FIT file processing library for Ruby
5
+ #
6
+ # Copyright (c) 2018 by Chris Schlaeger <cs@taskjuggler.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
13
+ require 'fit4ruby/FitDataRecord'
14
+ require 'fit4ruby/FileId'
15
+ require 'fit4ruby/FileCreator'
16
+ require 'fit4ruby/DeviceInfo'
17
+ require 'fit4ruby/TrainingStatus'
18
+
19
+ module Fit4Ruby
20
+
21
+ # The Metrics object is a FIT file class. It's a top-level object that
22
+ # holds all references to other FIT records that are part of the FIT file.
23
+ # Each of the objects it references are direct equivalents of the message
24
+ # record structures used in the FIT file.
25
+ #
26
+ # This is not part of the officially documented FIT API. Names may change in
27
+ # the future if the real Garmin names get known.
28
+ class Metrics < FitDataRecord
29
+
30
+ attr_accessor :field_descriptions, :file_id, :file_creator, :device_infos
31
+
32
+ # Create a new Metrics object.
33
+ # @param field_values [Hash] A Hash that provides initial values for
34
+ # certain fields of the FitDataRecord.
35
+ def initialize(field_values = {})
36
+ super('metrics')
37
+
38
+ @field_descriptions = []
39
+
40
+ @file_id = FileId.new
41
+ @device_infos = []
42
+ @file_creator = nil
43
+ @training_statuses = []
44
+ end
45
+
46
+ # Perform some basic logical checks on the object and all references sub
47
+ # objects. Any errors will be reported via the Log object.
48
+ def check
49
+ end
50
+
51
+ # Create a new FitDataRecord.
52
+ # @param record_type [String] Type that identifies the FitDataRecord
53
+ # derived class to create.
54
+ # @param field_values [Hash] A Hash that provides initial values for
55
+ # certain fields of the FitDataRecord.
56
+ # @return FitDataRecord
57
+ def new_fit_data_record(record_type, field_values = {})
58
+ case record_type
59
+ when 'file_id'
60
+ @file_id = (record = FileId.new(field_values))
61
+ when 'file_creator'
62
+ @software = (record = FileCreator.new(field_values))
63
+ when 'device_info'
64
+ @device_infos << (record = DeviceInfo.new(field_values))
65
+ when 'training_status'
66
+ @training_statuses << (record = TrainingStatus.new(field_values))
67
+ else
68
+ record = nil
69
+ end
70
+
71
+ record
72
+ end
73
+
74
+ end
75
+
76
+ end
77
+
78
+
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = TrainingStatus.rb -- Fit4Ruby - FIT file processing library for Ruby
5
+ #
6
+ # Copyright (c) 2018 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
+ # This class corresponds to the training_status message.
18
+ #
19
+ # This is not part of the officially documented FIT API. Names may change in
20
+ # the future if the real Garmin names get known.
21
+ class TrainingStatus < FitDataRecord
22
+
23
+ def initialize(field_values = {})
24
+ super('training_status')
25
+ set_field_values(field_values)
26
+ end
27
+
28
+ # Ensure that FitDataRecords have a deterministic sequence. Device infos
29
+ # are sorted by device_index.
30
+ def <=>(fdr)
31
+ @timestamp == fdr.timestamp ?
32
+ @message.name == fdr.message.name ?
33
+ @device_index <=> fdr.device_index :
34
+ RecordOrder.index(@message.name) <=>
35
+ RecordOrder.index(fdr.message.name) :
36
+ @timestamp <=> fdr.timestamp
37
+ end
38
+
39
+ def check(index)
40
+ end
41
+
42
+ end
43
+
44
+ end
45
+
46
+
@@ -1,4 +1,4 @@
1
1
  module Fit4Ruby
2
2
  # The version number of the library.
3
- VERSION = '3.1.0'
3
+ VERSION = '3.2.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.1.0
4
+ version: 3.2.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: 2018-06-17 00:00:00.000000000 Z
11
+ date: 2019-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bindata
@@ -119,6 +119,7 @@ files:
119
119
  - lib/fit4ruby/HeartRateZones.rb
120
120
  - lib/fit4ruby/Lap.rb
121
121
  - lib/fit4ruby/Log.rb
122
+ - lib/fit4ruby/Metrics.rb
122
123
  - lib/fit4ruby/Monitoring.rb
123
124
  - lib/fit4ruby/MonitoringInfo.rb
124
125
  - lib/fit4ruby/Monitoring_B.rb
@@ -129,6 +130,7 @@ files:
129
130
  - lib/fit4ruby/SensorSettings.rb
130
131
  - lib/fit4ruby/Session.rb
131
132
  - lib/fit4ruby/Software.rb
133
+ - lib/fit4ruby/TrainingStatus.rb
132
134
  - lib/fit4ruby/UserData.rb
133
135
  - lib/fit4ruby/UserProfile.rb
134
136
  - lib/fit4ruby/version.rb