fit4ruby 3.3.0 → 3.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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'
|