fit4ruby 3.7.0 → 3.8.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 +4 -4
- data/fit4ruby.gemspec +1 -1
- data/lib/fit4ruby/Activity.rb +94 -55
- data/lib/fit4ruby/BDFieldNameTranslator.rb +36 -0
- data/lib/fit4ruby/FDR_DevField_Extension.rb +81 -0
- data/lib/fit4ruby/FieldDescription.rb +22 -10
- data/lib/fit4ruby/FileId.rb +2 -1
- data/lib/fit4ruby/FitDataRecord.rb +83 -30
- data/lib/fit4ruby/FitDefinition.rb +11 -4
- data/lib/fit4ruby/FitDefinitionField.rb +4 -4
- 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 +23 -18
- data/lib/fit4ruby/FitRecord.rb +2 -1
- data/lib/fit4ruby/FitTypeDefs.rb +2 -2
- data/lib/fit4ruby/GlobalFitMessage.rb +79 -14
- data/lib/fit4ruby/GlobalFitMessages.rb +2 -2
- data/lib/fit4ruby/Lap.rb +10 -1
- data/lib/fit4ruby/Record.rb +11 -2
- data/lib/fit4ruby/version.rb +1 -1
- data/spec/FitFile_spec.rb +198 -100
- metadata +12 -11
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 29f7e7354dfe1a0b9cfa30849b6131693deba24858f7cf6ec0745b923bcbd86a
         | 
| 4 | 
            +
              data.tar.gz: 24aa3e37347db57f6e26078118bc20da45692097c395a21ad480702ebb66f0c6
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 2638207885da4f16185df8ef71d7999855b2f9199be60d1156727473a855a01039ce0fd36faaa7093696f4576247f78c208c2628df200da2d5761832ebc46142
         | 
| 7 | 
            +
              data.tar.gz: a7fd64132dba6d6594e9ade153e1596d66ef7f47c7846f79ad7971240ac8b6dfb0b457474e80dcd369faadc88dc79fee17233a3c3cc4cfe2d40f40f01df28e47
         | 
    
        data/fit4ruby.gemspec
    CHANGED
    
    | @@ -24,7 +24,7 @@ EOT | |
| 24 24 | 
             
              spec.require_paths = ["lib"]
         | 
| 25 25 | 
             
              spec.required_ruby_version = '>=2.0'
         | 
