fit4ruby 2.0.0 → 3.0.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: 52f8b521fc5fd62ec4a5dc424985816b3532d9c4
4
- data.tar.gz: 11575588e41f8a325afb6987b2b0bfa351676e1e
3
+ metadata.gz: b4ee014802983dc12f9d4204e29e1c80d33be729
4
+ data.tar.gz: 7d52d887dea393412752a72974d189452ffea3e3
5
5
  SHA512:
6
- metadata.gz: eee1354180d8870ebf322961e8aace3d01009fa6f06682c46dbb4df83ccf48f54093394f5a9e5201e86c1b5588bd6d6c556e978b308f05a2bd3ee06099f3af67
7
- data.tar.gz: 68a30a48b9fb1832fb1c02bf305b0437f4640825278ef46f57b688cecd00002efbc850268082908ad6591fc9ed32cf46f6221713f110912a1a8c6d08bbbc9407
6
+ metadata.gz: 0d306e3ff6d58837943461a2508c6a81d05043b49eb186e352f273e11b341ffe6b0db92e500d764e327c37f38c5f3a5ec466a8bb8172599dd1df563a3b9a0075
7
+ data.tar.gz: cb7692535f35056b613c8f9e3a334d9690400ec2f614c8e5676af0919cb8132b1a280caa7efcd3c6265044008def7deed8a6e706e4718aad1be57a96b12700f3
@@ -19,6 +19,7 @@ require 'fit4ruby/FileCreator'
19
19
  require 'fit4ruby/DeviceInfo'
20
20
  require 'fit4ruby/SensorSettings'
21
21
  require 'fit4ruby/DataSources'
22
+ require 'fit4ruby/UserData'
22
23
  require 'fit4ruby/UserProfile'
23
24
  require 'fit4ruby/PhysiologicalMetrics'
24
25
  require 'fit4ruby/Session'
@@ -38,7 +39,7 @@ module Fit4Ruby
38
39
 
39
40
  attr_accessor :file_id, :field_descriptions, :developer_data_ids, :epo_data,
40
41
  :file_creator, :device_infos, :sensor_settings, :data_sources,
41
- :user_profiles, :physiological_metrics,
42
+ :user_data, :user_profiles, :physiological_metrics,
42
43
  :sessions, :laps, :records, :hrv,
43
44
  :heart_rate_zones, :events, :personal_records
44
45
 
@@ -58,6 +59,7 @@ module Fit4Ruby
58
59
  @device_infos = []
59
60
  @sensor_settings = []
60
61
  @data_sources = []
62
+ @user_data = []
61
63
  @user_profiles = []
62
64
  @physiological_metrics = []
63
65
  @events = []
@@ -318,7 +320,7 @@ module Fit4Ruby
318
320
  # @param field_values [Hash] A Hash that provides initial values for
319
321
  # certain fields of the FitDataRecord.
320
322
  # @return [DeveloperDataId]
321
- def new_field_description(field_values = {})
323
+ def new_developer_data_id(field_values = {})
322
324
  new_fit_data_record('developer_data_id', field_values)
323
325
  end
324
326
 
@@ -347,12 +349,20 @@ module Fit4Ruby
347
349
  new_fit_data_record('data_sources', field_values)
348
350
  end
349
351
 
352
+ # Add a new UserData to the Activity.
353
+ # @param field_values [Hash] A Hash that provides initial values for
354
+ # certain fields of the FitDataRecord.
355
+ # @return [UserData]
356
+ def new_user_data(field_values = {})
357
+ new_fit_data_record('user_data', field_values)
358
+ end
359
+
350
360
  # Add a new UserProfile to the Activity.
351
361
  # @param field_values [Hash] A Hash that provides initial values for
352
362
  # certain fields of the FitDataRecord.
353
363
  # @return [UserProfile]
354
364
  def new_user_profile(field_values = {})
355
- new_fit_data_record('old_user_profile', field_values)
365
+ new_fit_data_record('user_profile', field_values)
356
366
  end
357
367
 
358
368
  # Add a new PhysiologicalMetrics to the Activity.
@@ -461,7 +471,9 @@ module Fit4Ruby
461
471
  @sensor_settings << (record = SensorSettings.new(field_values))
