lib/fit4ruby/FitDataRecord.rb in fit4ruby-0.0.4 vs lib/fit4ruby/FitDataRecord.rb in fit4ruby-0.0.5

- old
+ new

@@ -22,13 +22,16 @@ def initialize(record_id) @message = GlobalFitMessages.find_by_name(record_id) # Create instance variables that correspond to every field of the # corresponding FIT data record. - @message.fields.each do |field_number, field| - create_instance_variable(field.name) + @message.fields_by_name.each do |name, field| + create_instance_variable(name) end + # Meta fields are additional fields that are not part of the FIT + # specification but are convenient to have. These are typcially + # aggregated or converted values of regular fields. @meta_field_units = {} @timestamp = Time.now end def set_field_values(field_values) @@ -38,49 +41,50 @@ end def set(name, value) ivar_name = '@' + name unless instance_variable_defined?(ivar_name) - Log.warn("Unknown FIT record field '#{ivar_name}'") + Log.warn("Unknown FIT record field '#{name}' in global message " + + "#{@message.name} (#{@message.number}).") return end - instance_variable_set('@' + name, value) + instance_variable_set(ivar_name, value) end def get(name) ivar_name = '@' + name return nil unless instance_variable_defined?(ivar_name) - instance_variable_get('@' + name) + instance_variable_get(ivar_name) end def get_as(name, to_unit) value = respond_to?(name) ? send(name) : get(name) return nil if value.nil? if @meta_field_units.include?(name) unit = @meta_field_units[name] else - field = @message.find_by_name(name) + field = @message.fields_by_name[name] unless (unit = field.opts[:unit]) Log.fatal "Field #{name} has no unit" end end value * conversion_factor(unit, to_unit) end def ==(fdr) - @message.fields.each do |field_number, field| - ivar_name = '@' + field.name + @message.fields_by_name.each do |name, field| + ivar_name = '@' + name v1 = field.fit_to_native(field.native_to_fit( instance_variable_get(ivar_name))) v2 = field.fit_to_native(field.native_to_fit( fdr.instance_variable_get(ivar_name))) unless v1 == v2 - Log.error "#{field.name}: #{v1} != #{v2}" + Log.error "#{name}: #{v1} != #{v2}" return false end end true @@ -89,20 +93,26 @@ def <=>(fdr) @timestamp <=> fdr.timestamp end def write(io, id_mapper) - global_message_number = @message.number + # Construct a GlobalFitMessage object that matches exactly the provided + # set of fields. It does not contain any AltField objects. + fields = {} + @message.fields_by_name.each_key do |name| + fields[name] = instance_variable_get('@' + name) + end + global_fit_message = @message.construct(fields) # Map the global message number to the current local message number. - unless (local_message_number = id_mapper.get_local(global_message_number)) + unless (local_message_number = id_mapper.get_local(global_fit_message)) # If the current dictionary does not contain the global message # number, we need to create a new entry for it. The index in the # dictionary is the local message number. - local_message_number = id_mapper.add_global(global_message_number) + local_message_number = id_mapper.add_global(global_fit_message) # Write the definition of the global message number to the file. - @message.write(io, local_message_number) + global_fit_message.write(io, local_message_number) end # Write data record header. header = FitRecordHeader.new header.normal = 0 @@ -110,19 +120,19 @@ header.local_message_type = local_message_number header.write(io) # Create a BinData::Struct object to store the data record. fields = [] - @message.fields.each do |field_number, field| + global_fit_message.fields_by_number.each do |field_number, field| bin_data_type = FitDefinitionField.fit_type_to_bin_data(field.type) fields << [ bin_data_type, field.name ] end bd = BinData::Struct.new(:endian => :little, :fields => fields) # Fill the BinData::Struct object with the values from the corresponding # instance variables. - @message.fields.each do |field_number, field| + global_fit_message.fields_by_number.each do |field_number, field| iv = "@#{field.name}" if instance_variable_defined?(iv) && !(iv_value = instance_variable_get(iv)).nil? value = field.native_to_fit(iv_value) else @@ -137,10 +147,10 @@ bd.write(io) end def inspect fields = {} - @message.fields.each do |field_number, field| + @message.fields_by_name.each do |name, field| ivar_name = '@' + field.name fields[field.name] = instance_variable_get(ivar_name) end fields.inspect end