fit4ruby 3.3.0 → 3.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/Gemfile.lock +30 -6
- data/fit4ruby.gemspec +4 -2
- data/lib/fit4ruby/Activity.rb +145 -58
- data/lib/fit4ruby/BDFieldNameTranslator.rb +36 -0
- data/lib/fit4ruby/DeviceInfo.rb +37 -0
- data/lib/fit4ruby/FDR_DevField_Extension.rb +81 -0
- data/lib/fit4ruby/FieldDescription.rb +26 -8
- data/lib/fit4ruby/FileId.rb +2 -1
- data/lib/fit4ruby/FitDataRecord.rb +86 -33
- data/lib/fit4ruby/FitDefinition.rb +11 -4
- data/lib/fit4ruby/FitDefinitionField.rb +6 -6
- data/lib/fit4ruby/FitDefinitionFieldBase.rb +15 -6
- data/lib/fit4ruby/FitDeveloperDataFieldDefinition.rb +1 -1
- data/lib/fit4ruby/FitFile.rb +2 -0
- data/lib/fit4ruby/FitMessageRecord.rb +26 -21
- data/lib/fit4ruby/FitRecord.rb +2 -1
- data/lib/fit4ruby/FitTypeDefs.rb +2 -2
- data/lib/fit4ruby/GlobalFitDictionaries.rb +278 -22
- data/lib/fit4ruby/GlobalFitMessage.rb +84 -14
- data/lib/fit4ruby/GlobalFitMessages.rb +104 -10
- data/lib/fit4ruby/Lap.rb +38 -3
- data/lib/fit4ruby/Length.rb +53 -0
- data/lib/fit4ruby/Record.rb +11 -2
- data/lib/fit4ruby/version.rb +1 -1
- data/spec/FitFile_spec.rb +233 -89
- metadata +43 -13
@@ -3,7 +3,7 @@
|
|
3
3
|
#
|
4
4
|
# = GlobalFitMessage.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, 2020 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
|
@@ -21,7 +21,8 @@ module Fit4Ruby
|
|
21
21
|
# the data fields of the message.
|
22
22
|
class GlobalFitMessage
|
23
23
|
|
24
|
-
attr_reader :name, :number, :fields_by_name, :fields_by_number
|
24
|
+
attr_reader :name, :number, :fields_by_name, :fields_by_number,
|
25
|
+
:field_values_by_name
|
25
26
|
|
26
27
|
# The Field objects describe the name, type and optional attributes of a
|
27
28
|
# FitMessage definition field. It also provides methods to convert field
|
@@ -38,8 +39,21 @@ module Fit4Ruby
|
|
38
39
|
@opts = opts
|
39
40
|
end
|
40
41
|
|
42
|
+
def is_undefined?(value)
|
43
|
+
value == FitDefinitionFieldBase.undefined_value(@type)
|
44
|
+
end
|
45
|
+
|
46
|
+
def is_string?
|
47
|
+
@type == 'string'
|
48
|
+
end
|
49
|
+
|
50
|
+
def is_array?
|
51
|
+
@opts[:array] == true
|
52
|
+
end
|
53
|
+
|
41
54
|
def to_machine(value)
|
42
|
-
return nil if value.nil?
|
55
|
+
return nil if value.nil? ||
|
56
|
+
value == FitDefinitionFieldBase.undefined_value(@type)
|
43
57
|
|
44
58
|
if @opts.include?(:dict) &&
|
45
59
|
(dict = GlobalFitDictionaries[@opts[:dict]])
|
@@ -51,6 +65,13 @@ module Fit4Ruby
|
|
51
65
|
value *= 180.0 / 2147483648
|
52
66
|
when 'date_time'
|
53
67
|
value = fit_time_to_time(value)
|
68
|
+
when 'float'
|
69
|
+
if value >= 4294967295.0
|
70
|
+
return nil
|
71
|
+
end
|
72
|
+
end
|
73
|
+
if value.is_a?(Float) && value >= 4294967295.0
|
74
|
+
return nil
|
54
75
|
end
|
55
76
|
value /= @opts[:scale].to_f if @opts[:scale]
|
56
77
|
value -= @opts[:offset] if @opts[:offset]
|
@@ -133,7 +154,7 @@ module Fit4Ruby
|
|
133
154
|
value
|
134
155
|
end
|
135
156
|
|
136
|
-
def to_s(value)
|
157
|
+
def to_s(value = nil)
|
137
158
|
return "[no value]" if value.nil?
|
138
159
|
|
139
160
|
human_readable = to_human(value)
|
@@ -167,7 +188,7 @@ module Fit4Ruby
|
|
167
188
|
|
168
189
|
def field(ref_value, type, name, opts = {})
|
169
190
|
field = Field.new(type, name, opts)
|
170
|
-
if ref_value.respond_to?(
|
191
|
+
if ref_value.respond_to?(:each)
|
171
192
|
ref_value.each do |rv|
|
172
193
|
@fields[rv] = field
|
173
194
|
end
|
@@ -180,13 +201,13 @@ module Fit4Ruby
|
|
180
201
|
# Select the alternative field based on the actual field values of the
|
181
202
|
# FitMessageRecord.
|
182
203
|
def select(field_values_by_name)
|
183
|
-
unless (
|
204
|
+
unless (value_of_referenced_field = field_values_by_name[@ref_field])
|
184
205
|
Log.fatal "The selection field #{@ref_field} for the alternative " +
|
185
206
|
"field is undefined in global message #{@message.name}: " +
|
186
207
|
field_values_by_name.inspect
|
187
208
|
end
|
188
209
|
@fields.each do |ref_value, field|
|
189
|
-
return field if ref_value ==
|
210
|
+
return field if ref_value == value_of_referenced_field
|
190
211
|
end
|
191
212
|
return @fields[:default] if @fields[:default]
|
192
213
|
|
@@ -199,7 +220,7 @@ module Fit4Ruby
|
|
199
220
|
# Create a new GlobalFitMessage definition.
|
200
221
|
# @param name [String] name of the FIT message
|
201
222
|
# @param number [Fixnum] global message number
|
202
|
-
def initialize(name, number)
|
223
|
+
def initialize(name, number, field_values_by_name = {})
|
203
224
|
@name = name
|
204
225
|
@number = number
|
205
226
|
# Field names must be unique. A name always matches a single Field.
|
@@ -207,13 +228,57 @@ module Fit4Ruby
|
|
207
228
|
# Field numbers are not unique. A group of alternative fields shares the
|
208
229
|
# same number and is stored as an AltField. Otherwise as Field.
|
209
230
|
@fields_by_number = {}
|
231
|
+
# To generate the proper definition message we need to know the length
|
232
|
+
# of String and Array fields. This is only needed when writing FIT
|
233
|
+
# files.
|
234
|
+
@field_values_by_name = field_values_by_name
|
210
235
|
end
|
211
236
|
|
212
237
|
# Two GlobalFitMessage objects are considered equal if they have the same
|
213
|
-
# number, name and list of named fields.
|
238
|
+
# number, name and list of named fields. In case they have String or Array
|
239
|
+
# values, they must have identical size.
|
214
240
|
def ==(m)
|
215
|
-
@number == m.number && @name == m.name &&
|
216
|
-
|
241
|
+
unless @number == m.number && @name == m.name &&
|
242
|
+
@fields_by_name.keys.sort == m.fields_by_name.keys.sort
|
243
|
+
return false
|
244
|
+
end
|
245
|
+
|
246
|
+
unless @field_values_by_name.size == m.field_values_by_name.size
|
247
|
+
return false
|
248
|
+
end
|
249
|
+
|
250
|
+
unless @field_values_by_name.empty?
|
251
|
+
@field_values_by_name.keys.each do |name|
|
252
|
+
a = @field_values_by_name[name]
|
253
|
+
b = m.field_values_by_name[name]
|
254
|
+
if a.class != b.class
|
255
|
+
return false
|
256
|
+
end
|
257
|
+
if a.is_a?(String)
|
258
|
+
if a.bytes.length != b.bytes.length
|
259
|
+
return false
|
260
|
+
end
|
261
|
+
elsif a.is_a?(Array)
|
262
|
+
if a.length != b.length
|
263
|
+
return false
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
true
|
270
|
+
end
|
271
|
+
|
272
|
+
def each_field(field_values)
|
273
|
+
@fields_by_number.each do |number, field|
|
274
|
+
if field.is_a?(AltField)
|
275
|
+
# For alternative fields, we need to look at the value of the
|
276
|
+
# selector field and pick the corresponding Field.
|
277
|
+
field = field.select(field_values)
|
278
|
+
end
|
279
|
+
|
280
|
+
yield(number, field)
|
281
|
+
end
|
217
282
|
end
|
218
283
|
|
219
284
|
# Define a new Field for this message definition.
|
@@ -223,6 +288,11 @@ module Fit4Ruby
|
|
223
288
|
register_field_by_number(field, number)
|
224
289
|
end
|
225
290
|
|
291
|
+
# Check if a field with the given name already exists?
|
292
|
+
def has_field?(name)
|
293
|
+
return @fields_by_name.include?(name)
|
294
|
+
end
|
295
|
+
|
226
296
|
# Define a new set of Field alternatives for this message definition.
|
227
297
|
def alt_field(number, ref_field, &block)
|
228
298
|
unless @fields_by_name.include?(ref_field)
|
@@ -250,7 +320,7 @@ module Fit4Ruby
|
|
250
320
|
end
|
251
321
|
|
252
322
|
def construct(field_values_by_name)
|
253
|
-
gfm = GlobalFitMessage.new(@name, @number)
|
323
|
+
gfm = GlobalFitMessage.new(@name, @number, field_values_by_name)
|
254
324
|
|
255
325
|
@fields_by_number.each do |number, field|
|
256
326
|
if field.is_a?(AltField)
|
@@ -264,7 +334,7 @@ module Fit4Ruby
|
|
264
334
|
gfm
|
265
335
|
end
|
266
336
|
|
267
|
-
def write(io, local_message_type
|
337
|
+
def write(io, local_message_type)
|
268
338
|
header = FitRecordHeader.new
|
269
339
|
header.normal = 0
|
270
340
|
header.message_type = 1
|
@@ -273,7 +343,7 @@ module Fit4Ruby
|
|
273
343
|
|
274
344
|
definition = FitDefinition.new
|
275
345
|
definition.global_message_number = @number
|
276
|
-
definition.setup(
|
346
|
+
definition.setup(self, @field_values_by_name)
|
277
347
|
definition.write(io)
|
278
348
|
end
|
279
349
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
#
|
4
4
|
# = GlobalFitMessages.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, 2020 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
|
@@ -129,8 +129,16 @@ module Fit4Ruby
|
|
129
129
|
field 142, 'uint8', 'undocumented_field_142'
|
130
130
|
field 143, 'uint8', 'undocumented_field_143'
|
131
131
|
field 144, 'enum', 'true_up_enabled'
|
132
|
+
field 145, 'enum', 'undocumented_field_145'
|
132
133
|
field 148, 'enum', 'undocumented_field_148'
|
133
134
|
field 149, 'enum', 'undocumented_field_149'
|
135
|
+
field 151, 'enum', 'undocumented_field_151'
|
136
|
+
field 160, 'enum', 'undocumented_field_160'
|
137
|
+
field 163, 'enum', 'undocumented_field_163'
|
138
|
+
field 164, 'uint8', 'undocumented_field_164'
|
139
|
+
field 167, 'string', 'undocumented_field_167'
|
140
|
+
field 168, 'enum', 'undocumented_field_168'
|
141
|
+
field 170, 'uint8', 'undocumented_field_170'
|
134
142
|
|
135
143
|
message 3, 'user_profile'
|
136
144
|
field 0, 'string', 'friendly_name'
|
@@ -161,14 +169,20 @@ module Fit4Ruby
|
|
161
169
|
field 34, 'uint16', 'undocumented_field_34'
|
162
170
|
field 35, 'uint32', 'undocumented_field_35'
|
163
171
|
field 36, 'uint8', 'undocumented_field_36'
|
164
|
-
field 37, 'uint16', '
|
172
|
+
field 37, 'uint16', 'functional_threshold_speed', :scale => 36, :unit => 'm/s'
|
165
173
|
field 38, 'uint16', 'undocumented_field_38'
|
166
174
|
field 39, 'float32', 'undocumented_field_39'
|
167
175
|
field 40, 'float32', 'undocumented_field_40'
|
168
176
|
field 41, 'uint32', 'time_last_lthr_update', :type => 'date_time'
|
169
177
|
field 42, 'uint32', 'undocumented_field_42'
|
170
178
|
field 43, 'enum', 'undocumented_field_43'
|
179
|
+
field 44, 'uint8', 'undocumented_field_44'
|
180
|
+
field 45, 'uint8z', 'undocumented_field_45'
|
171
181
|
field 47, 'enum', 'undocumented_field_47'
|
182
|
+
field 52, 'enum', 'undocumented_field_52'
|
183
|
+
field 53, 'uint8', 'undocumented_field_53'
|
184
|
+
field 54, 'uint8', 'undocumented_field_54'
|
185
|
+
field 57, 'enum', 'undocumented_field_57'
|
172
186
|
field 253, 'uint32', 'timestamp', :type => 'date_time'
|
173
187
|
|
174
188
|
message 5, 'sdm_profile'
|
@@ -225,6 +239,8 @@ module Fit4Ruby
|
|
225
239
|
field 11, 'enum', 'undocumented_field_11'
|
226
240
|
field 12, 'enum', 'undocumented_field_12'
|
227
241
|
field 13, 'enum', 'undocumented_field_13'
|
242
|
+
field 15, 'uint16', 'undocumented_field_15'
|
243
|
+
field 16, 'uint32', 'undocumented_field_16'
|
228
244
|
field 254, 'uint16', 'message_index'
|
229
245
|
|
230
246
|
message 12, 'sport'
|
@@ -245,6 +261,7 @@ module Fit4Ruby
|
|
245
261
|
field 17, 'enum', 'undocumented_field_17'
|
246
262
|
field 18, 'enum', 'undocumented_field_18'
|
247
263
|
field 19, 'enum', 'undocumented_field_19', :array => true
|
264
|
+
field 21, 'enum', 'undocumented_field_21'
|
248
265
|
|
249
266
|
# Not part of the official ANT SDK doc.
|
250
267
|
message 13, 'undocumented_13'
|
@@ -309,12 +326,20 @@ module Fit4Ruby
|
|
309
326
|
field 65, 'enum', 'undocumented_field_65'
|
310
327
|
field 66, 'enum', 'undocumented_field_66'
|
311
328
|
field 67, 'enum', 'undocumented_field_67'
|
329
|
+
field 68, 'sint32','undocumented_field_68'
|
312
330
|
field 69, 'uint16', 'undocumented_field_69'
|
313
331
|
field 70, 'enum', 'undocumented_field_70'
|
332
|
+
field 71, 'enum', 'undocumented_field_71'
|
333
|
+
field 72, 'enum', 'undocumented_field_72'
|
314
334
|
field 73, 'sint32', 'undocumented_field_73'
|
315
335
|
field 74, 'sint32', 'undocumented_field_74'
|
316
336
|
field 75, 'enum', 'undocumented_field_75'
|
317
337
|
field 76, 'enum', 'undocumented_field_76'
|
338
|
+
field 78, 'enum', 'undocumented_field_78'
|
339
|
+
field 79, 'enum', 'undocumented_field_79'
|
340
|
+
field 81, 'enum', 'undocumented_field_81'
|
341
|
+
field 82, 'enum', 'undocumented_field_82'
|
342
|
+
field 83, 'enum', 'undocumented_field_83'
|
318
343
|
field 254, 'uint16', 'message_index'
|
319
344
|
|
320
345
|
message 18, 'session'
|
@@ -372,7 +397,7 @@ module Fit4Ruby
|
|
372
397
|
field 44, 'uint16', 'pool_length', :scale => 100, :unit => 'm'
|
373
398
|
field 45, 'uint16', 'undefined_value_45'
|
374
399
|
field 46, 'enum', 'pool_length_unit', :dict => 'display_measure'
|
375
|
-
field 47, 'uint16', '
|
400
|
+
field 47, 'uint16', 'num_active_lengths', :unit => 'lengths'
|
376
401
|
field 48, 'uint32', 'total_work', :unit => 'J'
|
377
402
|
field 57, 'sint8', 'avg_temperature', :unit => 'C'
|
378
403
|
field 58, 'sint8', 'max_temperature', :unit => 'C'
|
@@ -445,6 +470,10 @@ module Fit4Ruby
|
|
445
470
|
field 185, 'uint8', 'undocumented_field_185'
|
446
471
|
field 187, 'float32', 'undocumented_field_187'
|
447
472
|
field 188, 'enum', 'undocumented_field_188'
|
473
|
+
field 189, 'uint16', 'undocumented_field_189'
|
474
|
+
field 190, 'uint16', 'undocumented_field_190'
|
475
|
+
field 194, 'uint8', 'undocumented_field_194'
|
476
|
+
field 195, 'uint8', 'undocumented_field_195'
|
448
477
|
field 253, 'uint32', 'timestamp', :type => 'date_time'
|
449
478
|
field 254, 'uint16', 'message_index'
|
450
479
|
|
@@ -496,7 +525,7 @@ module Fit4Ruby
|
|
496
525
|
field 37, 'uint16', 'avg_stroke_distance', :scale => 100, :unit => 'm'
|
497
526
|
field 38, 'enum', 'swim_stroke', :dict => 'swim_stroke'
|
498
527
|
field 39, 'enum', 'sub_sport', :dict => 'sub_sport'
|
499
|
-
field 40, 'uint16', '
|
528
|
+
field 40, 'uint16', 'num_active_lengths', :unit => 'lengths'
|
500
529
|
field 41, 'uint32', 'total_work', :unit => 'J'
|
501
530
|
field 50, 'sint8', 'avg_temperature', :unit => 'C'
|
502
531
|
field 51, 'sint8', 'max_temperature', :unit => 'C'
|
@@ -572,6 +601,7 @@ module Fit4Ruby
|
|
572
601
|
field 13, 'sint8', 'temperature', :unit => 'C'
|
573
602
|
field 14, 'uint32', 'undefined_field_14'
|
574
603
|
field 15, 'uint32', 'undefined_field_15'
|
604
|
+
field 18, 'uint8', 'undefined_field_18'
|
575
605
|
field 29, 'uint32', 'accumulated_power', :unit => 'watts'
|
576
606
|
field 30, 'uint8', 'left_right_balance', :dict => 'left_right_balance'
|
577
607
|
field 39, 'uint16', 'vertical_oscillation', :scale => 10, :unit => 'mm'
|
@@ -598,6 +628,12 @@ module Fit4Ruby
|
|
598
628
|
field 71, 'uint8', 'right_power_phase', :scale => 0.7111111, :unit => 'degrees', :array => true
|
599
629
|
field 72, 'uint8', 'right_power_phase_peak', :scale => 0.7111111, :unit => 'degrees', :array => true
|
600
630
|
field 73, 'uint32', 'enhanced_speed', :scale => 1000, :unit => 'm/s'
|
631
|
+
field 74, 'uint32', 'undefined_value_74'
|
632
|
+
field 75, 'uint32', 'undefined_value_75'
|
633
|
+
field 76, 'uint32', 'undefined_value_76'
|
634
|
+
field 77, 'uint32', 'undefined_value_77'
|
635
|
+
field 79, 'uint32', 'undefined_value_79'
|
636
|
+
field 80, 'uint32', 'undefined_value_80'
|
601
637
|
field 78, 'uint32', 'enhanced_elevation', :scale => 5, :offset => 500, :unit => 'm'
|
602
638
|
field 83, 'uint16', 'vertical_ratio', :scale => 100, :unit => '%' # guessed
|
603
639
|
field 84, 'uint16', 'gct_balance', :scale => 100, :unit => '%' # guessed
|
@@ -605,6 +641,13 @@ module Fit4Ruby
|
|
605
641
|
field 87, 'uint16', 'undefined_value_87' # first seen on F3 FW6.80
|
606
642
|
field 88, 'uint16', 'undefined_value_88' # first seen on F3HR FW3.60
|
607
643
|
field 90, 'sint8', 'performance_condition' # guessed
|
644
|
+
field 100, 'sint32', 'undocumented_field_100'
|
645
|
+
field 101, 'sint32', 'undocumented_field_101'
|
646
|
+
field 107, 'enum', 'undocumented_field_107'
|
647
|
+
field 116, 'uint16', 'undocumented_field_116'
|
648
|
+
field 108, 'uint16', 'respiration_rate', :scale => 100, :unit => 'brpm' # guessed
|
649
|
+
field 135, 'uint8', 'undocumented_field_135'
|
650
|
+
field 136, 'uint8', 'undocumented_field_136'
|
608
651
|
field 253, 'uint32', 'timestamp', :type => 'date_time'
|
609
652
|
|
610
653
|
message 21, 'event'
|
@@ -808,7 +851,7 @@ module Fit4Ruby
|
|
808
851
|
field 10, 'uint8', 'avg_resting_heart_rate', :unit => 'bpm'
|
809
852
|
field 11, 'uint16', 'running_lactate_threshold_heart_rate', :unit => 'bpm'
|
810
853
|
field 12, 'uint16', 'functional_threshold_power', :unit => 'W'
|
811
|
-
field 13, 'uint16', '
|
854
|
+
field 13, 'uint16', 'functional_threshold_speed', :scale => 36, :unit => 'm/s'
|
812
855
|
field 14, 'uint8', 'undocumented_field_14'
|
813
856
|
field 15, 'uint8', 'undocumented_field_15'
|
814
857
|
field 16, 'uint32', 'undocumented_field_16'
|
@@ -816,12 +859,14 @@ module Fit4Ruby
|
|
816
859
|
field 18, 'sint32', 'undocumented_field_18'
|
817
860
|
field 19, 'sint32', 'undocumented_field_19'
|
818
861
|
field 20, 'uint16', 'undocumented_field_20'
|
862
|
+
field 21, 'sint32', 'undocumented_field_21'
|
863
|
+
field 22, 'sint32', 'undocumented_field_22'
|
819
864
|
field 253, 'uint32', 'timestamp', :type => 'date_time'
|
820
865
|
|
821
866
|
message 101, 'length'
|
822
867
|
field 0, 'enum', 'event', :dict => 'event'
|
823
868
|
field 1, 'enum', 'event_type', :dict => 'event_type'
|
824
|
-
field 2, 'uint32', '
|
869
|
+
field 2, 'uint32', 'start_time', :type => 'date_time'
|
825
870
|
field 3, 'uint32', 'total_elapsed_time', :scale => 1000, :unit => 's'
|
826
871
|
field 4, 'uint32', 'total_timer_time', :scale => 1000, :unit => 's'
|
827
872
|
field 5, 'uint16', 'total_strokes', :unit => 'strokes'
|
@@ -833,6 +878,8 @@ module Fit4Ruby
|
|
833
878
|
field 12, 'enum', 'length_type', :dict => 'length_type'
|
834
879
|
field 18, 'uint16', 'player_score'
|
835
880
|
field 19, 'uint16', 'opponent_score'
|
881
|
+
field 20, 'uint16', 'stroke_count', :unit => 'counts'
|
882
|
+
field 21, 'uint16', 'zone_count', :unit => 'counts'
|
836
883
|
field 253, 'uint32', 'timestamp', :type => 'date_time'
|
837
884
|
field 254, 'uint16', 'message_index'
|
838
885
|
|
@@ -901,8 +948,8 @@ module Fit4Ruby
|
|
901
948
|
field 12, 'enum', 'undocumented_field_12'
|
902
949
|
field 13, 'uint8', 'undocumented_field_13'
|
903
950
|
field 14, 'uint16', 'running_lactate_threshold_heart_rate', :unit => 'bpm'
|
904
|
-
field 15, 'uint16', '
|
905
|
-
field 16, 'uint16', '
|
951
|
+
field 15, 'uint16', 'undocumented_field_15'
|
952
|
+
field 16, 'uint16', 'running_lactate_threshold_speed', :scale => 36, :unit => 'm/s'
|
906
953
|
field 17, 'sint8', 'performance_condition'
|
907
954
|
field 18, 'uint8', 'undocumented_field_18'
|
908
955
|
field 19, 'uint8', 'undocumented_field_19'
|
@@ -928,6 +975,12 @@ module Fit4Ruby
|
|
928
975
|
field 39, 'sint32', 'undocumented_field_39'
|
929
976
|
field 40, 'sint32', 'undocumented_field_40'
|
930
977
|
field 41, 'enum', 'undocumented_field_41'
|
978
|
+
field 42, 'uint8', 'undocumented_field_42'
|
979
|
+
field 43, 'sint16', 'undocumented_field_43'
|
980
|
+
field 44, 'sint16', 'undocumented_field_44'
|
981
|
+
field 45, 'sint16', 'undocumented_field_45'
|
982
|
+
field 46, 'uint8', 'undocumented_field_46'
|
983
|
+
field 48, 'uint32', 'undocumented_field_48'
|
931
984
|
field 253, 'uint32', 'timestamp', :type => 'date_time'
|
932
985
|
|
933
986
|
# Not part of the official ANT SDK doc. The message name is guessed and
|
@@ -964,7 +1017,7 @@ module Fit4Ruby
|
|
964
1017
|
field 18, 'uint8z', 'undocumented_field_18'
|
965
1018
|
field 19, 'uint8z', 'undocumented_field_19'
|
966
1019
|
field 20, 'uint8z', 'undocumented_field_20'
|
967
|
-
field 21, 'uint16', '
|
1020
|
+
field 21, 'uint16', 'wheel_size', :unit => 'mm'
|
968
1021
|
field 25, 'uint16', 'undocumented_field_25'
|
969
1022
|
field 26, 'uint16', 'undocumented_field_26'
|
970
1023
|
field 27, 'uint8', 'undocumented_field_27'
|
@@ -992,7 +1045,12 @@ module Fit4Ruby
|
|
992
1045
|
field 48, 'enum', 'undocumented_field_48'
|
993
1046
|
field 50, 'uint8', 'undocumented_field_50'
|
994
1047
|
field 51, 'enum', 'undocumented_field_51'
|
995
|
-
field
|
1048
|
+
# The type of this field changed from 'uint8' to 'enum' in more recent
|
1049
|
+
# devices. No idea why and what the proper selection field should be.
|
1050
|
+
alt_field 52, 'undocumented_field_51' do
|
1051
|
+
field :default, 'uint8', 'undocumented_field_52_0'
|
1052
|
+
field 0, 'enum', 'undocumented_field_52_1'
|
1053
|
+
end
|
996
1054
|
field 53, 'uint8', 'undocumented_field_53'
|
997
1055
|
field 54, 'enum', 'undocumented_field_54'
|
998
1056
|
field 55, 'uint16', 'undocumented_field_55'
|
@@ -1008,8 +1066,14 @@ module Fit4Ruby
|
|
1008
1066
|
field 65, 'uint32', 'undocumented_field_65'
|
1009
1067
|
field 70, 'uint32', 'undocumented_field_70'
|
1010
1068
|
field 71, 'enum', 'undocumented_field_71'
|
1069
|
+
field 73, 'uint16z', 'undocumented_field_73'
|
1011
1070
|
field 254, 'uint16', 'message_index'
|
1012
1071
|
|
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'
|
1076
|
+
|
1013
1077
|
# Not part of the official ANT SDK doc.
|
1014
1078
|
message 188, 'undocumented_188'
|
1015
1079
|
field 0, 'enum', 'undocumented_field_0'
|
@@ -1120,6 +1184,7 @@ module Fit4Ruby
|
|
1120
1184
|
message 269, 'undocumented_269'
|
1121
1185
|
field 0, 'uint8', 'undocumented_field_0'
|
1122
1186
|
field 1, 'uint8', 'undocumented_field_1'
|
1187
|
+
field 2, 'uint8', 'undocumented_field_2'
|
1123
1188
|
field 253, 'uint32', 'timestamp', :type => 'date_time'
|
1124
1189
|
|
1125
1190
|
# Not part of the official ANT SDK doc.
|
@@ -1152,6 +1217,35 @@ module Fit4Ruby
|
|
1152
1217
|
field 252, 'uint8', 'undocumented_field_252'
|
1153
1218
|
field 253, 'uint32', 'timestamp', :type => 'date_time'
|
1154
1219
|
|
1220
|
+
# Not part of the official ANT SDK doc.
|
1221
|
+
message 325, 'undocumented_325'
|
1222
|
+
field 0, 'uint8', 'undocumented_field_0'
|
1223
|
+
field 1, 'uint8', 'undocumented_field_1'
|
1224
|
+
field 2, 'uint8', 'undocumented_field_2'
|
1225
|
+
field 3, 'uint8', 'undocumented_field_3'
|
1226
|
+
field 4, 'uint8', 'undocumented_field_4'
|
1227
|
+
field 5, 'uint8', 'undocumented_field_5'
|
1228
|
+
field 253, 'uint32', 'timestamp', :type => 'date_time'
|
1229
|
+
|
1230
|
+
# Not part of the official ANT SDK doc.
|
1231
|
+
message 326, 'undocumented_326'
|
1232
|
+
field 0, 'uint32', 'undocumented_field_0'
|
1233
|
+
field 1, 'uint32', 'undocumented_field_1'
|
1234
|
+
field 253, 'uint32', 'timestamp', :type => 'date_time'
|
1235
|
+
|
1236
|
+
# Not part of the official ANT SDK doc.
|
1237
|
+
message 327, 'undocumented_327'
|
1238
|
+
field 0, 'uint8', 'undocumented_field_0'
|
1239
|
+
field 1, 'uint8', 'undocumented_field_1'
|
1240
|
+
field 2, 'uint8', 'undocumented_field_2'
|
1241
|
+
field 3, 'uint32', 'undocumented_field_3'
|
1242
|
+
field 4, 'uint32', 'undocumented_field_4'
|
1243
|
+
field 5, 'uint32', 'undocumented_field_5'
|
1244
|
+
field 6, 'enum', 'undocumented_field_6'
|
1245
|
+
field 251, 'byte', 'undocumented_field_251'
|
1246
|
+
field 252, 'uint8', 'undocumented_field_252'
|
1247
|
+
field 253, 'uint32', 'timestamp', :type => 'date_time'
|
1248
|
+
|
1155
1249
|
# Not part of the official ANT SDK doc.
|
1156
1250
|
message 1024, 'undocumented_1024'
|
1157
1251
|
field 0, 'enum', 'undocumented_field_0'
|