462
472
  when 'data_sources'
463
473
  @data_sources << (record = DataSources.new(field_values))
464
- when 'old_user_profile'
474
+ when 'user_data'
475
+ @user_data << (record = UserData.new(field_values))
476
+ when 'user_profile'
465
477
  @user_profiles << (record = UserProfile.new(field_values))
466
478
  when 'physiological_metrics'
467
479
  @physiological_metrics <<
@@ -25,9 +25,6 @@ module Fit4Ruby
25
25
  set_field_values(field_values)
26
26
  end
27
27
 
28
- def create_global_definition
29
- end
30
-
31
28
  end
32
29
 
33
30
  end
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = FieldDescription.rb -- Fit4Ruby - FIT file processing library for Ruby
5
5
  #
6
- # Copyright (c) 2017 by Chris Schlaeger <cs@taskjuggler.org>
6
+ # Copyright (c) 2017, 2018 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
@@ -11,6 +11,8 @@
11
11
  #
12
12
 
13
13
  require 'fit4ruby/FitDataRecord'
14
+ require 'fit4ruby/FitDefinitionFieldBase'
15
+ require 'fit4ruby/FitTypeDefs'
14
16
 
15
17
  module Fit4Ruby
16
18
 
@@ -25,7 +27,31 @@ module Fit4Ruby
25
27
  set_field_values(field_values)
26
28
  end
27
29
 
28
- def create_global_definition
30
+ def create_global_definition(fit_entity)
31
+ messages = fit_entity.developer_fit_messages
32
+ unless (gfm = GlobalFitMessages[@native_mesg_num])
33
+ Log.error "Developer field description references unknown global " +
34
+ "message number #{@native_mesg_num}"
35
+ end
36
+
37
+ if @developer_data_index >=
38
+ fit_entity.top_level_record.developer_data_ids.size
39
+ Log.error "Developer data index #{@developer_data_index} is too large"
40
+ end
41
+
42
+ msg = messages[@native_mesg_num] ||
43
+ messages.message(@native_mesg_num, gfm.name)
44
+ unless (@fit_base_type_id & 0x7F) < FIT_TYPE_DEFS.size
45
+ Log.error "fit_base_type_id #{@fit_base_type_id} is too large"
46
+ end
47
+ options = {}
48
+ options[:scale] = @scale if @scale
49
+ options[:offset] = @offset if @offset
50
+ options[:array] = @array if @array
51
+ options[:unit] = @units
52
+ msg.field(@field_definition_number,
53
+ FIT_TYPE_DEFS[@fit_base_type_id & 0x7F][1],
54
+ "_#{@developer_data_index}_#{@field_name}", options)
29
55
  end
30
56
 
31
57
  end
@@ -19,7 +19,8 @@ module Fit4Ruby
19
19
 
20
20
  include Converters
21
21
 
