fit4ruby 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/COPYING +280 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +21 -0
- data/README.md +16 -0
- data/Rakefile +19 -0
- data/fit4ruby.gemspec +30 -0
- data/lib/fit4ruby.rb +26 -0
- data/lib/fit4ruby/Activity.rb +119 -0
- data/lib/fit4ruby/Converters.rb +58 -0
- data/lib/fit4ruby/FitDataRecord.rb +79 -0
- data/lib/fit4ruby/FitDefinition.rb +54 -0
- data/lib/fit4ruby/FitDefinitionField.rb +137 -0
- data/lib/fit4ruby/FitFile.rb +154 -0
- data/lib/fit4ruby/FitFileId.rb +31 -0
- data/lib/fit4ruby/FitFilter.rb +26 -0
- data/lib/fit4ruby/FitHeader.rb +55 -0
- data/lib/fit4ruby/FitMessageIdMapper.rb +53 -0
- data/lib/fit4ruby/FitMessageRecord.rb +77 -0
- data/lib/fit4ruby/FitRecord.rb +80 -0
- data/lib/fit4ruby/FitRecordHeader.rb +39 -0
- data/lib/fit4ruby/GlobalFitDictList.rb +68 -0
- data/lib/fit4ruby/GlobalFitDictionaries.rb +302 -0
- data/lib/fit4ruby/GlobalFitMessage.rb +189 -0
- data/lib/fit4ruby/GlobalFitMessages.rb +235 -0
- data/lib/fit4ruby/Lap.rb +44 -0
- data/lib/fit4ruby/Log.rb +45 -0
- data/lib/fit4ruby/Record.rb +56 -0
- data/lib/fit4ruby/Session.rb +110 -0
- data/lib/fit4ruby/version.rb +3 -0
- data/tasks/changelog.rake +169 -0
- data/tasks/gem.rake +52 -0
- data/tasks/rdoc.rake +14 -0
- data/tasks/test.rake +7 -0
- data/test/FitFile_spec.rb +31 -0
- metadata +137 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# = FitFileId.rb -- Fit4Ruby - FIT file processing library for Ruby
|
5
|
+
#
|
6
|
+
# Copyright (c) 2014 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/Converters'
|
14
|
+
require 'fit4ruby/FitDataRecord'
|
15
|
+
|
16
|
+
module Fit4Ruby
|
17
|
+
|
18
|
+
class FitFileId < FitDataRecord
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
super('file_id')
|
22
|
+
@serial_number = 1234567890
|
23
|
+
@time_created = Time.now
|
24
|
+
@manufacturer = 'development'
|
25
|
+
@type = 'activity'
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# = FitFilter.rb -- Fit4Ruby - FIT file processing library for Ruby
|
5
|
+
#
|
6
|
+
# Copyright (c) 2014 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
|
+
class FitFilter < Struct.new(:record_numbers, :record_indexes, :field_names,
|
16
|
+
:ignore_undef)
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
super
|
20
|
+
self[:ignore_undef] = false
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# = FitHeader.rb -- Fit4Ruby - FIT file processing library for Ruby
|
5
|
+
#
|
6
|
+
# Copyright (c) 2014 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 'bindata'
|
14
|
+
require 'fit4ruby/Log'
|
15
|
+
|
16
|
+
module Fit4Ruby
|
17
|
+
|
18
|
+
class FitHeader < BinData::Record
|
19
|
+
|
20
|
+
endian :little
|
21
|
+
|
22
|
+
uint8 :header_size, :initial_value => 14
|
23
|
+
uint8 :protocol_version, :initial_value => 16
|
24
|
+
uint16 :profile_version, :initial_value => 1012
|
25
|
+
uint32 :data_size, :initial_value => 0
|
26
|
+
string :data_type, :read_length => 4, :initial_value => '.FIT'
|
27
|
+
uint16 :crc, :initial_value => 0
|
28
|
+
|
29
|
+
def check
|
30
|
+
unless header_size == 14
|
31
|
+
Log.fatal { "Unsupported header size #{@header.header_size}" }
|
32
|
+
end
|
33
|
+
unless data_type == '.FIT'
|
34
|
+
Log.fata { "Unknown file type #{@header.data_type}" }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def dump
|
39
|
+
puts <<"EOT"
|
40
|
+
Fit File Header
|
41
|
+
Header Size: #{header_size}
|
42
|
+
Protocol Version: #{protocol_version}
|
43
|
+
Profile Version: #{profile_version}
|
44
|
+
Data Size: #{data_size}
|
45
|
+
EOT
|
46
|
+
end
|
47
|
+
|
48
|
+
def end_pos
|
49
|
+
header_size + data_size
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# = FitMessageIdMapper.rb -- Fit4Ruby - FIT file processing library for Ruby
|
5
|
+
#
|
6
|
+
# Copyright (c) 2014 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
|
+
class FitMessageIdMapper
|
16
|
+
|
17
|
+
class Entry < Struct.new(:global_id, :last_use)
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@entries = Array.new(16, nil)
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_global(id)
|
25
|
+
unless (slot = @entries.index { |e| e.nil? })
|
26
|
+
puts @entries.inspect
|
27
|
+
# No more free slots. We have to find the least recently used one.
|
28
|
+
slot = 0
|
29
|
+
0.upto(15) do |i|
|
30
|
+
if i != slot && @entries[slot].last_use > @entries[i].last_use
|
31
|
+
slot = i
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
@entries[slot] = Entry.new(id, Time.now)
|
36
|
+
|
37
|
+
slot
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_local(id)
|
41
|
+
0.upto(15) do |i|
|
42
|
+
if (entry = @entries[i]) && entry.global_id == id
|
43
|
+
entry.last_use = Time.now
|
44
|
+
return i
|
45
|
+
end
|
46
|
+
end
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
@@ -0,0 +1,77 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# = FitMessageRecord.rb -- Fit4Ruby - FIT file processing library for Ruby
|
5
|
+
#
|
6
|
+
# Copyright (c) 2014 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 'bindata'
|
14
|
+
require 'fit4ruby/Log'
|
15
|
+
require 'fit4ruby/GlobalFitMessage'
|
16
|
+
|
17
|
+
module Fit4Ruby
|
18
|
+
|
19
|
+
class FitMessageRecord
|
20
|
+
|
21
|
+
attr_reader :global_message_number, :name, :message_record
|
22
|
+
|
23
|
+
def initialize(definition)
|
24
|
+
@definition = definition
|
25
|
+
@global_message_number = definition.global_message_number.snapshot
|
26
|
+
|
27
|
+
if (@gfm = GlobalFitMessages[@global_message_number])
|
28
|
+
@name = @gfm.name
|
29
|
+
else
|
30
|
+
@name = "message#{@global_message_number}"
|
31
|
+
Log.warn { "Unknown global message number #{@global_message_number}" }
|
32
|
+
end
|
33
|
+
@message_record = produce(definition)
|
34
|
+
end
|
35
|
+
|
36
|
+
def read(io, activity, filter = nil, fields_dump = nil)
|
37
|
+
@message_record.read(io)
|
38
|
+
|
39
|
+
obj = case @name
|
40
|
+
when 'activity'
|
41
|
+
activity
|
42
|
+
when 'session'
|
43
|
+
activity.new_session
|
44
|
+
when 'record'
|
45
|
+
activity.new_record
|
46
|
+
else
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
@definition.fields.each do |field|
|
51
|
+
value = @message_record[field.name].snapshot
|
52
|
+
obj.set(field.name, field.to_machine(value)) if obj
|
53
|
+
if filter && fields_dump &&
|
54
|
+
(filter.field_names.nil? ||
|
55
|
+
filter.field_names.include?(field.name)) &&
|
56
|
+
(value != field.undefined_value || !filter.ignore_undef)
|
57
|
+
fields_dump[field] = value
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def produce(definition)
|
65
|
+
fields = []
|
66
|
+
definition.fields.each do |field|
|
67
|
+
fields << [ field.type, field.name ]
|
68
|
+
end
|
69
|
+
|
70
|
+
BinData::Struct.new(:endian => definition.endian, :fields => fields)
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
@@ -0,0 +1,80 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# = FitRecord.rb -- Fit4Ruby - FIT file processing library for Ruby
|
5
|
+
#
|
6
|
+
# Copyright (c) 2014 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/Log'
|
14
|
+
require 'fit4ruby/FitRecordHeader'
|
15
|
+
require 'fit4ruby/FitDefinition'
|
16
|
+
require 'fit4ruby/FitMessageRecord'
|
17
|
+
require 'fit4ruby/FitFilter'
|
18
|
+
require 'fit4ruby/Activity'
|
19
|
+
|
20
|
+
module Fit4Ruby
|
21
|
+
|
22
|
+
class FitRecord
|
23
|
+
|
24
|
+
def initialize(definitions)
|
25
|
+
@definitions = definitions
|
26
|
+
@name = @number = @fields = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def read(io, activity, filter, record_counters)
|
30
|
+
header = FitRecordHeader.read(io)
|
31
|
+
|
32
|
+
if header.normal?
|
33
|
+
# process normal headers
|
34
|
+
local_message_type = header.local_message_type.snapshot
|
35
|
+
if header.message_type == 1
|
36
|
+
# process definition message
|
37
|
+
definition = FitDefinition.read(io)
|
38
|
+
@definitions[local_message_type] = FitMessageRecord.new(definition)
|
39
|
+
else
|
40
|
+
# process data message
|
41
|
+
definition = @definitions[local_message_type]
|
42
|
+
unless definition
|
43
|
+
Log.fatal "Undefined local message type: #{local_message_type}"
|
44
|
+
end
|
45
|
+
if filter
|
46
|
+
@number = @definitions[local_message_type].global_message_number
|
47
|
+
index = (record_counters[@number] += 1)
|
48
|
+
if (filter.record_numbers.nil? ||
|
49
|
+
filter.record_numbers.include?(@number)) &&
|
50
|
+
(filter.record_indexes.nil? ||
|
51
|
+
filter.record_indexes.include?(index))
|
52
|
+
@name = definition.name
|
53
|
+
@fields = {}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
definition.read(io, activity, filter, @fields)
|
57
|
+
end
|
58
|
+
else
|
59
|
+
# process compressed timestamp header
|
60
|
+
time_offset = header.time_offset
|
61
|
+
Log.fatal "Support for compressed headers not yet implemented"
|
62
|
+
end
|
63
|
+
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
def dump
|
68
|
+
return unless @fields
|
69
|
+
|
70
|
+
puts "Message #{@number}: #{@name}" unless @fields.empty?
|
71
|
+
@fields.each do |field, value|
|
72
|
+
puts " [#{"%-7s" % field.type(true)}] #{field.name}: " +
|
73
|
+
"#{field.to_s(value)}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# = FitRecordHeader.rb -- Fit4Ruby - FIT file processing library for Ruby
|
5
|
+
#
|
6
|
+
# Copyright (c) 2014 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
|
+
class FitRecordHeader < BinData::Record
|
16
|
+
|
17
|
+
bit1 :normal
|
18
|
+
|
19
|
+
bit1 :message_type, :onlyif => :normal?
|
20
|
+
bit2 :reserved, :onlyif => :normal?
|
21
|
+
|
22
|
+
choice :local_message_type, :selection => :normal do
|
23
|
+
bit4 0
|
24
|
+
bit2 1
|
25
|
+
end
|
26
|
+
|
27
|
+
bit5 :time_offset, :onlyif => :compressed?
|
28
|
+
|
29
|
+
def normal?
|
30
|
+
normal == 0
|
31
|
+
end
|
32
|
+
|
33
|
+
def compressed?
|
34
|
+
normal == 1
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# = GlobalFitDictList.rb -- Fit4Ruby - FIT file processing library for Ruby
|
5
|
+
#
|
6
|
+
# Copyright (c) 2014 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/Log'
|
14
|
+
|
15
|
+
module Fit4Ruby
|
16
|
+
|
17
|
+
class GlobalFitDict
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@entries = {}
|
21
|
+
end
|
22
|
+
|
23
|
+
def entry(number, name)
|
24
|
+
if @entries.include?(number)
|
25
|
+
Log.fatal "Entry #{number} has already been defined"
|
26
|
+
end
|
27
|
+
@entries[number] = name
|
28
|
+
end
|
29
|
+
|
30
|
+
def name(number)
|
31
|
+
@entries[number]
|
32
|
+
end
|
33
|
+
|
34
|
+
def value_by_name(name)
|
35
|
+
@entries.invert[name]
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
class GlobalFitDictList
|
41
|
+
|
42
|
+
def initialize(&block)
|
43
|
+
@current_dict = nil
|
44
|
+
@dicts = {}
|
45
|
+
instance_eval(&block) if block_given?
|
46
|
+
end
|
47
|
+
|
48
|
+
def dict(name)
|
49
|
+
if @dicts.include?(name)
|
50
|
+
Log.fatal "Dictionary #{name} has already been defined"
|
51
|
+
end
|
52
|
+
@dicts[name] = @current_dict = GlobalFitDict.new
|
53
|
+
end
|
54
|
+
|
55
|
+
def entry(number, name)
|
56
|
+
unless @current_dict
|
57
|
+
Log.fatal "You must define a dictionary first"
|
58
|
+
end
|
59
|
+
@current_dict.entry(number, name)
|
60
|
+
end
|
61
|
+
|
62
|
+
def [](name)
|
63
|
+
@dicts[name]
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,302 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# = GlobalFitDictionaries.rb -- Fit4Ruby - FIT file processing library for Ruby
|
5
|
+
#
|
6
|
+
# Copyright (c) 2014 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/GlobalFitDictList'
|
14
|
+
|
15
|
+
module Fit4Ruby
|
16
|
+
|
17
|
+
GlobalFitDictionaries = GlobalFitDictList.new do
|
18
|
+
|
19
|
+
dict 'activity_type'
|
20
|
+
entry 0, 'generic'
|
21
|
+
entry 1, 'running'
|
22
|
+
entry 2, 'cycling'
|
23
|
+
entry 3, 'transition'
|
24
|
+
entry 4, 'fitness_equipment'
|
25
|
+
entry 5, 'swimming'
|
26
|
+
entry 6, 'walking'
|
27
|
+
entry 254, 'all'
|
28
|
+
|
29
|
+
dict 'battery_status'
|
30
|
+
entry 1, 'new'
|
31
|
+
entry 2, 'good'
|
32
|
+
entry 3, 'ok'
|
33
|
+
entry 4, 'low'
|
34
|
+
entry 5, 'critical'
|
35
|
+
|
36
|
+
dict 'device_type'
|
37
|
+
entry 1, 'antfs'
|
38
|
+
entry 11, 'bike_power'
|
39
|
+
entry 12, 'environment_sensor_legacy'
|
40
|
+
entry 13, 'multi_sport_speed_distance'
|
41
|
+
entry 14, 'control'
|
42
|
+
entry 17, 'fitness_equipment'
|
43
|
+
entry 18, 'blood_pressure'
|
44
|
+
entry 19, 'geocache_node'
|
45
|
+
entry 20, 'light_electric_vehicle'
|
46
|
+
entry 25, 'env_sensor'
|
47
|
+
entry 26, 'racquet'
|
48
|
+
entry 30, 'running_dynamics' # Just a guess
|
49
|
+
entry 119, 'weight_scale'
|
50
|
+
entry 120, 'heart_rate'
|
51
|
+
entry 121, 'bike_speed_cadence'
|
52
|
+
entry 122, 'bike_cadence'
|
53
|
+
entry 123, 'bike_speed'
|
54
|
+
entry 124, 'stride_speed_distance'
|
55
|
+
|
56
|
+
dict 'event'
|
57
|
+
entry 0, 'timer'
|
58
|
+
entry 3, 'workout'
|
59
|
+
entry 4, 'workout_step'
|
60
|
+
entry 5, 'power_down'
|
61
|
+
entry 6, 'power_up'
|
62
|
+
entry 7, 'off_course'
|
63
|
+
entry 8, 'session'
|
64
|
+
entry 9, 'lap'
|
65
|
+
entry 10, 'course_point'
|
66
|
+
entry 11, 'battery'
|
67
|
+
entry 12, 'virtual_partner_pace'
|
68
|
+
entry 13, 'hr_high_alert'
|
69
|
+
entry 14, 'hr_low_alert'
|
70
|
+
entry 15, 'speed_high_alert'
|
71
|
+
entry 16, 'speed_low_alert'
|
72
|
+
entry 17, 'cad_high_alert'
|
73
|
+
entry 18, 'cad_low_alert'
|
74
|
+
entry 19, 'power_high_alert'
|
75
|
+
entry 20, 'power_low_alert'
|
76
|
+
entry 21, 'recovery_hr'
|
77
|
+
entry 22, 'battery_low'
|
78
|
+
entry 23, 'time_duration_alert'
|
79
|
+
entry 24, 'distance_duration_alert'
|
80
|
+
entry 25, 'calorie_duration_alert'
|
81
|
+
entry 26, 'activity'
|
82
|
+
entry 27, 'fitness_equipment'
|
83
|
+
entry 28, 'length'
|
84
|
+
entry 32, 'user_marker'
|
85
|
+
entry 33, 'sport_point'
|
86
|
+
entry 36, 'calibration'
|
87
|
+
entry 37, 'vo2max' # guess
|
88
|
+
entry 38, 'recovery_time' # guess (in minutes)
|
89
|
+
entry 42, 'front_gear_change'
|
90
|
+
entry 43, 'rear_gear_change'
|
91
|
+
|
92
|
+
dict 'event_type'
|
93
|
+
entry 0, 'start_time'
|
94
|
+
entry 1, 'stop'
|
95
|
+
entry 2, 'consecutive_depreciated'
|
96
|
+
entry 3, 'marker'
|
97
|
+
entry 4, 'stop_all'
|
98
|
+
entry 5, 'begin_depreciated'
|
99
|
+
entry 6, 'end_depreciated'
|
100
|
+
entry 7, 'end_all_depreciated'
|
101
|
+
entry 8, 'stop_disable'
|
102
|
+
entry 9, 'stop_disable_all'
|
103
|
+
|
104
|
+
dict 'file'
|
105
|
+
entry 1, 'device'
|
106
|
+
entry 2, 'settings'
|
107
|
+
entry 3, 'sport'
|
108
|
+
entry 4, 'activity'
|
109
|
+
entry 5, 'workout'
|
110
|
+
entry 6, 'course_point'
|
111
|
+
entry 7, 'schedules'
|
112
|
+
entry 9, 'weight_scale'
|
113
|
+
entry 10, 'totals'
|
114
|
+
entry 11, 'goals'
|
115
|
+
entry 14, 'blood_pressure'
|
116
|
+
entry 15, 'monitoring_a'
|
117
|
+
entry 20, 'activity_summary'
|
118
|
+
entry 28, 'monitoring_daily'
|
119
|
+
entry 32, 'monitoring_b'
|
120
|
+
|
121
|
+
dict 'gender'
|
122
|
+
entry 0, 'female'
|
123
|
+
entry 1, 'male'
|
124
|
+
|
125
|
+
dict 'intensity'
|
126
|
+
entry 0, 'active'
|
127
|
+
entry 1, 'rest'
|
128
|
+
entry 2, 'warmup'
|
129
|
+
entry 3, 'cooldown'
|
130
|
+
|
131
|
+
dict 'lap_trigger'
|
132
|
+
entry 0, 'manual'
|
133
|
+
entry 1, 'time'
|
134
|
+
entry 2, 'distance'
|
135
|
+
entry 3, 'position_start'
|
136
|
+
entry 4, 'position_lap'
|
137
|
+
entry 5, 'position_waypoint'
|
138
|
+
entry 6, 'position_marked'
|
139
|
+
entry 7, 'session_end'
|
140
|
+
entry 8, 'fitness_equipment'
|
141
|
+
|
142
|
+
dict 'manufacturer'
|
143
|
+
entry 1, 'Garmin'
|
144
|
+
entry 2, 'garmin_fr405_antfs'
|
145
|
+
entry 3, 'zephyr'
|
146
|
+
entry 4, 'dayton'
|
147
|
+
entry 5, 'idt'
|
148
|
+
entry 6, 'srm'
|
149
|
+
entry 7, 'quarq'
|
150
|
+
entry 8, 'ibike'
|
151
|
+
entry 9, 'saris'
|
152
|
+
entry 10, 'spark_hk'
|
153
|
+
entry 11, 'tanita'
|
154
|
+
entry 12, 'echowell'
|
155
|
+
entry 13, 'dynastream_oem'
|
156
|
+
entry 14, 'nautilus'
|
157
|
+
entry 15, 'dynastream'
|
158
|
+
entry 16, 'timex'
|
159
|
+
entry 17, 'metrigear'
|
160
|
+
entry 18, 'xelic'
|
161
|
+
entry 19, 'beurer'
|
162
|
+
entry 20, 'cardiosport'
|
163
|
+
entry 21, 'a_and_d'
|
164
|
+
entry 22, 'hmm'
|
165
|
+
entry 23, 'suunto'
|
166
|
+
entry 24, 'thita_elektronik'
|
167
|
+
entry 25, 'gpulse'
|
168
|
+
entry 26, 'clean_mobile'
|
169
|
+
entry 27, 'pedal_brain'
|
170
|
+
entry 28, 'peaksware'
|
171
|
+
entry 29, 'saxonar'
|
172
|
+
entry 30, 'lemond_fitness'
|
173
|
+
entry 31, 'dexcom'
|
174
|
+
entry 32, 'wahoo_fitness'
|
175
|
+
entry 33, 'octane_fitness'
|
176
|
+
entry 34, 'archinoetics'
|
177
|
+
entry 35, 'the_hurt_box'
|
178
|
+
entry 36, 'citizen_systems'
|
179
|
+
entry 37, 'magellan'
|
180
|
+
entry 38, 'osynce'
|
181
|
+
entry 39, 'holux'
|
182
|
+
entry 40, 'concept2'
|
183
|
+
entry 42, 'one_giant_leap'
|
184
|
+
entry 43, 'ace_sensor'
|
185
|
+
entry 44, 'brim_brothers'
|
186
|
+
entry 45, 'xplova'
|
187
|
+
entry 46, 'perception_digital'
|
188
|
+
entry 47, 'bf1systems'
|
189
|
+
entry 48, 'pioneer'
|
190
|
+
entry 49, 'spantec'
|
191
|
+
entry 50, 'metalogics'
|
192
|
+
entry 51, '4iiiis'
|
193
|
+
entry 52, 'seiko_epson'
|
194
|
+
entry 53, 'seiko_epson_oem'
|
195
|
+
entry 54, 'ifor_powell'
|
196
|
+
entry 55, 'maxwell_guider'
|
197
|
+
entry 56, 'star_trac'
|
198
|
+
entry 57, 'breakaway'
|
199
|
+
entry 58, 'alatech_technology_ltd'
|
200
|
+
entry 59, 'mio_technology_europe'
|
201
|
+
entry 60, 'rotor'
|
202
|
+
entry 61, 'geonaute'
|
203
|
+
entry 62, 'id_bike'
|
204
|
+
entry 63, 'specialized'
|
205
|
+
entry 64, 'wtek'
|
206
|
+
entry 65, 'physical_enterprises'
|
207
|
+
entry 66, 'north_pole_engineering'
|
208
|
+
entry 67, 'bkool'
|
209
|
+
entry 68, 'cateye'
|
210
|
+
entry 69, 'stages_cycling'
|
211
|
+
entry 70, 'sigmasport'
|
212
|
+
entry 71, 'tomtom'
|
213
|
+
entry 72, 'peripedal'
|
214
|
+
entry 73, 'wattbike'
|
215
|
+
entry 74, 'moxy'
|
216
|
+
entry 77, 'ciclosport'
|
217
|
+
entry 78, 'powerbahn'
|
218
|
+
entry 79, 'acorn_projects_aps'
|
219
|
+
entry 80, 'lifebeam'
|
220
|
+
entry 81, 'bontrager'
|
221
|
+
entry 82, 'wellgo'
|
222
|
+
entry 83, 'scosche'
|
223
|
+
entry 84, 'magura'
|
224
|
+
entry 85, 'woodway'
|
225
|
+
entry 86, 'elite'
|
226
|
+
entry 255, 'development'
|
227
|
+
entry 5759, 'actigraphcorp'
|
228
|
+
|
229
|
+
dict 'session_trigger'
|
230
|
+
entry 0, 'activity_end'
|
231
|
+
entry 1, 'manual'
|
232
|
+
entry 2, 'auto_multi_sport'
|
233
|
+
entry 3, 'fitness_equipment'
|
234
|
+
|
235
|
+
dict 'sport'
|
236
|
+
entry 0, 'generic'
|
237
|
+
entry 1, 'running'
|
238
|
+
entry 2, 'cycling'
|
239
|
+
entry 3, 'transition'
|
240
|
+
entry 4, 'fitness_equipment'
|
241
|
+
entry 5, 'swimming'
|
242
|
+
entry 6, 'basketball'
|
243
|
+
entry 7, 'soccer'
|
244
|
+
entry 8, 'tennis'
|
245
|
+
entry 9, 'american_football'
|
246
|
+
entry 10, 'training'
|
247
|
+
entry 11, 'walking'
|
248
|
+
entry 12, 'cross_country_skiing'
|
249
|
+
entry 13, 'alpine_skiing'
|
250
|
+
entry 14, 'snowboarding'
|
251
|
+
entry 15, 'rowing'
|
252
|
+
entry 16, 'mountaineering'
|
253
|
+
entry 17, 'hiking'
|
254
|
+
entry 18, 'multisport'
|
255
|
+
entry 19, 'paddling'
|
256
|
+
entry 254, 'all'
|
257
|
+
|
258
|
+
dict 'sub_sport'
|
259
|
+
entry 0, 'generic'
|
260
|
+
entry 1, 'treadmill'
|
261
|
+
entry 2, 'street'
|
262
|
+
entry 3, 'trail'
|
263
|
+
entry 4, 'track'
|
264
|
+
entry 5, 'spin'
|
265
|
+
entry 6, 'indoor_cycling'
|
266
|
+
entry 7, 'road'
|
267
|
+
entry 8, 'mountain'
|
268
|
+
entry 9, 'downhill'
|
269
|
+
entry 10, 'recumbent'
|
270
|
+
entry 11, 'cyclocross'
|
271
|
+
entry 12, 'hand_cycling'
|
272
|
+
entry 13, 'track_cycling'
|
273
|
+
entry 14, 'indoor_rowing'
|
274
|
+
entry 15, 'elliptical'
|
275
|
+
entry 16, 'stair_climbing'
|
276
|
+
entry 17, 'lap_swimming'
|
277
|
+
entry 18, 'open_water'
|
278
|
+
entry 19, 'flexibility_training'
|
279
|
+
entry 20, 'strength_training'
|
280
|
+
entry 21, 'warm_up'
|
281
|
+
entry 22, 'match'
|
282
|
+
entry 23, 'exercise'
|
283
|
+
entry 24, 'challenge'
|
284
|
+
entry 25, 'indoor_skiing'
|
285
|
+
entry 26, 'cardio_training'
|
286
|
+
entry 254, 'all'
|
287
|
+
|
288
|
+
dict 'product'
|
289
|
+
entry 8, 'hrm_run_single_byte_product_id'
|
290
|
+
entry 1623, 'fr620'
|
291
|
+
entry 1632, 'fr220'
|
292
|
+
entry 1752, 'hrm_run'
|
293
|
+
entry 1928, 'fr620_japan'
|
294
|
+
entry 1929, 'fr620_china'
|
295
|
+
entry 1930, 'fr220_japan'
|
296
|
+
entry 1931 , 'fr220_china'
|
297
|
+
entry 10007, 'sdm4'
|
298
|
+
|
299
|
+
end
|
300
|
+
|
301
|
+
end
|
302
|
+
|