Class: Fitreader::Record

Inherits:
Object
  • Object
show all
Defined in:
lib/fitreader/record.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(definition, bytes) ⇒ Record

Returns a new instance of Record.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/fitreader/record.rb', line 7

def initialize(definition, bytes)
  # definition = definition
  @fields = {}
  @error_fields = {}

  unless definition.fit_msg.nil?
    start = 0
    definition.field_definitions.each do |f|
      raw = bytes[start...start+=f.size]
      b = Static.base[f.base_num]
      data = unpack_data(f, b, raw)
      begin
        process_data(f.def_num, b[:invalid], data, definition)
      rescue UnknownFieldTypeError => error
        push_error error.reason, error.field, error.data
        # puts error unless error.reason == :invalid
      end
    end

    if definition.global_num == 21
      process_event
    elsif definition.global_num == 23
      process_deviceinfo
    end
  else
    msg = "no known message type: #{definition.global_num}"
    raise UnknownMessageTypeError.new, msg, caller
  end
end

Instance Attribute Details

#definitionObject (readonly)

Returns the value of attribute definition.



6
7
8
# File 'lib/fitreader/record.rb', line 6

def definition
  @definition
end

#error_fieldsObject (readonly)

Returns the value of attribute error_fields.



6
7
8
# File 'lib/fitreader/record.rb', line 6

def error_fields
  @error_fields
end

#fieldsObject (readonly)

Returns the value of attribute fields.



6
7
8
# File 'lib/fitreader/record.rb', line 6

def fields
  @fields
end

Instance Method Details

#get_raw(key) ⇒ Object



120
121
122
123
124
125
126
127
# File 'lib/fitreader/record.rb', line 120

def get_raw(key)
  if key.class == String
    f = @fields.values.detect{|v| v.name == key}
  elsif key.class == Integer
    f = @fields[key]
  end
  return !f.nil? ? f.raw_value : nil
end

#get_val(key) ⇒ Object



111
112
113
114
115
116
117
118
# File 'lib/fitreader/record.rb', line 111

def get_val(key)
  if key.class == String
    f = @fields.values.detect{|v| v.name == key}
  elsif key.class == Integer
    f = @fields[key]
  end
  return f != nil ? f.value : nil
end

#process_data(fieldDefNum, invalid, data, definition) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/fitreader/record.rb', line 55

def process_data(fieldDefNum, invalid, data, definition)
  field_def = definition.fit_msg[fieldDefNum]
  unless field_def.nil?
    # populate invalid
    if data.is_a?(Array)
      data = data.select{ |x| x != invalid } if data.is_a?(Array)
      invalid = data.empty?
    else
      invalid = data == invalid
    end

    unless invalid
      @fields[fieldDefNum] = FieldData.new(fieldDefNum, data, field_def)
    else
      msg = "invalid field data (#{data}) processed for field number [#{fieldDefNum}::#{field_def[:name]}] in message (#{definition.global_num}::#{definition.name})"
      raise UnknownFieldTypeError.new(definition, fieldDefNum, data, :invalid), msg, caller
    end
  else
    msg = "invalid field [#{fieldDefNum}] encountered for message [#{definition.global_num}::#{definition.name}] with data [#{data}]"
    raise UnknownFieldTypeError.new(definition, fieldDefNum, data, :unknown), msg, caller
  end
end

#push_error(reason, field, data) ⇒ Object



82
83
84
# File 'lib/fitreader/record.rb', line 82

def push_error(reason, field, data)
  (@error_fields[reason] ||= {})[field] = data
end

#temporal?Boolean

Returns:

  • (Boolean)


78
79
80
# File 'lib/fitreader/record.rb', line 78

def temporal?
  fields.key?(253)
end

#to_sObject



129
130
131
132
133
134
135
# File 'lib/fitreader/record.rb', line 129

def to_s
  s = "#{name} (#{definition.global_num})\n"
  @fields.each do |_, v|
    s += v.to_s
  end
  "#{s}\n"
end

#typeObject

:file_id 1 :user_profile 1 :zones_target 1 :session 1 :lap 1 :record 2899 :event 73 :source 58 :device_info 14 :activity 1 :file_creator 1 :training_file 1 :battery_info 40 :sensor_info 3



100
101
102
103
104
105
106
107
108
109
# File 'lib/fitreader/record.rb', line 100

def type
  case definition.name
  when :file_id, :user_profile, :zones_target, :session
    :ride
  when condition
    :lap
  else
    :time
  end
end

#unpack_data(f, b, raw) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/fitreader/record.rb', line 37

def unpack_data(f, b, raw)
  if !b[:unpack_type].nil?
    if b[:size] != f.size && f.base_num != 7
      data = []
      s = 0
      (f.size/b[:size]).times do |_|
        data.push(raw[s..s+=b[:size]].unpack(b[:unpack_type]).first)
      end
    else
      data = raw.unpack(b[:unpack_type]).first
    end
  elsif f.base_num.zero?
    data = raw.unpack('C').first
  else
    data = raw.split(/\0/)[0]
  end
end