22
- RecordOrder = [ 'old_user_profile', 'device_info', 'data_sources', 'event',
22
+ RecordOrder = [ 'user_data', 'user_profile',
23
+ 'device_info', 'data_sources', 'event',
23
24
  'record', 'lap', 'session', 'heart_rate_zones',
24
25
  'personal_records' ]
25
26
 
@@ -54,10 +54,12 @@ module Fit4Ruby
54
54
  Log.fatal "Illegal architecture value #{architecture.snapshot}"
55
55
  end
56
56
  data_fields.each { |f| f.check }
57
+ developer_fields.each { |f| f.check }
57
58
  end
58
59
 
59
- def FitDefinition::read(io, entity, developer_data_flag)
60
+ def FitDefinition::read(io, entity, developer_data_flag, fit_entity)
60
61
  @@has_developer_data = developer_data_flag != 0
62
+ @@fit_entity = fit_entity
61
63
  super(io)
62
64
  end
63
65
 
@@ -71,6 +73,10 @@ module Fit4Ruby
71
73
  @@has_developer_data
72
74
  end
73
75
 
76
+ def fit_entity
77
+ @@fit_entity
78
+ end
79
+
74
80
  def setup(fit_message_definition)
75
81
  fit_message_definition.fields_by_number.each do |number, f|
76
82
  fdf = FitDefinitionField.new
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = FitDefinitionField.rb -- Fit4Ruby - FIT file processing library for Ruby
5
5
  #
6
- # Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
6
+ # Copyright (c) 2014, 2017, 2018 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
@@ -15,6 +15,7 @@ require 'time'
15
15
  require 'fit4ruby/FitDefinitionFieldBase'
16
16
  require 'fit4ruby/Log'
17
17
  require 'fit4ruby/GlobalFitMessage'
18
+ require 'fit4ruby/FitTypeDefs'
18
19
 
19
20
  module Fit4Ruby
20
21
 
@@ -45,7 +46,7 @@ module Fit4Ruby
45
46
  "choice_#{field_number}"
46
47
  @type = field.respond_to?('type') ? field.type : nil
47
48
 
48
- if @type && (td = @@TypeDefs[checked_base_type_number]) &&
49
+ if @type && (td = FIT_TYPE_DEFS[checked_base_type_number]) &&
49
50
  td[0] != @type
50
51
  Log.warn "#{@global_message_number}:#{@name} must be of type " +
51
52
  "#{@type}, not #{td[0]}"
@@ -10,52 +10,33 @@
10
10
  # published by the Free Software Foundation.
11
11
  #
12
12
 
13
+ require 'fit4ruby/FitTypeDefs'
14
+
13
15
  module Fit4Ruby
14
16
 
15
17
  module FitDefinitionFieldBase
16
18
 
17
- @@TypeDefs = [
18
- # FIT Type, BinData type, undefined value, bytes
19
- [ 'enum', 'uint8', 0xFF, 1 ],
20
- [ 'sint8', 'int8', 0x7F, 1 ],
21
- [ 'uint8', 'uint8', 0xFF, 1 ],
22
- [ 'sint16', 'int16', 0x7FFF, 2 ],
23
- [ 'uint16', 'uint16', 0xFFFF, 2 ],
24
- [ 'sint32', 'int32', 0x7FFFFFFF, 4 ],
25
- [ 'uint32', 'uint32', 0xFFFFFFFF, 4 ],
26
- [ 'string', 'string', '', 0 ],
27
- [ 'float32', 'float', 0xFFFFFFFF, 4 ],
28
- [ 'float63', 'double', 0xFFFFFFFF, 4 ],
29
- [ 'uint8z', 'uint8', 0, 1 ],
30
- [ 'uint16z', 'uint16', 0, 2 ],
31
- [ 'uint32z', 'uint32', 0, 4 ],
32
- [ 'byte', 'uint8', 0xFF, 1 ],
33
- [ 'sint64', 'int64', 0x7FFFFFFFFFFFFFFF, 8 ],
34
- [ 'uint64', 'uint64', 0xFFFFFFFFFFFFFFFF, 8 ],
35
- [ 'uint64z', 'uint64', 0, 8 ]
36
- ]
37
-
38
19
  def FitDefinitionFieldBase::fit_type_to_bin_data(fit_type)
39
- entry = @@TypeDefs.find { |e| e[0] == fit_type }
20
+ entry = FIT_TYPE_DEFS.find { |e| e[0] == fit_type }
40
21
  raise "Unknown fit type #{fit_type}" unless entry
41
22
  entry[1]
42
23
  end
43
24
 
44
25
  def FitDefinitionFieldBase::undefined_value(fit_type)
45
- entry = @@TypeDefs.find { |e| e[0] == fit_type }
26
+ entry = FIT_TYPE_DEFS.find { |e| e[0] == fit_type }
46
27
  raise "Unknown fit type #{fit_type}" unless entry
47
28
  entry[2]
48
29
  end
49
30
 
50
31
  def set_type(fit_type)
51
- idx = @@TypeDefs.index { |x| x[0] == fit_type }
32
+ idx = FIT_TYPE_DEFS.index { |x| x[0] == fit_type }
52
33
  raise "Unknown type #{fit_type}" unless idx
53
34
  self.base_type_number = idx
54
- self.byte_count = @@TypeDefs[idx][3]
35
+ self.byte_count = FIT_TYPE_DEFS[idx][3]
55
36
  end
56
37
 
57
38
  def type(fit_type = false)
58
- @@TypeDefs[checked_base_type_number][fit_type ? 0 : 1]
39
+ FIT_TYPE_DEFS[checked_base_type_number][fit_type ? 0 : 1]
59
40
  end
60
41
 
61
42
  def is_array?
@@ -76,17 +57,17 @@ module Fit4Ruby
76
57
  end
77
58
 
78
59
  def base_type_bytes
79
- @@TypeDefs[checked_base_type_number][3]
60
+ FIT_TYPE_DEFS[checked_base_type_number][3]
80
61
  end
81
62
 
82
63
  def undefined_value
83
- @@TypeDefs[checked_base_type_number][2]
64
+ FIT_TYPE_DEFS[checked_base_type_number][2]
84
65
  end
85
66
 
86
67
  private
87
68
 
88
69
  def checked_base_type_number
89
- if @@TypeDefs.length <= base_type_number.snapshot
70
+ if FIT_TYPE_DEFS.length <= base_type_number.snapshot
90
71
  Log.error "Unknown FIT Base type #{base_type_number.snapshot} in " +
91
72
  "Global FIT Message #{name}"
92
73
  return 0
@@ -95,7 +76,7 @@ module Fit4Ruby
95
76
  end
96
77
 
97
78
  def check_fit_base_type
98
- if @@TypeDefs.length <= base_type_number.snapshot
79
+ if FIT_TYPE_DEFS.length <= base_type_number.snapshot
99
80
  end
100
81
  end
101
82
 
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = FitDeveloperDataFieldDefinition.rb -- Fit4Ruby - FIT file processing library for Ruby
5
5
  #
6
- # Copyright (c) 2017 by Chris Schlaeger <cs@taskjuggler.org>
6
+ # Copyright (c) 2017, 2018 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
@@ -12,6 +12,7 @@
12
12
 
13
13
  require 'bindata'
14
14
  require 'fit4ruby/FitDefinitionFieldBase'
15
+ require 'fit4ruby/FitTypeDefs'
15
16
 
16
17
  module Fit4Ruby
17
18
 
@@ -28,13 +29,44 @@ module Fit4Ruby
28
29
  "#{field_number.snapshot}"
29
30
  end
30
31
 
31
- def bindata_type
32
- fit_definition = parent.parent
33
- if (entry = @@TypeDefs.find { |e| e[3] == size_in_bytes.snapshot })
34
- entry[1]
35
- else
36
- 'uint8'
32
+ def type
33
+ FIT_TYPE_DEFS[checked_base_type_number][1]
34
+ end
35
+
36
+ def base_type_bytes
37
+ FIT_TYPE_DEFS[checked_base_type_number][3]
38
+ end
39
+
40
+ def byte_count
41
+ size_in_bytes
42
+ end
43
+
44
+ private
45
+
46
+ def find_field_definition
47
+ tlr = parent.parent.fit_entity.top_level_record
48
+ field = tlr.field_descriptions.find do |fd|
49
+ fd.field_definition_number == field_number.snapshot &&
50
+ fd.developer_data_index == developer_data_index.snapshot
37
51
  end
52
+ unless field
53
+ Log.error "Unknown developer field #{field_number.snapshot} " +
54
+ "for developer #{developer_data_index.snapshot}"
55
+ end
56
+
57
+ field
58
+ end
59
+
60
+ def checked_base_type_number
61
+ field = find_field_definition
62
+ base_type_number = field.fit_base_type_id & 0x7F
63
+ if FIT_TYPE_DEFS.length <= base_type_number
64
+ Log.error "Unknown FIT Base type #{base_type_number} in " +
65
+ "Global FIT Message #{name}"
66
+ return 0
67
+ end
68
+
69
+ base_type_number
38
70
  end
39
71
 
40
72
  end
@@ -55,7 +55,7 @@ module Fit4Ruby
55
55
  # incremented each time the corresponding record type is found.
56
56
  record_counters = Hash.new { 0 }
57
57
  while io.pos < offset + header.end_pos
58
- record = FitRecord.new(definitions)
58
+ record = FitRecord.new(definitions, entity)
59
59
  record.read(io, entity, filter, record_counters)
60
60
  records << record if filter
61
61
  end
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = FitMessageRecord.rb -- Fit4Ruby - FIT file processing library for Ruby
5
5
  #
6
- # Copyright (c) 2015 by Chris Schlaeger <cs@taskjuggler.org>
6
+ # Copyright (c) 2015, 2016, 2017, 2018 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
@@ -12,6 +12,7 @@
12
12
 
13
13
  require 'fit4ruby/Activity'
14
14
  require 'fit4ruby/Monitoring_B'
15
+ require 'fit4ruby/GlobalFitMessage'
15
16
 
16
17
  module Fit4Ruby
17
18
 
@@ -25,11 +26,12 @@ module Fit4Ruby
25
26
  # objec we need to use to store it for later consumption.
26
27
  class FitFileEntity
27
28
 
28
- attr_reader :top_level_record
29
+ attr_reader :top_level_record, :developer_fit_messages
29
30
 
30
31
  # Create a FitFileEntity.
31
32
  def initialize
32
33
  @top_level_record = nil
34
+ @developer_fit_messages = GlobalFitMessageList.new
33
35
  end
34
36
 
35
37
  # Set what kind of FIT file we are dealing with.
@@ -41,9 +41,16 @@ module Fit4Ruby
41
41
  @message_record = produce(definition)
42
42
  end
43
43
 
44
- def read(io, entity, filter = nil, fields_dump = nil)
44
+ def read(io, entity, filter = nil, fields_dump = nil, fit_entity)
45
45
  @message_record.read(io)
46
46
 
47
+ # Check if we have a developer defined message for this global message
48
+ # number.
49
+ if fit_entity.top_level_record
50
+ developer_fields = fit_entity.top_level_record.field_descriptions
51
+ @dfm = developer_fields[@global_message_number]
52
+ end
53
+
47
54
  if @name == 'file_id'
48
55
  unless (entity_type = @message_record['type'].snapshot)
49
56
  Log.fatal "Corrupted FIT file: file_id record has no type definition"
@@ -63,6 +70,7 @@ module Fit4Ruby
63
70
  f1alt ? 1 : -1
64
71
  end
65
72
 
73
+ #(sorted_fields + @definition.developer_fields).each do |field|
66
74
  sorted_fields.each do |field|
67
75
  value = @message_record[field.name].snapshot
68
76
  # Strings are null byte terminated. There may be more bytes in the
@@ -89,16 +97,10 @@ module Fit4Ruby
89
97
  (field_def ? field_def : field).to_s(value))
