fit4ruby 2.0.0 → 3.0.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 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