| 26 26 |  | 
| 27 | 
            -
              spec.add_dependency('bindata', ' | 
| 27 | 
            +
              spec.add_dependency('bindata', '~>2.4.8')
         | 
| 28 28 | 
             
              spec.add_development_dependency('yard', '~>0.9.20')
         | 
| 29 29 | 
             
              spec.add_development_dependency('rake', '~>12.0.0')
         | 
| 30 30 | 
             
              spec.add_development_dependency('bundler', '>=1.6.4')
         | 
    
        data/lib/fit4ruby/Activity.rb
    CHANGED
    
    | @@ -3,7 +3,7 @@ | |
| 3 3 | 
             
            #
         | 
| 4 4 | 
             
            # = Activity.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
         | 
| @@ -33,45 +33,65 @@ require 'fit4ruby/PersonalRecords' | |
| 33 33 |  | 
| 34 34 | 
             
            module Fit4Ruby
         | 
| 35 35 |  | 
| 36 | 
            -
              #  | 
| 37 | 
            -
              #  | 
| 38 | 
            -
              #  | 
| 36 | 
            +
              # Activity files are arguably the most common type of FIT file. The Activity
         | 
| 37 | 
            +
              # class represents the top-level structure of an activity FIT file.
         | 
| 38 | 
            +
              # It holds references to all other data structures. Each of the objects it
         | 
| 39 | 
            +
              # references are direct equivalents of the message record structures used in
         | 
| 40 | 
            +
              # the FIT file.
         | 
| 39 41 | 
             
              class Activity < FitDataRecord
         | 
| 40 42 |  | 
| 41 | 
            -
                 | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 43 | 
            +
                # These symbols are a complete list of all the sub-sections that an
         | 
| 44 | 
            +
                # activity FIT file may contain. This list is used to generate accessors,
         | 
| 45 | 
            +
                # instance variables and other sections of code. Some are just simple
         | 
| 46 | 
            +
                # instance variables, but the majority can appear multiple times and hence
         | 
| 47 | 
            +
                # are stored in an Array.
         | 
| 48 | 
            +
                FILE_SECTIONS = [
         | 
| 49 | 
            +
                  :file_id,
         | 
| 50 | 
            +
                  :file_creator,
         | 
| 51 | 
            +
                  :events,
         | 
| 52 | 
            +
                  :device_infos,
         | 
| 53 | 
            +
                  :data_sources,
         | 
| 54 | 
            +
                  :epo_data,
         | 
| 55 | 
            +
                  :user_profiles,
         | 
| 56 | 
            +
                  :user_data,
         | 
| 57 | 
            +
                  :sensor_settings,
         | 
| 58 | 
            +
                  :developer_data_ids,
         | 
| 59 | 
            +
                  :field_descriptions,
         | 
| 60 | 
            +
                  :records,
         | 
| 61 | 
            +
                  :hrv,
         | 
| 62 | 
            +
                  :laps,
         | 
| 63 | 
            +
                  :lengths,
         | 
| 64 | 
            +
                  :heart_rate_zones,
         | 
| 65 | 
            +
                  :physiological_metrics,
         | 
| 66 | 
            +
                  :sessions,
         | 
| 67 | 
            +
                  :personal_records
         | 
| 68 | 
            +
                ]
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                attr_accessor *FILE_SECTIONS
         | 
| 46 71 |  | 
| 47 72 | 
             
                # Create a new Activity object.
         | 
| 48 73 | 
             
                # @param field_values [Hash] A Hash that provides initial values for
         | 
| 49 74 | 
             
                #        certain fields of the FitDataRecord.
         | 
| 50 75 | 
             
                def initialize(field_values = {})
         | 
| 51 76 | 
             
                  super('activity')
         | 
| 52 | 
            -
                  @meta_field_units['total_gps_distance'] = 'm'
         | 
| 53 | 
            -
                  @num_sessions = 0
         | 
| 54 77 |  | 
| 55 | 
            -
                   | 
| 56 | 
            -
                   | 
| 57 | 
            -
                   | 
| 78 | 
            +
                  # The variables hold references to other parts of the FIT file. These
         | 
| 79 | 
            +
                  # can either be direct references to a certain FIT file section or an
         | 
| 80 | 
            +
                  # Array in case the section can appear multiple times in the FIT file.
         | 
| 81 | 
            +
                  @file_id = new_file_id()
         | 
| 82 | 
            +
                  @file_creator = new_file_creator()
         | 
| 58 83 | 
             
                  @epo_data = nil
         | 
| 59 | 
            -
                   | 
| 60 | 
            -
                   | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 65 | 
            -
                   | 
| 66 | 
            -
                  @events = []
         | 
| 67 | 
            -
                  @sessions = []
         | 
| 68 | 
            -
                  @laps = []
         | 
| 69 | 
            -
                  @lengths = []
         | 
| 70 | 
            -
                  @records = []
         | 
| 71 | 
            -
                  @hrv = []
         | 
| 72 | 
            -
                  @heart_rate_zones = []
         | 
| 73 | 
            -
                  @personal_records = []
         | 
| 84 | 
            +
                  # Initialize the remaining variables as empty Array.
         | 
| 85 | 
            +
                  FILE_SECTIONS.each do |fs|
         | 
| 86 | 
            +
                    ivar_name = '@' + fs.to_s
         | 
| 87 | 
            +
                    unless instance_variable_defined?(ivar_name)
         | 
| 88 | 
            +
                      instance_variable_set(ivar_name, [])
         | 
| 89 | 
            +
                    end
         | 
| 90 | 
            +
                  end
         | 
| 74 91 |  | 
| 92 | 
            +
                  # The following variables hold derived or auxilliary information that
         | 
| 93 | 
            +
                  # are not directly part of the FIT file.
         | 
| 94 | 
            +
                  @meta_field_units['total_gps_distance'] = 'm'
         | 
| 75 95 | 
             
                  @cur_session_laps = []
         | 
| 76 96 |  | 
| 77 97 | 
             
                  @cur_lap_records = []
         | 
| @@ -99,11 +119,6 @@ module Fit4Ruby | |
| 99 119 | 
             
                  end
         | 
| 100 120 | 
             
                  @device_infos.each.with_index { |d, index| d.check(index) }
         | 
| 101 121 | 
             
                  @sensor_settings.each.with_index { |s, index| s.check(index) }
         | 
| 102 | 
            -
                  unless @num_sessions == @sessions.count
         | 
| 103 | 
            -
                    Log.fatal "Activity record requires #{@num_sessions}, but "
         | 
| 104 | 
            -
                              "#{@sessions.length} session records were found in the "
         | 
| 105 | 
            -
                              "FIT file."
         | 
| 106 | 
            -
                  end
         | 
| 107 122 |  | 
| 108 123 | 
             
                  # Records must have consecutively growing timestamps and distances.
         | 
| 109 124 | 
             
                  ts = Time.parse('1989-12-31')
         | 
| @@ -308,13 +323,17 @@ module Fit4Ruby | |
| 308 323 | 
             
                def write(io, id_mapper)
         | 
| 309 324 | 
             
                  @file_id.write(io, id_mapper)
         | 
| 310 325 | 
             
                  @file_creator.write(io, id_mapper)
         | 
| 326 | 
            +
                  @epo_data.write(io, id_mapper) if @epo_data
         | 
| 311 327 |  | 
| 312 | 
            -
                   | 
| 313 | 
            -
             | 
| 314 | 
            -
             | 
| 315 | 
            -
             | 
| 316 | 
            -
             | 
| 317 | 
            -
             | 
| 328 | 
            +
                  ary_ivars = []
         | 
| 329 | 
            +
                  FILE_SECTIONS.each do |fs|
         | 
| 330 | 
            +
                    ivar_name = '@' + fs.to_s
         | 
| 331 | 
            +
                    if (ivar = instance_variable_get(ivar_name)) && ivar.respond_to?(:sort)
         | 
| 332 | 
            +
                      ary_ivars += ivar
         | 
| 333 | 
            +
                    end
         | 
| 334 | 
            +
                  end
         | 
| 335 | 
            +
             | 
| 336 | 
            +
                  ary_ivars.sort.each do |s|
         | 
| 318 337 | 
             
                    s.write(io, id_mapper)
         | 
| 319 338 | 
             
                  end
         | 
| 320 339 | 
             
                  super
         | 
| @@ -464,18 +483,17 @@ module Fit4Ruby | |
| 464 483 | 
             
                # @return [TrueClass/FalseClass] true if both Activities are equal,
         | 
| 465 484 | 
             
                # otherwise false.
         | 
| 466 485 | 
             
                def ==(a)
         | 
| 467 | 
            -
                  super(a) | 
| 468 | 
            -
             | 
| 469 | 
            -
             | 
| 470 | 
            -
                    @ | 
| 471 | 
            -
                     | 
| 472 | 
            -
                     | 
| 473 | 
            -
             | 
| 474 | 
            -
                     | 
| 475 | 
            -
             | 
| 476 | 
            -
             | 
| 477 | 
            -
             | 
| 478 | 
            -
                    @sessions == a.sessions && personal_records == a.personal_records
         | 
| 486 | 
            +
                  return false unless super(a)
         | 
| 487 | 
            +
             | 
| 488 | 
            +
                  FILE_SECTIONS.each do |fs|
         | 
| 489 | 
            +
                    ivar_name = '@' + fs.to_s
         | 
| 490 | 
            +
                    ivar = instance_variable_get(ivar_name)
         | 
| 491 | 
            +
                    a_ivar = a.instance_variable_get(ivar_name)
         | 
| 492 | 
            +
             | 
| 493 | 
            +
                    return false unless ivar == a_ivar
         | 
| 494 | 
            +
                  end
         | 
| 495 | 
            +
             | 
| 496 | 
            +
                  true
         | 
| 479 497 | 
             
                end
         | 
| 480 498 |  | 
| 481 499 | 
             
                # Create a new FitDataRecord.
         | 
| @@ -521,7 +539,6 @@ module Fit4Ruby | |
| 521 539 | 
             
                      # Ensure that all previous records have been assigned to a lap.
         | 
| 522 540 | 
             
                      record = create_new_lap(lap_field_values)
         | 
| 523 541 | 
             
                    end
         | 
| 524 | 
            -
                    @num_sessions += 1
         | 
| 525 542 | 
             
                    @sessions << (record = Session.new(@cur_session_laps, @lap_counter,
         | 
| 526 543 | 
             
                                                       field_values))
         | 
| 527 544 | 
             
                    @cur_session_laps = []
         | 
| @@ -530,7 +547,7 @@ module Fit4Ruby | |
| 530 547 | 
             
                  when 'length'
         | 
| 531 548 | 
             
                    record = create_new_length(field_values)
         | 
| 532 549 | 
             
                  when 'record'
         | 
| 533 | 
            -
                    record = Record.new(field_values)
         | 
| 550 | 
            +
                    record = Record.new(self, field_values)
         | 
| 534 551 | 
             
                    @cur_lap_records << record
         | 
| 535 552 | 
             
                    @cur_length_records << record
         | 
| 536 553 | 
             
                    @records << record
         | 
| @@ -547,10 +564,31 @@ module Fit4Ruby | |
| 547 564 | 
             
                  record
         | 
| 548 565 | 
             
                end
         | 
| 549 566 |  | 
| 567 | 
            +
                def export
         | 
| 568 | 
            +
                  # Collect all records in a consistent order.
         | 
| 569 | 
            +
                  records = []
         | 
| 570 | 
            +
                  FILE_SECTIONS.each do |fs|
         | 
| 571 | 
            +
                    ivar_name = '@' + fs.to_s
         | 
| 572 | 
            +
                    ivar = instance_variable_get(ivar_name)
         | 
| 573 | 
            +
             | 
| 574 | 
            +
                    next unless ivar
         | 
| 575 | 
            +
             | 
| 576 | 
            +
                    if ivar.respond_to?(:sort) and ivar.respond_to?(:empty?)
         | 
| 577 | 
            +
                      records += ivar.sort unless ivar.empty?
         | 
| 578 | 
            +
                    else
         | 
| 579 | 
            +
                      records << ivar if ivar
         | 
| 580 | 
            +
                    end
         | 
| 581 | 
            +
                  end
         | 
| 582 | 
            +
             | 
| 583 | 
            +
                  records.map do |record|
         | 
| 584 | 
            +
                    record.export
         | 
| 585 | 
            +
                  end
         | 
| 586 | 
            +
                end
         | 
| 587 | 
            +
             | 
| 550 588 | 
             
                private
         | 
| 551 589 |  | 
| 552 590 | 
             
                def create_new_lap(field_values)
         | 
| 553 | 
            -
                  lap = Lap.new(@cur_lap_records, @laps.last,
         | 
| 591 | 
            +
                  lap = Lap.new(self, @cur_lap_records, @laps.last,
         | 
| 554 592 | 
             
                                field_values,
         | 
| 555 593 | 
             
                                @length_counter, @cur_lap_lengths)
         | 
| 556 594 | 
             
                  lap.message_index = @lap_counter - 1
         | 
| @@ -573,6 +611,7 @@ module Fit4Ruby | |
| 573 611 |  | 
| 574 612 | 
             
                  length
         | 
| 575 613 | 
             
                end
         | 
| 614 | 
            +
             | 
| 576 615 | 
             
              end
         | 
| 577 616 |  | 
| 578 617 | 
             
            end
         | 
| @@ -0,0 +1,36 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby -w
         | 
| 2 | 
            +
            # encoding: UTF-8
         | 
| 3 | 
            +
            #
         | 
| 4 | 
            +
            # = FitDataRecord.rb -- Fit4Ruby - FIT file processing library for Ruby
         | 
| 5 | 
            +
            #
         | 
| 6 | 
            +
            # Copyright (c) 2020 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 | 
            +
              # Some FIT message field names conflict with BinData reserved names. We use
         | 
| 16 | 
            +
              # this translation method to map the conflicting names to BinData compatible
         | 
| 17 | 
            +
              # names.
         | 
| 18 | 
            +
              module BDFieldNameTranslator
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                BD_DICT =  {
         | 
| 21 | 
            +
                  'array' => '_array',
         | 
| 22 | 
            +
                  'type' => '_type'
         | 
| 23 | 
            +
                }
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def to_bd_field_name(name)
         | 
| 26 | 
            +
                  if (bd_name = BD_DICT[name])
         | 
| 27 | 
            +
                    return bd_name
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  name
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            end
         | 
| 36 | 
            +
             | 
| @@ -0,0 +1,81 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby -w
         | 
| 2 | 
            +
            # encoding: UTF-8
         | 
| 3 | 
            +
            #
         | 
| 4 | 
            +
            # = FDR_DevField_Extension.rb -- Fit4Ruby - FIT file processing library for Ruby
         | 
| 5 | 
            +
            #
         | 
| 6 | 
            +
            # Copyright (c) 2020 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 | 
            +
              # This module extends FitDataRecord derived classes in case they have
         | 
| 16 | 
            +
              # developer fields.
         | 
| 17 | 
            +
              module FDR_DevField_Extension
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def create_dev_field_instance_variables
         | 
| 20 | 
            +
                  # Create instance variables for developer fields
         | 
| 21 | 
            +
                  @dev_field_descriptions = {}
         | 
| 22 | 
            +
                  @top_level_record.field_descriptions.each do |field_description|
         | 
| 23 | 
            +
                    # Only create instance variables if the FieldDescription is for this
         | 
| 24 | 
            +
                    # message number.
         | 
| 25 | 
            +
                    if field_description.native_mesg_num == @message.number
         | 
| 26 | 
            +
                      name = field_description.full_field_name(@top_level_record.
         | 
| 27 | 
            +
                                                               developer_data_ids)
         | 
| 28 | 
            +
                      create_instance_variable(name)
         | 
| 29 | 
            +
                      @dev_field_descriptions[name] = field_description
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def each_developer_field
         | 
| 35 | 
            +
                  @top_level_record.field_descriptions.each do |field_description|
         | 
| 36 | 
            +
                    # Only create instance variables if the FieldDescription is for this
         | 
| 37 | 
            +
                    # message number.
         | 
| 38 | 
            +
                    if field_description.native_mesg_num == @message.number
         | 
| 39 | 
            +
                      name = field_description.full_field_name(@top_level_record.
         | 
| 40 | 
            +
                                                               developer_data_ids)
         | 
| 41 | 
            +
                      yield(field_description, instance_variable_get('@' + name))
         | 
| 42 | 
            +
                    end
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                def get_unit_by_name(name)
         | 
| 47 | 
            +
                  if /[A-Za-z_]+_[A-F0-9]{16}/ =~ name
         | 
| 48 | 
            +
                    @dev_field_descriptions[name].units
         | 
| 49 | 
            +
                  else
         | 
| 50 | 
            +
                    super
         | 
| 51 | 
            +
                  end
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                def export
         | 
| 55 | 
            +
                  message = super
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  each_developer_field do |field_description, ivar|
         | 
| 58 | 
            +
                    field = field_description.message.fields_by_number[
         | 
| 59 | 
            +
                      field_description.native_field_num]
         | 
| 60 | 
            +
                    fit_value = field.native_to_fit(ivar)
         | 
| 61 | 
            +
                    unless field.is_undefined?(fit_value)
         | 
| 62 | 
            +
                      fld = {
         | 
| 63 | 
            +
                        'number' => field_description.native_field_num | 128,
         | 
| 64 | 
            +
                        'value' => field.fit_to_native(fit_value),
         | 
| 65 | 
            +
                        #'human' => field.to_human(fit_value),
         | 
| 66 | 
            +
                        'type' => field.type
         | 
| 67 | 
            +
                      }
         | 
| 68 | 
            +
                      fld['unit'] = field.opts[:unit] if field.opts[:unit]
         | 
| 69 | 
            +
                      fld['scale'] = field.opts[:scale] if field.opts[:scale]
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                      message['fields'][field.name] = fld
         | 
| 72 | 
            +
                    end
         | 
| 73 | 
            +
                  end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                  message
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
            end
         | 
| 81 | 
            +
             | 
| @@ -3,7 +3,7 @@ | |
| 3 3 | 
             
            #
         | 
| 4 4 | 
             
            # = FieldDescription.rb -- Fit4Ruby - FIT file processing library for Ruby
         | 
| 5 5 | 
             
            #
         | 
| 6 | 
            -
            # Copyright (c) 2017, 2018, 2019 by Chris Schlaeger <cs@taskjuggler.org>
         | 
| 6 | 
            +
            # Copyright (c) 2017, 2018, 2019, 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
         | 
| @@ -25,6 +25,24 @@ module Fit4Ruby | |
| 25 25 | 
             
                def initialize(field_values = {})
         | 
| 26 26 | 
             
                  super('field_description')
         | 
| 27 27 | 
             
                  set_field_values(field_values)
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  @full_field_name = nil
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                def full_field_name(developer_data_ids)
         | 
| 33 | 
            +
                  return @full_field_name if @full_field_name
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  if @developer_data_index >=
         | 
| 36 | 
            +
                       developer_data_ids.size
         | 
| 37 | 
            +
                     Log.error "Developer data index #{@developer_data_index} is too large"
         | 
| 38 | 
            +
                     return
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  app_id = developer_data_ids[@developer_data_index].application_id
         | 
| 42 | 
            +
                  # Convert the byte array with the app ID into a 16 character hex string.
         | 
| 43 | 
            +
                  app_id_str = app_id.map { |i| '%02X' % i }.join('')
         | 
| 44 | 
            +
                  @full_field_name =
         | 
| 45 | 
            +
                    "#{@field_name.gsub(/[^A-Za-z0-9_]/, '_')}_#{app_id_str}"
         | 
| 28 46 | 
             
                end
         | 
| 29 47 |  | 
| 30 48 | 
             
                def create_global_definition(fit_entity)
         | 
| @@ -35,12 +53,6 @@ module Fit4Ruby | |
| 35 53 | 
             
                    return
         | 
| 36 54 | 
             
                  end
         | 
| 37 55 |  | 
| 38 | 
            -
                  if @developer_data_index >=
         | 
| 39 | 
            -
                       fit_entity.top_level_record.developer_data_ids.size
         | 
| 40 | 
            -
                     Log.error "Developer data index #{@developer_data_index} is too large"
         | 
| 41 | 
            -
                     return
         | 
| 42 | 
            -
                  end
         | 
| 43 | 
            -
             | 
| 44 56 | 
             
                  msg = messages[@native_mesg_num] ||
         | 
| 45 57 | 
             
                    messages.message(@native_mesg_num, gfm.name)
         | 
| 46 58 | 
             
                  unless (@fit_base_type_id & 0x7F) < FIT_TYPE_DEFS.size
         | 
| @@ -48,10 +60,10 @@ module Fit4Ruby | |
| 48 60 | 
             
                    return
         | 
| 49 61 | 
             
                  end
         | 
| 50 62 |  | 
| 51 | 
            -
                  name = "_#{@developer_data_index}_#{@field_name}"
         | 
| 52 63 | 
             
                  # A fit file may include multiple definitions of the same field. We
         | 
| 53 64 | 
             
                  # ignore all subsequent definitions.
         | 
| 54 | 
            -
                  return if msg.has_field?( | 
| 65 | 
            +
                  return if msg.has_field?(full_field_name(fit_entity.top_level_record.
         | 
| 66 | 
            +
                                                           developer_data_ids))
         | 
| 55 67 |  | 
| 56 68 | 
             
                  options = {}
         | 
| 57 69 | 
             
                  options[:scale] = @scale if @scale
         | 
| @@ -60,7 +72,7 @@ module Fit4Ruby | |
| 60 72 | 
             
                  options[:unit] = @units
         | 
| 61 73 | 
             
                  msg.field(@field_definition_number,
         | 
| 62 74 | 
             
                            FIT_TYPE_DEFS[@fit_base_type_id & 0x7F][1],
         | 
| 63 | 
            -
                             | 
| 75 | 
            +
                            @full_field_name, options)
         | 
| 64 76 | 
             
                end
         | 
| 65 77 |  | 
| 66 78 | 
             
              end
         | 
    
        data/lib/fit4ruby/FileId.rb
    CHANGED
    
    | @@ -3,7 +3,7 @@ | |
| 3 3 | 
             
            #
         | 
| 4 4 | 
             
            # = FileId.rb -- Fit4Ruby - FIT file processing library for Ruby
         | 
| 5 5 | 
             
            #
         | 
| 6 | 
            -
            # Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
         | 
| 6 | 
            +
            # Copyright (c) 2014, 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
         | 
| @@ -23,6 +23,7 @@ module Fit4Ruby | |
| 23 23 | 
             
                  @time_created = Time.at(Time.now.to_i)
         | 
| 24 24 | 
             
                  @manufacturer = 'development'
         | 
| 25 25 | 
             
                  @type = 'activity'
         | 
| 26 | 
            +
                  @product = 0
         | 
| 26 27 |  | 
| 27 28 | 
             
                  set_field_values(field_values)
         | 
| 28 29 | 
             
                end
         |