90
98
  end
91
99
  end
92
- #@definition.developer_fields.each do |field|
93
- # $stderr.puts " ++ New Developer Field " +
94
- # "#{field.field_number.snapshot} " +
95
- # "Bytes: #{field.size_in_bytes.snapshot} " +
96
- # "Developer ID: #{field.developer_data_index.snapshot}"
97
- #end
98
-
99
- #if @name == 'field_description'
100
- # obj.create_global_definition
101
- #end
100
+
101
+ if @name == 'field_description'
102
+ obj.create_global_definition(fit_entity)
103
+ end
102
104
  end
103
105
 
104
106
  private
@@ -141,26 +143,24 @@ module Fit4Ruby
141
143
 
142
144
  def produce(definition)
143
145
  fields = []
144
- definition.data_fields.each do |field|
146
+ (definition.data_fields.to_a +
147
+ definition.developer_fields.to_a).each do |field|
145
148
  field_def = [ field.type, field.name ]
149
+
150
+ # Some field types need special handling.
146
151
  if field.type == 'string'
147
- # Strings need special handling. We need to also include the length
148
- # of the String.
152
+ # We need to also include the length of the String.
149
153
  field_def << { :read_length => field.total_bytes }
150
154
  elsif field.is_array?
155
+ # For Arrays we have to break them into separte fields.
151
156
  field_def = [ :array, field.name,
152
157
  { :type => field.type.intern,
153
- :initial_length => field.total_bytes /
154
- field.base_type_bytes } ]
158
+ :initial_length =>
159
+ field.total_bytes / field.base_type_bytes } ]
155
160
  end
