diff --git a/lib/fit4ruby/Activity.rb b/lib/fit4ruby/Activity.rb index 2354933..0e2303c 100644 --- a/lib/fit4ruby/Activity.rb +++ b/lib/fit4ruby/Activity.rb @@ -113,11 +113,12 @@ def check # broken. Unfortunately, the Skiing/Boarding app in the Fenix3 # produces such broken FIT files. So we just warn about this # problem and discard the earlier records. - Log.error "Record #{r.timestamp} has smaller distance " + + Log.error "- #{r.timestamp} has smaller distance " + "(#{r.distance}) than an earlier record (#{distance})." # Index of the list record to be discarded. (idx - 1).downto(0) do |i| - if (ri = @records[i]).distance > r.distance + ri = @records[i] + if ri.distance && (ri.distance > r.distance) # This is just an approximation. It looks like the app adds # records to the FIT file for runs that it meant to discard. # Maybe the two successive time start events are a better diff --git a/lib/fit4ruby/CRC16.rb b/lib/fit4ruby/CRC16.rb index c01f18d..fcb042c 100644 --- a/lib/fit4ruby/CRC16.rb +++ b/lib/fit4ruby/CRC16.rb @@ -14,7 +14,11 @@ module Fit4Ruby module CRC16 - + + @@crc_table = [ + 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, + 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400 + ] def write_crc(io, start_pos, end_pos) # Compute the checksum over the data section of the file and append it # to the file. Ideally, we should compute the CRC from data in memory @@ -27,10 +31,7 @@ def write_crc(io, start_pos, end_pos) end def compute_crc(io, start_pos, end_pos) - crc_table = [ - 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, - 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400 - ] + io.seek(start_pos) @@ -43,9 +44,9 @@ def compute_crc(io, start_pos, end_pos) byte = io.readbyte 0.upto(1) do |i| - tmp = crc_table[crc & 0xF] + tmp = @@crc_table[crc & 0xF] crc = (crc >> 4) & 0x0FFF - crc = crc ^ tmp ^ crc_table[(byte >> (4 * i)) & 0xF] + crc = crc ^ tmp ^ @@crc_table[(byte >> (4 * i)) & 0xF] end end diff --git a/lib/fit4ruby/DeviceInfo.rb b/lib/fit4ruby/DeviceInfo.rb index c413451..83651b6 100644 --- a/lib/fit4ruby/DeviceInfo.rb +++ b/lib/fit4ruby/DeviceInfo.rb @@ -50,9 +50,9 @@ def check(index) Log.fatal 'device info record 0 must have a product field set' end end - if @serial_number.nil? - Log.fatal 'device info record 0 must have a serial number set' - end + #if @serial_number.nil? + # Log.fatal 'device info record 0 must have a serial number set' + #end end end diff --git a/lib/fit4ruby/GlobalFitDictionaries.rb b/lib/fit4ruby/GlobalFitDictionaries.rb index 9da2646..ba128d4 100644 --- a/lib/fit4ruby/GlobalFitDictionaries.rb +++ b/lib/fit4ruby/GlobalFitDictionaries.rb @@ -308,51 +308,170 @@ module Fit4Ruby entry 144, 'uint64z' dict 'garmin_product' + entry 1,'hrm1' + entry 2,'axh01' + entry 3,'axb01' + entry 4,'axb02' + entry 6,'dsi_alf02' + entry 7,'hrm3ss' entry 8, 'hrm_run_single_byte_product_id' entry 9, 'bsm' entry 10, 'bcm' + entry 11, 'axs01' + entry 12, 'hrm_tri_single_byte_product_id' + entry 14, 'fr225_single_byte_product_id' + entry 473, 'fr301_china' + entry 474, 'fr301_japan' + entry 475, 'fr301_korea' + entry 494, 'fr301_taiwan' + entry 717, 'fr405' + entry 782, 'fr50' + entry 987, 'fr405_japan' + entry 988, 'fr60' + entry 1011, 'dsi_alf01' + entry 1018, 'fr310xt' + entry 1036, 'edge500' + entry 1124, 'fr110' + entry 1169, 'edge800' + entry 1199, 'edge500_taiwan' + entry 1213, 'edge500_japan' + entry 1253, 'chirp' + entry 1274, 'fr110_japan' + entry 1325, 'edge200' + entry 1328, 'fr910xt' + entry 1333, 'edge800_taiwan' + entry 1334, 'edge800_japan' + entry 1341, 'alf04' + entry 1345, 'fr610' + entry 1360, 'fr210_japan' + entry 1380, 'vector_ss' + entry 1381, 'vector_cp' + entry 1386, 'edge800_china' + entry 1387, 'edge500_china' + entry 1410, 'fr610_japan' + entry 1422, 'edge500_korea' + entry 1436, 'fr70' + entry 1446, 'fr310xt_4t' + entry 1461, 'amx' + entry 1482, 'fr10' + entry 1497, 'edge800_korea' + entry 1499, 'swim' + entry 1537, 'fr910xt_china' entry 1551, 'fenix' + entry 1555, 'edge200_taiwan' + entry 1561, 'edge510' + entry 1567, 'edge810' + entry 1570, 'tempe' + entry 1600, 'fr910xt_japan' # The Fenix3 is rumored to have a Mediatek MT3333 GPS chipset. Not sure if # that would be a beter name. entry 1620, 'fenix3_gps' # Just a guess entry 1621, 'fenix5_gps' # Just a guess entry 1623, 'fr620' entry 1632, 'fr220' + entry 1664, 'fr910xt_korea' + entry 1688, 'fr10_japan' # The FR620 is rumored to have a MediaTek MT3339 GPS chipset while the # FR920XT is rumored to have a MT3333. Not sure why they have the same ID # in the FIT file for the GPS device. entry 1689, 'fr620_fr920xt_gps' # Just a guess + entry 1721, 'edge810_japan' + entry 1735, 'virb_elite' + entry 1736, 'edge_touring' + entry 1742, 'edge510_japan' entry 1743, 'hrm_tri' entry 1752, 'hrm_run' entry 1765, 'fr920xt' + entry 1821, 'edge510_asia' + entry 1822, 'edge810_china' + entry 1823, 'edge810_taiwan' + entry 1836, 'edge1000' + entry 1837, 'vivo_fit' + entry 1853, 'virb_remote' + entry 1885, 'vivo_ki' + entry 1903, 'fr15' + entry 1907, 'vivo_active' + entry 1918, 'edge510_korea' entry 1928, 'fr620_japan' entry 1929, 'fr620_china' entry 1930, 'fr220_japan' entry 1931, 'fr220_china' + entry 1936, 'approach_s6' + entry 1956, 'vivo_smart' entry 1967, 'fenix2' entry 1988, 'epix' entry 2050, 'fenix3' + entry 2052, 'edge1000_taiwan' + entry 2053, 'edge1000_japan' + entry 2061, 'fr15_japan' + entry 2067, 'edge520' + entry 2070, 'edge1000_china' entry 2072, 'fr620_russia' entry 2073, 'fr220_russia' + entry 2079, 'vector_s' + entry 2100, 'edge1000_korea' entry 2130, 'fr920xt_taiwan' entry 2131, 'fr920xt_china' entry 2132, 'fr920xt_japan' + entry 2134, 'virbx' + entry 2135, 'vivo_smart_apac' + entry 2140, 'etrex_touch' + entry 2147, 'edge25' + entry 2148, 'fr25' + entry 2150, 'vivo_fit2' + entry 2153, 'fr225' + entry 2156, 'fr630' + entry 2157, 'fr230' + entry 2160, 'vivo_active_apac' + entry 2161, 'vector_2' + entry 2162, 'vector_2s' + entry 2172, 'virbxe' entry 2173, 'fr620_taiwan' + entry 2174, 'fr220_taiwan' + entry 2175, 'truswing' entry 2188, 'fenix3_china' entry 2189, 'fenix3_twn' + entry 2192, 'varia_headlight' + entry 2193, 'varia_taillight_old' + entry 2204, 'edge_explore_1000' + entry 2219, 'fr225_asia' + entry 2225, 'varia_radar_taillight' + entry 2226, 'varia_radar_display' + entry 2238, 'edge20' + entry 2266, 'd2_bravo' + entry 2262, 'approach_s20' + entry 2276, 'varia_remote' entry 2327, 'hrm4_run' + entry 2337, 'vivo_active_hr' + entry 2347, 'vivo_smart_gps_hr' + entry 2348, 'vivo_smart_hr' + entry 2368, 'vivo_move' + entry 2398,'varia_vision' + entry 2406, 'vivo_fit3' entry 2413, 'fenix3_hr' + entry 2417, 'virb_ultra_30' + entry 2429, 'index_smart_scale' entry 2431, 'fr235' entry 2432, 'fenix3_chronos' + entry 2441, 'oregon7xx' + entry 2444, 'rino7xx' + entry 2496, 'nautix' + entry 2530, 'edge_820' + entry 2531, 'edge_explore_820' entry 2544, 'fenix5s' - entry 2604, 'fenix5x' + entry 2547, 'd2_bravo_titanium' + entry 2567, 'varia_ut800' entry 2593, 'running_dynamics_pod' + entry 2604, 'fenix5x' + entry 2606, 'vivo_fit_jr' entry 2691, 'fr935' entry 2697, 'fenix5' entry 2957, 'fenix5_gps_galileo' # Just a guess - entry 3111, 'fenix5x_plus' + entry 3111, 'fenix5x_plus' #Not included in the fit specifitation entry 10007, 'sdm4' + entry 10014, 'edge_remote' entry 20119, 'training_center' + entry 65531, 'connectiq_simulator' entry 65532, 'android_antplus_plugin' entry 65534, 'connect' @@ -670,4 +789,3 @@ module Fit4Ruby end end - diff --git a/lib/fit4ruby/GlobalFitMessage.rb b/lib/fit4ruby/GlobalFitMessage.rb index ca5b244..51deb4f 100644 --- a/lib/fit4ruby/GlobalFitMessage.rb +++ b/lib/fit4ruby/GlobalFitMessage.rb @@ -235,7 +235,9 @@ def alt_field(number, ref_field, &block) def register_field_by_name(field, name) if @fields_by_name.include?(name) - raise "Field '#{name}' has already been defined" + #raise "Field '#{name}' has already been defined" + Log.warn "Field '#{name}' has already been defined" + return end @fields_by_name[name] = field diff --git a/lib/fit4ruby/GlobalFitMessages.rb b/lib/fit4ruby/GlobalFitMessages.rb index 48dc3bc..b52b713 100644 --- a/lib/fit4ruby/GlobalFitMessages.rb +++ b/lib/fit4ruby/GlobalFitMessages.rb @@ -292,18 +292,44 @@ module Fit4Ruby field 42, 'uint16', 'avg_stroke_distance', :scale => 100, :unit => 'm' field 43, 'enum', 'swim_stroke', :dict => 'swim_stroke' field 44, 'uint16', 'pool_length', :scale => 100, :unit => 'm' - field 45, 'uint16', 'undefined_value_45' + field 45, 'uint16', 'threshold_power', :unit => 'watts' field 46, 'enum', 'pool_length_unit', :dict => 'display_measure' field 47, 'uint16', 'num_active_length', :unit => 'lengths' field 48, 'uint32', 'total_work', :unit => 'J' + field 49, 'uint16', 'avg_altiturde', :scale => 5, :offset => 500, :unit => 'm' + field 50, 'uint16', 'max_altitude', :scale => 5, :offset => 500, :unit => 'm' + field 51, 'uint8', 'gps_accuracy', :unit => 'm' + field 52, 'sint16', 'avg_grade', :scale => 100, :unit => 'percent' + field 53, 'sint16', 'avg_pos_grade', :scale => 100, :unit => 'percent' + field 54, 'sint16', 'avg_neg_grade', :scale => 100, :unit => 'percent' + field 55, 'sint16', 'max_pos_grade', :scale => 100, :unit => 'percent' + field 56, 'sint16', 'max_neg_grade', :scale => 100, :unit => 'percent' field 57, 'sint8', 'avg_temperature', :unit => 'C' field 58, 'sint8', 'max_temperature', :unit => 'C' + field 59, 'unit32', 'total_moving_time', :scale => 1000, :unit => 's' + field 60, 'sint16', 'avg_pos_vertical_speed', :scale => 1000, :unit => 'm/s' + field 61, 'sint16', 'avg_neg_vertical_speed', :scale => 1000, :unit => 'm/s' + field 62, 'sint16', 'max_pos_vertical_speed', :scale => 1000, :unit => 'm/s' + field 63, 'sint16', 'max_neg_vertical_speed', :scale => 1000, :unit => 'm/s' + field 64, 'uint8', 'min_heart_rate', :unit => 'bpm' field 65, 'uint32', 'time_in_hr_zone', :array => true, :scale => 1000, :unit => 's' + field 66, 'uint32', 'time_in_speed_zone', :array => true, :scale => 1000, :unit => 's' + field 67, 'uint32', 'time_in_cadence_zone', :array => true, :scale => 1000, :unit => 's' field 68, 'uint32', 'time_in_power_zone', :array => true, :scale => 1000, :unit => 's' + field 69, 'uint32', 'avg_lap_time', :scale => 1000, :unit => 's' + field 70, 'uint16', 'best_lap_index' + field 71, 'uint16', 'min_altitude', :scale => 5, :offset => 500, :unit => 'm' field 78, 'uint32', 'undocumented_field_78' field 79, 'uint16', 'undocumented_field_79' field 80, 'uint16', 'undocumented_field_80' field 81, 'enum', 'undocumented_field_81' + field 82, 'uint16', 'player_score' + field 83, 'uint16', 'opponent_score' + field 84, 'string', 'opponent_name' + field 85, 'uint16', 'stroke_count', :array => true, :unit => 'count' + field 86, 'uint16', 'zone_count', :array => true, :unit => 'count' + field 87, 'uint16', 'max_ball_speed', :array => true, :scale => 100, :unit => 'm/s' + field 88, 'uint16', 'avg_ball_speed', :array => true, :scale => 100, :unit => 'm/s' field 89, 'uint16', 'avg_vertical_oscillation', :scale => 10, :unit => 'mm' field 90, 'uint16', 'avg_stance_time_percent', :scale => 100, :unit => 'percent' field 91, 'uint16', 'avg_stance_time', :scale => 10, :unit => 'ms' @@ -313,6 +339,9 @@ module Fit4Ruby field 95, 'uint16', 'avg_total_hemoglobin_conc', :array => true, :scale => 100, :unit => 'g/dL' field 96, 'uint16', 'min_total_hemoglobin_conc', :array => true, :scale => 100, :unit => 'g/dL' field 97, 'uint16', 'max_total_hemoglobin_conc', :array => true, :scale => 100, :unit => 'g/dL' + field 98, 'uint16', 'avg_saturated_hemoglobin_percent', :array => true, :scale => 10, :unit => 'percent' + field 99, 'uint16', 'min_saturated_hemoglobin_percent', :array => true, :scale => 10, :unit => 'percent' + field 100, 'uint16', 'max_saturated_hemoglobin_percent', :array => true, :scale => 10, :unit => 'percent' field 101, 'uint8', 'avg_left_torque_effectiveness', :scale => 2, :unit => 'percent' field 102, 'uint8', 'avg_right_torque_effectiveness', :scale => 2, :unit => 'percent' field 103, 'uint8', 'avg_left_pedal_smoothness', :scale => 2, :unit => 'percent' @@ -323,6 +352,7 @@ module Fit4Ruby field 108, 'uint16', 'undefined_value_108' field 109, 'uint8', 'undefined_value_109' field 110, 'string', 'undefined_value_110' + field 111, 'uint8', 'sport_index' field 112, 'uint32', 'time_standing', :scale => 1000, :unit => 's' field 113, 'uint16', 'stand_count' field 114, 'sint8', 'avg_left_pco', :unit => 'mm' @@ -340,11 +370,15 @@ module Fit4Ruby field 126, 'uint32', 'enhanced_avg_altitude', :scale => 5, :offset => 500, :unit => 'm' field 127, 'uint32', 'enhanced_min_altitude', :scale => 5, :offset => 500, :unit => 'm' field 128, 'uint32', 'enhanced_max_altitude', :scale => 5, :offset => 500, :unit => 'm' + field 129, 'uint16', 'avg_lev_motor_power', :unit => 'watts' + field 130, 'uint16', 'max_lev_motor_power', :unit => 'watts' + field 131, 'uint8', 'lev_battery_consumption', :scale => 2, :unit => 'percent' field 132, 'uint16', 'avg_vertical_ratio', :scale => 100, :unit => '%' field 133, 'uint16', 'avg_stance_time_balance', :scale => 100, :unit => '%' field 134, 'uint16', 'avg_step_length', :scale => 10, :unit => 'mm' field 137, 'uint8', 'total_anaerobic_training_effect', :scale => 10 field 138, 'uint8', 'undocumented_field_138' + field 139, 'uint16', 'avg_vam', :scale => 1000, :unit => 'm/s' field 150, 'sint8', 'min_temperature', :unit => 'C' # guessed field 151, 'uint16', 'undocumented_field_151' field 152, 'uint32', 'undocumented_field_152' @@ -392,10 +426,10 @@ module Fit4Ruby field 23, 'enum', 'intensity', :dict => 'intensity' field 24, 'enum', 'lap_trigger', :dict => 'lap_trigger' field 26, 'uint8', 'event_group' - field 27, 'sint32', 'nec_lat', :type => 'coordinate' - field 28, 'sint32', 'nec_long', :type => 'coordinate' - field 29, 'sint32', 'swc_lat', :type => 'coordinate' - field 30, 'sint32', 'swc_long', :type => 'coordinate' + field 27, 'sint32', 'nec_lat', :type => 'coordinate' #guessed + field 28, 'sint32', 'nec_long', :type => 'coordinate' #guessed + field 29, 'sint32', 'swc_lat', :type => 'coordinate' #guessed + field 30, 'sint32', 'swc_long', :type => 'coordinate' #guessed field 32, 'uint16', 'num_length', :unit => 'lengths' field 33, 'uint16', 'normalized_power', :unit => 'watts' field 34, 'uint16', 'left_right_balance', :dict => 'left_right_balance_100' @@ -405,20 +439,48 @@ module Fit4Ruby field 39, 'enum', 'sub_sport', :dict => 'sub_sport' field 40, 'uint16', 'num_active_length', :unit => 'lengths' field 41, 'uint32', 'total_work', :unit => 'J' + field 42, 'uint16', 'avg_altitude', :scale => 5, :offset => 500, :unit => 'm' + field 43, 'uint16', 'max_altitude', :scale => 5, :offset => 500, :unit => 'm' + field 44, 'uint8', 'gps_accuracy', :unit => 'm' + field 45, 'sint16', 'avg_grade', :scale => 100, :unit => 'percent' + field 46, 'sint16', 'avg_pos_grade', :scale => 100, :unit => 'percent' + field 47, 'sint16', 'avg_neg_grade', :scale => 100, :unit => 'percent' + field 48, 'sint16', 'max_pos_grade', :scale => 100, :unit => 'percent' + field 49, 'sint16', 'max_neg_grade', :scale => 100, :unit => 'percent' field 50, 'sint8', 'avg_temperature', :unit => 'C' field 51, 'sint8', 'max_temperature', :unit => 'C' + field 52, 'uint32', 'total_moving_time', :scale => 1000, :unit => 's' + field 53, 'sint16', 'avg_pos_vertical_speed', :scale => 1000, :unit => 'm/s' + field 54, 'sint16', 'avg_neg_vertical_speed', :scale => 1000, :unit => 'm/s' + field 55, 'sint16', 'max_pos_vertical_speed', :scale => 1000, :unit => 'm/s' + field 56, 'sint16', 'max_neg_vertical_speed', :scale => 1000, :unit => 'm/s' field 57, 'uint32', 'time_in_hr_zone', :array => true, :scale => 1000, :unit => 's' - field 60, 'uint32', 'avg_pos_vertical_speed', :scale => 1000, :unit => 'm/s' + field 58, 'uint32', 'time_in_speed_zone', :array => true, :scale => 1000, :unit => 's' + field 59, 'uint32', 'time_in_cadence_zone', :array => true, :scale => 1000, :unit => 's' + field 60, 'uint32', 'time_in_power_zone', :scale => 1000, :unit => 's' + field 61, 'uint16', 'repetition_num' + field 62, 'uint16', 'min_altitude', :scale => 5, :offset => 500, :unit => 'm' + field 63, 'uint8', 'min_heart_rate', :unit => 'bpm' field 70, 'uint32', 'undefined_value_70' field 71, 'uint16', 'wkt_step_index' field 72, 'enum', 'undocumented_field_72' field 73, 'uint16', 'undefined_value_73' + field 74, 'uint16', 'opponent_score' + field 75, 'uint16', 'stroke_count', :array => true, :unit => 'count' + field 76, 'uint16', 'zone_count', :array => true, :unit => 'count' field 77, 'uint16', 'avg_vertical_oscillation', :scale => 10, :unit => 'mm' field 78, 'uint16', 'avg_stance_time_percent', :scale => 100, :unit => 'percent' field 79, 'uint16', 'avg_stance_time', :scale => 10, :unit => 'ms' field 80, 'uint8', 'avg_fractional_cadence', :scale => 128 field 81, 'uint8', 'max_fractional_cadence', :scale => 128 field 82, 'uint8', 'total_fractional_cycles', :scale => 128 + field 83, 'uint16', 'player_score' + field 84, 'uint16', 'avg_total_hemoglobin_conc', :array => true, :scale => 100, :unit => 'g/dL' + field 85, 'uint16', 'min_total_hemoglobin_conc', :array => true, :scale => 100, :unit => 'g/dL' + field 86, 'uint16', 'max_total_hemoglobin_conc', :array => true, :scale => 100, :unit => 'g/dL' + field 87, 'uint16', 'avg_saturated_hemoglobin_percent', :array => true, :scale => 10, :unit => 'percent' + field 88, 'uint16', 'min_saturated_hemoglobin_percent', :array => true, :scale => 10, :unit => 'percent' + field 89, 'uint16', 'max_saturated_hemoglobin_percent', :array => true, :scale => 10, :unit => 'percent' field 90, 'uint16', 'undefined_value_90' field 91, 'uint8', 'avg_left_torque_effectiveness', :scale => 2, :unit => 'percent' field 92, 'uint8', 'avg_right_torque_effectiveness', :scale => 2, :unit => 'percent' @@ -444,9 +506,13 @@ module Fit4Ruby field 112, 'uint32', 'enhanced_avg_altitude', :scale => 5, :offset => 500, :unit => 'm' field 113, 'uint32', 'enhanced_min_altitude', :scale => 5, :offset => 500, :unit => 'm' field 114, 'uint32', 'enhanced_max_altitude', :scale => 5, :offset => 500, :unit => 'm' + field 115, 'uint16', 'avg_lev_motor_power', :unit => 'watts' + field 116, 'uint16', 'max_lev_motor_power', :unit => 'watts' + field 117, 'uint8', 'lev_battery_consumption', :scale => 2, :unit => 'percent' field 118, 'uint16', 'avg_vertical_ratio', :scale => 100, :unit => '%' field 119, 'uint16', 'avg_stance_time_balance', :scale => 100, :unit => '%' field 120, 'uint16', 'avg_step_length', :scale => 10000, :unit => 'm' + field 121, 'uint16', 'avg_vam', :scale => 1000, :unit => 'm/s' field 124, 'sint8', 'min_temperature', :unit => 'C' # guessed field 125, 'uint16', 'undocumented_field_125' field 126, 'uint16', 'undocumented_field_126' @@ -470,8 +536,15 @@ module Fit4Ruby field 13, 'sint8', 'temperature', :unit => 'C' field 14, 'uint32', 'undefined_field_14' field 15, 'uint32', 'undefined_field_15' + field 17, 'uint8', 'speed_1s', :array => true, :scale => 16, :unit => 'm/s' + field 18, 'uint8', 'cycles', :unit => 'cycles' + field 19, 'uint32', 'total_cycles', :unit => 'cycles' + field 28, 'uint16', 'compressed_accumulated_power', :unit => 'watts' field 29, 'uint32', 'accumulated_power', :unit => 'watts' field 30, 'uint8', 'left_right_balance', :dict => 'left_right_balance' + field 31, 'uint8', 'gps_accuracy', :unit => 'm' + field 32, 'sint16', 'vertical_speed', :scale => 1000, :unit => 'm/s' + field 33, 'uint16', 'calories', :unit => 'kcal' field 39, 'uint16', 'vertical_oscillation', :scale => 10, :unit => 'mm' field 40, 'uint16', 'stance_time_percent', :scale => 100, :unit => 'percent' field 41, 'uint16', 'stance_time', :scale => 10, :unit => 'ms' @@ -481,9 +554,17 @@ module Fit4Ruby field 45, 'uint8', 'left_pedal_smoothness', :scale => 2, :unit => '%' field 46, 'uint8', 'right_pedal_smoothness', :scale => 2, :unit => '%' field 47, 'uint8', 'combined_pedal_smoothness', :scale => 2, :unit => '%' + field 48, 'uint8', 'time128', :scale => 128, :unit => 's' + field 50, 'uint8', 'zone' + field 51, 'uint16', 'ball_speed', :scale => 100, :unit => 'm/s' + field 52, 'uint16', 'cadence256', :scale => 256, :unit => 'rpm' field 53, 'uint8', 'fractional_cadence', :scale => 128 field 54, 'uint16', 'total_hemoglobin_conc', :scale => 100, :unit => 'g/dL' + field 55, 'uint16', 'total_hemoglobin_conc_min', :scale => 100, :unit => 'g/dL' + field 56, 'uint16', 'total_hemoglobin_conc_max', :scale => 100, :unit => 'g/dL' field 57, 'uint16', 'saturated_hemoglobin_percent', :scale => 10, :unit => '%' + field 58, 'uint16', 'saturated_hemoglobin_percent_min', :scale => 10, :unit => '%' + field 59, 'uint16', 'saturated_hemoglobin_percent_max', :scale => 10, :unit => '%' field 61, 'uint16', 'undefined_value_61' field 63, 'uint16', 'undefined_value_63' field 64, 'uint16', 'undefined_value_64' @@ -495,12 +576,24 @@ module Fit4Ruby field 70, 'uint8', 'left_power_phase_peak', :scale => 0.7111111, :unit => 'degrees', :array => true field 71, 'uint8', 'right_power_phase', :scale => 0.7111111, :unit => 'degrees', :array => true field 72, 'uint8', 'right_power_phase_peak', :scale => 0.7111111, :unit => 'degrees', :array => true - field 83, 'uint16', 'vertical_ratio', :scale => 100, :unit => '%' # guessed - field 84, 'uint16', 'gct_balance', :scale => 100, :unit => '%' # guessed - field 85, 'uint16', 'stride_length', :scale => 10000, :unit => 'm' # guessed + field 73, 'uint32', 'enhanced_speed', :scale => 1000, :unit => 'm/s' + field 78, 'uint32', 'enhanced_altitude', :scale => 5, :offset => 500, :unit => 'm' + field 81, 'uint8', 'battery_soc', :scale => 2, :unit => 'percent' + field 82, 'uint16', 'motor_power', :unit => 'watts' + field 83, 'uint16', 'vertical_ratio', :scale => 100, :unit => 'percent' + field 84, 'uint16', 'stance_time_balance', :scale => 100, :unit => 'percent' + field 85, 'uint16', 'step_length', :scale => 10, :unit => 'mm' field 87, 'uint16', 'undefined_value_87' # first seen on F3 FW6.80 - field 88, 'uint16', 'undefined_value_88' # first seen on F3HR FW3.60 + field 88, 'uint16', 'undefined_value_88' # first seen on F3HR FW3.60 field 90, 'sint8', 'performance_condition' # guessed + field 91, 'uint32', 'absolute_pressure', :unit => 'Pa' + field 92, 'uint32', 'depth', :scale => 1000, :unit => 'm' + field 93, 'uint32', 'next_stop_depth', :scale => 1000, :unit => 'm' + field 94, 'uint32', 'next_stop_time', :scale => 1, :unit => 's' + field 95, 'uint32', 'time_to_surface', :scale => 1, :unit => 's' + field 96, 'uint32', 'ndl_time', :scale => 1, :unit => 's' + field 97, 'uint8', 'cns_load', :unit => 'percent' + field 98, 'uint16', 'n2_load', :scale => 1, :unit => 'percent' field 253, 'uint32', 'timestamp', :type => 'date_time' message 21, 'event' @@ -1006,4 +1099,3 @@ module Fit4Ruby end end - diff --git a/lib/fit4ruby/HeartRateZones.rb b/lib/fit4ruby/HeartRateZones.rb index 1660ed7..78212e4 100644 --- a/lib/fit4ruby/HeartRateZones.rb +++ b/lib/fit4ruby/HeartRateZones.rb @@ -27,7 +27,8 @@ def initialize(field_values) def check(index) unless @lap_index == index - Log.fatal "lap_index must be #{index}, not #{@lap_index}" + Log.warn "lap_index must be #{index}, not #{@lap_index}" + #Log.fatal "lap_index must be #{index}, not #{@lap_index}" end end diff --git a/lib/fit4ruby/Session.rb b/lib/fit4ruby/Session.rb index 127ee22..d49e503 100644 --- a/lib/fit4ruby/Session.rb +++ b/lib/fit4ruby/Session.rb @@ -54,10 +54,14 @@ def initialize(laps, first_lap_index, field_values) # are reported via the Log object. def check(activity) unless @first_lap_index - Log.fatal 'first_lap_index is not set' + @first_lap_index = 0 + Log.warn('first_lap_index is not set') + #Log.fatal 'first_lap_index is not set' end unless @num_laps - Log.fatal 'num_laps is not set' + @num_laps = 1 + Log.warn 'num_laps is not set' + #Log.fatal 'num_laps is not set' end @first_lap_index.upto(@first_lap_index - @num_laps) do |i| if (lap = activity.lap[i])