156
161
  fields << field_def
157
162
  end
158
163
 
159
- definition.developer_fields.each do |field|
160
- field_def = [ field.bindata_type, field.name ]
161
- fields << field_def
162
- end
163
-
164
164
  BinData::Struct.new(:endian => definition.endian, :fields => fields)
165
165
  end
166
166
 
@@ -28,8 +28,12 @@ module Fit4Ruby
28
28
 
29
29
  attr_reader :number
30
30
 
31
- def initialize(definitions)
31
+ def initialize(definitions, fit_entity)
32
32
  @definitions = definitions
33
+ # It's a bit ugly that we have to pass the generated FitFileEntity to
34
+ # the parser classes. But we need to have access to the developer field
35
+ # definitions to parse them properly.
36
+ @fit_entity = fit_entity
33
37
  @name = @number = @fields = nil
34
38
  end
35
39
 
@@ -44,8 +48,8 @@ module Fit4Ruby
44
48
  local_message_type = header.local_message_type.snapshot
45
49
  if header.normal? && header.message_type.snapshot == 1
46
50
  # process definition message
47
- definition = FitDefinition.read(io, entity,
48
- header.developer_data_flag.snapshot)
51
+ definition = FitDefinition.read(
52
+ io, entity, header.developer_data_flag.snapshot, @fit_entity)
49
53
  @definitions[local_message_type] = FitMessageRecord.new(definition)
50
54
  else
51
55
  # process data message
@@ -68,7 +72,7 @@ module Fit4Ruby
68
72
  @fields = []
69
73
  end
70
74
  end
71
- definition.read(io, entity, filter, @fields)
75
+ definition.read(io, entity, filter, @fields, @fit_entity)
72
76
  end
73
77
 
74
78
  self
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = FitTypeDefs.rb -- Fit4Ruby - FIT file processing library for Ruby
5
+ #
6
+ # Copyright (c) 2017, 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
+ module Fit4Ruby
14
+
15
+ FIT_TYPE_DEFS = [
16
+ # FIT Type, BinData type, undefined value, bytes
17
+ [ 'enum', 'uint8', 0xFF, 1 ],
18
+ [ 'sint8', 'int8', 0x7F, 1 ],
19
+ [ 'uint8', 'uint8', 0xFF, 1 ],
20
+ [ 'sint16', 'int16', 0x7FFF, 2 ],
21
+ [ 'uint16', 'uint16', 0xFFFF, 2 ],
22
+ [ 'sint32', 'int32', 0x7FFFFFFF, 4 ],
23
+ [ 'uint32', 'uint32', 0xFFFFFFFF, 4 ],
24
+ [ 'string', 'string', '', 0 ],
25
+ [ 'float32', 'float', 0xFFFFFFFF, 4 ],
26
+ [ 'float63', 'double', 0xFFFFFFFF, 4 ],
27
+ [ 'uint8z', 'uint8', 0, 1 ],
28
+ [ 'uint16z', 'uint16', 0, 2 ],
29
+ [ 'uint32z', 'uint32', 0, 4 ],
30
+ [ 'byte', 'uint8', 0xFF, 1 ],
31
+ [ 'sint64', 'int64', 0x7FFFFFFFFFFFFFFF, 8 ],
32
+ [ 'uint64', 'uint64', 0xFFFFFFFFFFFFFFFF, 8 ],
33
+ [ 'uint64z', 'uint64', 0, 8 ]
34
+ ]
35
+
36
+ end
37
+
@@ -114,7 +114,7 @@ module Fit4Ruby
114
114
  field 12, 'enum', 'hr_setting', :dict => 'display_heart'
115
115
  field 13, 'enum', 'speed_setting', :dict => 'display_measure'
116
116
  field 14, 'enum', 'dist_setting', :dict => 'display_measure'
117
- field 17, 'enum', 'activity_class'
117
+ field 17, 'enum', 'activity_class', :scale => 10
118
118
  field 18, 'enum', 'position_setting', :dict => 'display_position'
119
119
  field 21, 'enum', 'temperature_setting', :dict => 'display_measure'
120
120
  field 24, 'uint8', 'birth_year'
@@ -251,8 +251,8 @@ module Fit4Ruby
251
251
  field 35, 'uint16', 'training_stress_score', :scale => 10, :unit => 'tss'
252
252
  field 36, 'uint16', 'intensity_factor', :scale => 1000, :unit => 'if'
253
253
  field 37, 'uint16', 'left_right_balance', :dict => 'left_right_balance_100'
254
- field 38, 'sint32', 'undocumented_field_38'
255
- field 39, 'sint32', 'undocumented_field_39'
254
+ field 38, 'sint32', 'lap1_lat', :type => 'coordinate' # guessed
255
+ field 39, 'sint32', 'lap1_long', :type => 'coordinate' # guessed
256
256
  field 41, 'uint32', 'avg_stroke_count', :scale => 10, :unit => 'strokes/lap'
257
257
  field 42, 'uint16', 'avg_stroke_distance', :scale => 100, :unit => 'm'
258
258
  field 43, 'enum', 'swim_stroke', :dict => 'swim_stroke'
@@ -433,6 +433,8 @@ module Fit4Ruby
433
433
  field 46, 'uint8', 'right_pedal_smoothness', :scale => 2, :unit => '%'
434
434
  field 47, 'uint8', 'combined_pedal_smoothness', :scale => 2, :unit => '%'
435
435
  field 53, 'uint8', 'fractional_cadence', :scale => 128
436
+ field 54, 'uint16', 'total_hemoglobin_conc', :scale => 100, :unit => 'g/dL'
437
+ field 57, 'uint16', 'saturated_hemoglobin_percent', :scale => 10, :unit => '%'
436
438
  field 61, 'uint16', 'undefined_value_61'
437
439
  field 63, 'uint16', 'undefined_value_63'
438
440
  field 64, 'uint16', 'undefined_value_64'
@@ -629,7 +631,7 @@ module Fit4Ruby
629
631
  field 0, 'uint16', 'time', :array => true, :scale => 1000, :unit => 's'
630
632
 
631
633
  # Not part of the official ANT SDK doc
632
- message 79, 'old_user_profile'
634
+ message 79, 'user_data'
633
635
  field 0, 'uint16', 'metmax', :scale => 1000, :unit => 'MET' # VO2max / 3.5
634
636
  field 1, 'uint8', 'age', :unit => 'years'
635
637
  field 2, 'uint8', 'height', :scale => 100, :unit => 'm'
@@ -807,6 +809,7 @@ module Fit4Ruby
807
809
  field 57, 'uint16', 'undocumented_field_57'
808
810
  field 58, 'enum', 'undocumented_field_58'
809
811
  field 59, 'uint8', 'undocumented_field_59'
812
+ field 62, 'uint8', 'undocumented_field_62'
810
813
  field 254, 'uint16', 'message_index'
811
814
 
812
815
  message 206, 'field_description'
@@ -844,12 +847,12 @@ module Fit4Ruby
844
847
  field 1, 'uint16', 'lap_index'
845
848
  field 2, 'uint32', 'time_in_hr_zone', :array => true, :scale => 1000, :unit => 's'
846
849
  field 5, 'uint32', 'undocumented_field_5'
847
- field 6, 'uint8', 'heart_rate_zones', :array => true
850
+ field 6, 'uint8', 'heart_rate_zones', :array => true, :unit => 'bpm'
848
851
  field 9, 'uint16', 'undocumented_field_9'
849
852
  field 10, 'enum', 'undocumented_field_10'
850
- field 11, 'uint8', 'max_heart_rate'
851
- field 12, 'uint8', 'resting_heart_rate'
852
- field 13, 'uint8', 'undocumented_field_13'
853
+ field 11, 'uint8', 'max_heart_rate', :unit => 'bpm'
854
+ field 12, 'uint8', 'resting_heart_rate', :unit => 'bpm'
855
+ field 13, 'uint8', 'lactate_threshold_heart_rate', :unit => 'bpm'
853
856
  field 14, 'enum', 'undocumented_field_14'
854
857
  field 15, 'uint16', 'undocumented_field_15'
855
858
  field 253, 'uint32', 'timestamp', :type => 'date_time'
@@ -25,8 +25,8 @@ module Fit4Ruby
25
25
  # record structures used in the FIT file.
26
26
  class Monitoring_B < FitDataRecord
27
27
 
28
- attr_accessor :file_id, :device_infos, :software, :monitoring_infos,
29
- :monitorings
28
+ attr_accessor :file_id, :field_descriptions, :device_infos, :software,
29
+ :monitoring_infos, :monitorings
30
30
 
31
31
  # Create a new Monitoring_B object.
32
32
  # @param field_values [Hash] A Hash that provides initial values for
@@ -36,6 +36,7 @@ module Fit4Ruby
36
36
  @num_sessions = 0
37
37
 
38
38
  @file_id = FileId.new
39
+ @field_descriptions = []
39
40
  @device_infos = []
40
41
  @softwares = nil
41
42
  @monitoring_infos = []
@@ -14,7 +14,7 @@ require 'fit4ruby/FitDataRecord'
14
14
 
15
15
  module Fit4Ruby
16
16
 
17
- # This class corresponds to the old_user_profile FIT message.
17
+ # This class corresponds to the physiological_metrics FIT message.
18
18
  class PhysiologicalMetrics < FitDataRecord
19
19
 
20
20
  # Create a new PhysiologicalMetrics object.
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = UserData.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 old_user_profile FIT message.
18
+ class UserData < FitDataRecord
19
+
20
+ # Create a new UserData object.
21
+ # @param field_values [Hash] Hash that provides initial values for certain
22
+ # fields.
23
+ def initialize(field_values = {})
24
+ super('user_data')
25
+ set_field_values(field_values)
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+
32
+
@@ -21,7 +21,7 @@ module Fit4Ruby
21
21
  # @param field_values [Hash] Hash that provides initial values for certain
22
22
  # fields.
23
23
  def initialize(field_values = {})
24
- super('old_user_profile')
24
+ super('user_profile')
25
25
  set_field_values(field_values)
26
26
  end
27
27
 
@@ -1,4 +1,4 @@
1
1
  module Fit4Ruby
2
2
  # The version number of the library.
3
- VERSION = '2.0.0'
3
+ VERSION = '3.0.0'
4
4
  end
@@ -20,9 +20,9 @@ describe Fit4Ruby do
20
20
  ts = Time.now
21
21
  a = Fit4Ruby::Activity.new
22
22
  a.total_timer_time = 30 * 60.0
23
- a.new_user_profile({ :age => 33, :height => 1.78, :weight => 73.0,
24
- :gender => 'male', :activity_class => 4.0,
25
- :max_hr => 178 })
23
+ a.new_user_data({ :age => 33, :height => 1.78, :weight => 73.0,
24
+ :gender => 'male', :activity_class => 4.0,
25
+ :max_hr => 178 })
26
26
 
27
27
  a.new_event({ :event => 'timer', :event_type => 'start_time' })
28
28
  a.new_device_info({ :timestamp => ts,
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: 2.0.0
4
+ version: 3.0.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-01-17 00:00:00.000000000 Z
11
+ date: 2018-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bindata
@@ -108,6 +108,7 @@ files:
108
108
  - lib/fit4ruby/FitMessageRecord.rb
109
109
  - lib/fit4ruby/FitRecord.rb
110
110
  - lib/fit4ruby/FitRecordHeader.rb
111
+ - lib/fit4ruby/FitTypeDefs.rb
111
112
  - lib/fit4ruby/GeoMath.rb
112
113
  - lib/fit4ruby/GlobalFitDictList.rb
113
114
  - lib/fit4ruby/GlobalFitDictionaries.rb
@@ -127,6 +128,7 @@ files:
127
128
  - lib/fit4ruby/SensorSettings.rb
128
129
  - lib/fit4ruby/Session.rb
129
130
  - lib/fit4ruby/Software.rb
131
+ - lib/fit4ruby/UserData.rb
130
132
  - lib/fit4ruby/UserProfile.rb
131
133
  - lib/fit4ruby/version.rb
132
134
  - spec/FileNameCoder_spec.rb